diff options
author | Shreyas Siravara <sshreyas@fb.com> | 2017-09-07 15:34:58 -0700 |
---|---|---|
committer | Shreyas Siravara <sshreyas@fb.com> | 2017-09-07 22:48:18 +0000 |
commit | 7981d5147feca3f459dd5377dc92cc5a3e6ad953 (patch) | |
tree | 9194df881f2cf26355f36fa14cc5448d4f090acc | |
parent | 60c6b1729b93c05614bdbb9e2e4594a94138fe6b (diff) |
md-cache: Cache statfs calls
Summary:
- This gives md-cache to cache statfs calls
- You can turn it on or off via 'gluster vol set groot performance.md-cache-statfs <on|off>'
- This is a port of D4652632
Test Plan: Tested functionality on devserver
Reviewers: kvigor
Reviewed By: kvigor
Subscribers: #posix_storage
Differential Revision: https://phabricator.intern.facebook.com/D4652632
Change-Id: I664579e3c19fb9a6cd9d7b3a0eae061f70f4def4
Signature: t1:4652632:1488581841:111cc01efe83c71f1e98d075abb10589c4574705
Reviewed-on: https://review.gluster.org/18228
Reviewed-by: Shreyas Siravara <sshreyas@fb.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Smoke: Gluster Build System <jenkins@build.gluster.org>
-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", |