diff options
Diffstat (limited to 'xlators/performance/md-cache/src/md-cache.c')
| -rw-r--r-- | xlators/performance/md-cache/src/md-cache.c | 382 |
1 files changed, 363 insertions, 19 deletions
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index 237acab9f..84c363ad9 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -18,6 +18,7 @@ #include "dict.h" #include "xlator.h" #include "md-cache-mem-types.h" +#include "glusterfs-acl.h" #include <assert.h> #include <sys/time.h> @@ -32,6 +33,7 @@ struct mdc_conf { int timeout; gf_boolean_t cache_posix_acl; gf_boolean_t cache_selinux; + gf_boolean_t force_readdirp; }; @@ -41,17 +43,17 @@ static struct mdc_key { int check; } mdc_keys[] = { { - .name = "system.posix_acl_access", + .name = POSIX_ACL_ACCESS_XATTR, .load = 0, .check = 1, }, { - .name = "system.posix_acl_default", + .name = POSIX_ACL_DEFAULT_XATTR, .load = 0, .check = 1, }, { - .name = "security.selinux", + .name = GF_SELINUX_XATTR_KEY, .load = 0, .check = 1, }, @@ -65,7 +67,11 @@ static struct mdc_key { .load = 0, .check = 1, }, - {}, + { + .name = NULL, + .load = 0, + .check = 0, + } }; @@ -127,6 +133,7 @@ struct mdc_local { loc_t loc2; fd_t *fd; char *linkname; + char *key; dict_t *xattr; }; @@ -169,7 +176,7 @@ __mdc_inode_ctx_set (xlator_t *this, inode_t *inode, struct md_cache *mdc) uint64_t mdc_int = 0; mdc_int = (long) mdc; - ret = __inode_ctx_set2 (inode, this, &mdc_int, 0); + ret = __inode_ctx_set (inode, this, &mdc_int); return ret; } @@ -224,6 +231,8 @@ mdc_local_wipe (xlator_t *this, mdc_local_t *local) GF_FREE (local->linkname); + GF_FREE (local->key); + if (local->xattr) dict_unref (local->xattr); @@ -580,6 +589,31 @@ out: int +mdc_inode_xatt_unset (xlator_t *this, inode_t *inode, char *name) +{ + int ret = -1; + struct md_cache *mdc = NULL; + + mdc = mdc_inode_prep (this, inode); + if (!mdc) + goto out; + + if (!name) + goto out; + + LOCK (&mdc->lock); + { + dict_del (mdc->xattr, name); + } + UNLOCK (&mdc->lock); + + ret = 0; +out: + return ret; +} + + +int mdc_inode_xatt_get (xlator_t *this, inode_t *inode, dict_t **dict) { int ret = -1; @@ -593,13 +627,15 @@ mdc_inode_xatt_get (xlator_t *this, inode_t *inode, dict_t **dict) LOCK (&mdc->lock); { + ret = 0; + /* Missing xattr only means no keys were there, i.e + a negative cache for the "loaded" keys + */ if (!mdc->xattr) goto unlock; if (dict) *dict = dict_ref (mdc->xattr); - - ret = 0; } unlock: UNLOCK (&mdc->lock); @@ -609,6 +645,46 @@ out: } +int +mdc_inode_iatt_invalidate (xlator_t *this, inode_t *inode) +{ + int ret = -1; + struct md_cache *mdc = NULL; + + if (mdc_inode_ctx_get (this, inode, &mdc) != 0) + goto out; + + LOCK (&mdc->lock); + { + mdc->ia_time = 0; + } + UNLOCK (&mdc->lock); + +out: + return ret; +} + + +int +mdc_inode_xatt_invalidate (xlator_t *this, inode_t *inode) +{ + int ret = -1; + struct md_cache *mdc = NULL; + + if (mdc_inode_ctx_get (this, inode, &mdc) != 0) + goto out; + + LOCK (&mdc->lock); + { + mdc->xa_time = 0; + } + UNLOCK (&mdc->lock); + +out: + return ret; +} + + void mdc_load_reqs (xlator_t *this, dict_t *dict) { @@ -642,7 +718,7 @@ is_mdc_key_satisfied (const char *key) return 0; for (mdc_key = mdc_keys[i].name; (mdc_key = mdc_keys[i].name); i++) { - if (!mdc_keys[i].check) + if (!mdc_keys[i].load) continue; if (strcmp (mdc_key, key) == 0) return 1; @@ -716,6 +792,7 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt stbuf = {0, }; struct iatt postparent = {0, }; dict_t *xattr_rsp = NULL; + dict_t *xattr_alloc = NULL; mdc_local_t *local = NULL; @@ -723,6 +800,13 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, if (!local) goto uncached; + if (!loc->name) + /* A nameless discovery is dangerous to cache. We + perform nameless lookup with the intention of + re-establishing an inode "properly" + */ + goto uncached; + loc_copy (&local->loc, loc); ret = mdc_inode_iatt_get (this, loc->inode, &stbuf); @@ -747,6 +831,8 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, return 0; uncached: + if (!xdata) + xdata = xattr_alloc = dict_new (); if (xdata) mdc_load_reqs (this, xdata); @@ -755,7 +841,8 @@ uncached: if (xattr_rsp) dict_unref (xattr_rsp); - + if (xattr_alloc) + dict_unref (xattr_alloc); return 0; } @@ -1568,6 +1655,8 @@ mdc_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_xatt_update (this, local->loc.inode, local->xattr); + mdc_inode_iatt_invalidate (this, local->loc.inode); + out: MDC_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); @@ -1609,6 +1698,7 @@ mdc_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_xatt_update (this, local->fd->inode, local->xattr); + mdc_inode_iatt_invalidate (this, local->fd->inode); out: MDC_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata); @@ -1661,6 +1751,7 @@ mdc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *xdata) { int ret; + int op_errno = ENODATA; mdc_local_t *local = NULL; dict_t *xattr = NULL; @@ -1677,10 +1768,12 @@ mdc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, if (ret != 0) goto uncached; - if (!dict_get (xattr, (char *)key)) - goto uncached; + if (!xattr || !dict_get (xattr, (char *)key)) { + ret = -1; + op_errno = ENODATA; + } - MDC_STACK_UNWIND (getxattr, frame, 0, 0, xattr, xdata); + MDC_STACK_UNWIND (getxattr, frame, ret, op_errno, xattr, xdata); return 0; @@ -1722,6 +1815,7 @@ mdc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, int ret; mdc_local_t *local = NULL; dict_t *xattr = NULL; + int op_errno = ENODATA; local = mdc_local_get (frame); if (!local) @@ -1736,10 +1830,12 @@ mdc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, if (ret != 0) goto uncached; - if (!dict_get (xattr, (char *)key)) - goto uncached; + if (!xattr || !dict_get (xattr, (char *)key)) { + ret = -1; + op_errno = ENODATA; + } - MDC_STACK_UNWIND (fgetxattr, frame, 0, 0, xattr, xdata); + MDC_STACK_UNWIND (fgetxattr, frame, ret, op_errno, xattr, xdata); return 0; @@ -1750,6 +1846,97 @@ uncached: return 0; } +int +mdc_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + if (local->key) + mdc_inode_xatt_unset (this, local->loc.inode, local->key); + else + mdc_inode_xatt_invalidate (this, local->loc.inode); + + mdc_inode_iatt_invalidate (this, local->loc.inode); +out: + MDC_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata); + + return 0; +} + + +int +mdc_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = mdc_local_get (frame); + + loc_copy (&local->loc, loc); + + local->key = gf_strdup (name); + + STACK_WIND (frame, mdc_removexattr_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, + loc, name, xdata); + return 0; +} + + +int +mdc_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + if (local->key) + mdc_inode_xatt_unset (this, local->fd->inode, local->key); + else + mdc_inode_xatt_invalidate (this, local->fd->inode); + + mdc_inode_iatt_invalidate (this, local->fd->inode); +out: + MDC_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata); + + return 0; +} + + +int +mdc_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = mdc_local_get (frame); + + local->fd = fd_ref (fd); + + local->key = gf_strdup (name); + + STACK_WIND (frame, mdc_fremovexattr_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, + fd, name, xdata); + return 0; +} + int mdc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -1777,18 +1964,42 @@ int mdc_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { + dict_t *xattr_alloc = NULL; + + if (!xdata) + xdata = xattr_alloc = dict_new (); + if (xdata) + mdc_load_reqs (this, xdata); + STACK_WIND (frame, mdc_readdirp_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp, fd, size, offset, xdata); + if (xattr_alloc) + dict_unref (xattr_alloc); return 0; } +int +mdc_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, + int op_errno, gf_dirent_t *entries, dict_t *xdata) +{ + STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata); + return 0; +} int mdc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { int need_unref = 0; + struct mdc_conf *conf = this->private; + + if (!conf->force_readdirp) { + STACK_WIND(frame, mdc_readdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdir, fd, size, offset, + xdata); + return 0; + } if (!xdata) { xdata = dict_new (); @@ -1798,9 +2009,9 @@ mdc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, if (xdata) mdc_load_reqs (this, xdata); - STACK_WIND (frame, mdc_readdirp_cbk, - FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp, - fd, size, offset, xdata); + STACK_WIND(frame, mdc_readdirp_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdirp, fd, size, offset, + xdata); if (need_unref && xdata) dict_unref (xdata); @@ -1808,6 +2019,123 @@ mdc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, return 0; } +int +mdc_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); + +out: + MDC_STACK_UNWIND (fallocate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + + return 0; +} + +int mdc_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, + off_t offset, size_t len, dict_t *xdata) +{ + mdc_local_t *local; + + local = mdc_local_get(frame); + local->fd = fd_ref(fd); + + STACK_WIND(frame, mdc_fallocate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, + xdata); + + return 0; +} + +int +mdc_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); + +out: + MDC_STACK_UNWIND(discard, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + + return 0; +} + +int mdc_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + mdc_local_t *local; + + local = mdc_local_get(frame); + local->fd = fd_ref(fd); + + STACK_WIND(frame, mdc_discard_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->discard, fd, offset, len, + xdata); + + return 0; +} + +int +mdc_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); + +out: + MDC_STACK_UNWIND(zerofill, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + + return 0; +} + +int mdc_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + mdc_local_t *local; + + local = mdc_local_get(frame); + local->fd = fd_ref(fd); + + STACK_WIND(frame, mdc_zerofill_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->zerofill, fd, offset, len, + xdata); + + return 0; +} + int mdc_forget (xlator_t *this, inode_t *inode) @@ -1862,6 +2190,8 @@ reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("cache-posix-acl", conf->cache_posix_acl, options, bool, out); mdc_key_load_set (mdc_keys, "system.posix_acl_", conf->cache_posix_acl); + GF_OPTION_RECONF("force-readdirp", conf->force_readdirp, options, bool, out); + out: return 0; } @@ -1894,6 +2224,8 @@ init (xlator_t *this) GF_OPTION_INIT ("cache-posix-acl", conf->cache_posix_acl, bool, out); mdc_key_load_set (mdc_keys, "system.posix_acl_", conf->cache_posix_acl); + + GF_OPTION_INIT("force-readdirp", conf->force_readdirp, bool, out); out: this->private = conf; @@ -1931,8 +2263,13 @@ struct xlator_fops fops = { .fsetxattr = mdc_fsetxattr, .getxattr = mdc_getxattr, .fgetxattr = mdc_fgetxattr, + .removexattr = mdc_removexattr, + .fremovexattr= mdc_fremovexattr, .readdirp = mdc_readdirp, - .readdir = mdc_readdir + .readdir = mdc_readdir, + .fallocate = mdc_fallocate, + .discard = mdc_discard, + .zerofill = mdc_zerofill, }; @@ -1956,4 +2293,11 @@ struct volume_options options[] = { .default_value = "1", .description = "Time period after which cache has to be refreshed", }, + { .key = {"force-readdirp"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "true", + .description = "Convert all readdir requests to readdirplus to " + "collect stat info on each entry.", + }, + { .key = {NULL} }, }; |
