diff options
| -rw-r--r-- | xlators/performance/md-cache/src/md-cache.c | 126 | 
1 files changed, 126 insertions, 0 deletions
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index c3baafdc1b6..75a2b26ef65 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -8,6 +8,7 @@    cases as published by the Free Software Foundation.  */ +#include "timespec.h"  #include "glusterfs.h"  #include "defaults.h"  #include "logging.h" @@ -26,6 +27,12 @@     - send proper postbuf in setattr_cbk even when op_ret = -1  */ +struct mdc_statfs_cache { +        pthread_mutex_t lock; +        gf_boolean_t initialized; +        struct timespec last_refreshed; +        struct statvfs buf; +};  struct mdc_conf {  	int  timeout; @@ -34,6 +41,8 @@ struct mdc_conf {  	gf_boolean_t force_readdirp;          gf_boolean_t cache_swift_metadata;          gf_boolean_t cache_all_xattrs; +        gf_boolean_t cache_statfs; +        struct mdc_statfs_cache statfs_cache;  }; @@ -682,6 +691,112 @@ out:          return ret;  } +static void +mdc_cache_statfs (xlator_t *this, struct statvfs *buf) +{ +        struct mdc_conf *conf = this->private; + +        pthread_mutex_lock (&conf->statfs_cache.lock); +        { +                memcpy (&conf->statfs_cache.buf, buf, sizeof (struct statvfs)); +                clock_gettime (CLOCK_MONOTONIC, +                               &conf->statfs_cache.last_refreshed); +                conf->statfs_cache.initialized = _gf_true; +        } +        pthread_mutex_unlock (&conf->statfs_cache.lock); +} + +int +mdc_load_statfs_info_from_cache (xlator_t *this, struct statvfs **buf) +{ +        struct mdc_conf *conf = this->private; +        struct timespec now; +        double cache_age = 0.0; +        int ret = 0; + +        if (!buf || !conf) { +                ret = -1; +                goto err; +        } + +        pthread_mutex_lock (&conf->statfs_cache.lock); +        { +                *buf = NULL; + +                // Skip if the cache is not initialized +                if (!conf->statfs_cache.initialized) { +                        ret = -1; +                        goto err; +                } + +                timespec_now (&now); + +                cache_age = now.tv_sec - \ +                            conf->statfs_cache.last_refreshed.tv_sec; + + +                // Expire the cache +                gf_log (this->name, GF_LOG_DEBUG, +                        "STATFS cache age = %lf", cache_age); +                if (cache_age > conf->timeout) { +                        gf_log (this->name, GF_LOG_DEBUG, +                                "Cache age %lf exceeded timeout %d", +                                cache_age, conf->timeout); +                        ret = -1; +                        goto err; +                } + +                *buf = &conf->statfs_cache.buf; +        } +err: +        pthread_mutex_unlock (&conf->statfs_cache.lock); +        return ret; +} + +int +mdc_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, +                        struct statvfs *buf, dict_t *xdata) +{ +        struct mdc_conf *conf = this->private; + +        if (op_ret == 0 && conf && conf->cache_statfs) { +                mdc_cache_statfs (this, buf); +        } + +        STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata); + +        return 0; +} + +int +mdc_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ +        int ret = 0; +        struct statvfs *buf = NULL; +        struct mdc_conf *conf = this->private; + +        if (!conf) { +                goto uncached; +        } + +        if (!conf->cache_statfs) { +                goto uncached; +        } + +        ret = mdc_load_statfs_info_from_cache (this, &buf); +        if (ret == 0 && buf) { +                STACK_UNWIND_STRICT (statfs, frame, 0, 0, buf, xdata); +                goto out; +        } + +uncached: +        STACK_WIND (frame, mdc_statfs_cbk, FIRST_CHILD (this), +                    FIRST_CHILD (this)->fops->statfs, loc, xdata); + +out: +        return 0; +}  int  mdc_inode_iatt_invalidate (xlator_t *this, inode_t *inode) @@ -2388,6 +2503,9 @@ reconfigure (xlator_t *this, dict_t *options)  	GF_OPTION_RECONF("force-readdirp", conf->force_readdirp, options, bool, out);          GF_OPTION_RECONF("cache-all-xattrs", conf->cache_all_xattrs, options,                           bool, out); + +        GF_OPTION_RECONF ("md-cache-statfs", conf->cache_statfs, options, +                          bool, out);  out:  	return 0;  } @@ -2429,6 +2547,9 @@ init (xlator_t *this)  	GF_OPTION_INIT("force-readdirp", conf->force_readdirp, bool, out);          GF_OPTION_INIT ("cache-all-xattrs", conf->cache_all_xattrs, bool, out); + +        pthread_mutex_init (&conf->statfs_cache.lock, NULL); +        GF_OPTION_INIT ("md-cache-statfs", conf->cache_statfs, bool, out);  out:  	this->private = conf; @@ -2475,6 +2596,7 @@ struct xlator_fops fops = {  	.fallocate   = mdc_fallocate,  	.discard     = mdc_discard,          .zerofill    = mdc_zerofill, +        .statfs      = mdc_statfs,  }; @@ -2503,6 +2625,10 @@ struct volume_options options[] = {            .default_value = "1",            .description = "Time period after which cache has to be refreshed",          }, +        { .key = {"md-cache-statfs"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "on", +        },  	{ .key = {"force-readdirp"},  	  .type = GF_OPTION_TYPE_BOOL,  	  .default_value = "true",  | 
