diff options
author | Poornima G <pgurusid@redhat.com> | 2018-06-27 14:59:40 +0530 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2018-07-11 04:11:59 +0000 |
commit | 69f77d28c3ecacba77fbae2f789b5110641347f3 (patch) | |
tree | 746f1470476a981b6becaedb6c7c1e681f457f41 /xlators | |
parent | af6c6429f9743f287baaad68f8e3d56ed7390d1b (diff) |
md-cache: Do not invalidate cache post set/remove xattr
Since setxattr and removexattr fops cbk do not carry poststat,
the stat cache was being invalidated in setxatr/remoxattr cbk.
Hence the further lookup wouldn't be served from cache.
To prevent this invalidation, md-cache is modified to get
the poststat in set/removexattr_cbk in dict.
Co-authored with Xavi Hernandez.
Change-Id: I6b946be2d20b807e2578825743c25ba5927a60b4
fixes: bz#1586018
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
Signed-off-by: Poornima G <pgurusid@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 4 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-combine.c | 63 | ||||
-rw-r--r-- | xlators/features/upcall/src/upcall.c | 13 | ||||
-rw-r--r-- | xlators/performance/md-cache/src/md-cache.c | 56 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-entry-ops.c | 2 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 49 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-inode-fd-ops.c | 85 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 2 |
8 files changed, 206 insertions, 68 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 900789ca8aa..fa73c33c5ab 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -5558,9 +5558,9 @@ dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, out: if (local->fop == GF_FOP_SETXATTR) { - DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, NULL); + DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); } else { - DHT_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, NULL); + DHT_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata); } return 0; diff --git a/xlators/cluster/ec/src/ec-combine.c b/xlators/cluster/ec/src/ec-combine.c index b51ec87a934..2233caffdba 100644 --- a/xlators/cluster/ec/src/ec-combine.c +++ b/xlators/cluster/ec/src/ec-combine.c @@ -259,6 +259,7 @@ ec_value_ignore (char *key) (XATTR_IS_NODE_UUID(key))) { return _gf_true; } + return _gf_false; } @@ -554,6 +555,64 @@ int32_t ec_dict_data_uuid(ec_cbk_data_t * cbk, int32_t which, char * key) return 0; } +int32_t ec_dict_data_iatt(ec_cbk_data_t *cbk, int32_t which, char *key) +{ + ec_t *ec = cbk->fop->xl->private; + data_t *data[ec->nodes]; + dict_t *dict; + struct iatt *stbuf, *tmp; + int32_t i, ret; + + ec_dict_list(data, cbk, which, key, _gf_false); + + stbuf = NULL; + for (i = 0; i < ec->nodes; i++) { + if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { + continue; + } + tmp = data_to_iatt(data[i], key); + if (tmp == NULL) { + ret = -EINVAL; + goto out; + } + if (stbuf == NULL) { + stbuf = GF_MALLOC(sizeof(struct iatt), gf_common_mt_char); + if (stbuf == NULL) { + ret = -ENOMEM; + goto out; + } + *stbuf = *tmp; + } else { + if (!ec_iatt_combine (cbk->fop, stbuf, tmp, 1)) { + ret = -EINVAL; + goto out; + } + } + } + + if (stbuf->ia_type == IA_IFREG) { + ec_iatt_rebuild(ec, stbuf, 1, cbk->count); + /* TODO: not sure if an iatt could come in xdata from a fop that takes + * no locks. */ + if (!ec_get_inode_size(cbk->fop, cbk->fop->locks[0].lock->loc.inode, + &stbuf->ia_size)) { + ret = -EINVAL; + goto out; + } + } + + dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; + ret = dict_set_iatt(dict, key, stbuf, false); + if (ret >= 0) { + stbuf = NULL; + } + +out: + GF_FREE(stbuf); + + return ret; +} + int32_t ec_dict_data_max32(ec_cbk_data_t *cbk, int32_t which, char *key) { ec_t *ec = cbk->fop->xl->private; @@ -736,6 +795,10 @@ int32_t ec_dict_data_combine(dict_t * dict, char * key, data_t * value, return ec_dict_data_max64(data->cbk, data->which, key); } + if (strcmp (key, GF_PRESTAT) == 0 || strcmp (key, GF_POSTSTAT) == 0) { + return ec_dict_data_iatt(data->cbk, data->which, key); + } + return 0; } diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c index dc09b2b3027..0bf1f413a94 100644 --- a/xlators/features/upcall/src/upcall.c +++ b/xlators/features/upcall/src/upcall.c @@ -20,7 +20,6 @@ #include "common-utils.h" #include "statedump.h" -#include "syncop.h" #include "upcall.h" #include "upcall-mem-types.h" @@ -1697,8 +1696,7 @@ up_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!up_invalidate_needed (local->xattr)) goto out; - ret = syncop_stat (FIRST_CHILD(frame->this), &local->loc, &stbuf, - NULL, NULL); + ret = dict_get_iatt (xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; @@ -1774,8 +1772,7 @@ up_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!up_invalidate_needed (local->xattr)) goto out; - ret = syncop_fstat (FIRST_CHILD(frame->this), local->fd, &stbuf, NULL, - NULL); + ret = dict_get_iatt (xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; @@ -1850,8 +1847,7 @@ up_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!up_invalidate_needed (local->xattr)) goto out; - ret = syncop_fstat (FIRST_CHILD(frame->this), local->fd, &stbuf, NULL, - NULL); + ret = dict_get_iatt (xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; @@ -1938,8 +1934,7 @@ up_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!up_invalidate_needed (local->xattr)) goto out; - ret = syncop_stat (FIRST_CHILD(frame->this), &local->loc, &stbuf, NULL, - NULL); + ret = dict_get_iatt (xdata, GF_POSTSTAT, &stbuf); if (ret == 0) flags |= UP_TIMES; diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index 2180cb25960..a3721a8e3f4 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -2157,6 +2157,9 @@ mdc_setxattr_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; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; local = frame->local; if (!local) @@ -2170,7 +2173,15 @@ 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); + ret = dict_get_iatt (xdata, GF_PRESTAT, &prestat); + if (ret >= 0) { + ret = dict_get_iatt (xdata, GF_POSTSTAT, &poststat); + mdc_inode_iatt_set_validate (this, local->loc.inode, &prestat, + &poststat, _gf_true); + } + + if (ret < 0) + mdc_inode_iatt_invalidate (this, local->loc.inode); out: MDC_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); @@ -2193,6 +2204,7 @@ mdc_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, STACK_WIND (frame, mdc_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, xattr, flags, xdata); + return 0; } @@ -2202,6 +2214,9 @@ mdc_fsetxattr_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; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; local = frame->local; if (!local) @@ -2215,7 +2230,16 @@ 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); + ret = dict_get_iatt (xdata, GF_PRESTAT, &prestat); + if (ret >= 0) { + ret = dict_get_iatt (xdata, GF_POSTSTAT, &poststat); + mdc_inode_iatt_set_validate (this, local->fd->inode, &prestat, + &poststat, _gf_true); + } + + if (ret < 0) + mdc_inode_iatt_invalidate (this, local->fd->inode); + out: MDC_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata); @@ -2237,6 +2261,7 @@ mdc_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, STACK_WIND (frame, mdc_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, xattr, flags, xdata); + return 0; } @@ -2380,6 +2405,9 @@ 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; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; local = frame->local; if (!local) @@ -2396,7 +2424,15 @@ mdc_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else mdc_inode_xatt_invalidate (this, local->loc.inode); - mdc_inode_iatt_invalidate (this, local->loc.inode); + ret = dict_get_iatt (xdata, GF_PRESTAT, &prestat); + if (ret >= 0) { + ret = dict_get_iatt (xdata, GF_POSTSTAT, &poststat); + mdc_inode_iatt_set_validate (this, local->loc.inode, &prestat, + &poststat, _gf_true); + } + + if (ret < 0) + mdc_inode_iatt_invalidate (this, local->loc.inode); out: MDC_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata); @@ -2451,6 +2487,9 @@ 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; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; local = frame->local; if (!local) @@ -2467,7 +2506,16 @@ mdc_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else mdc_inode_xatt_invalidate (this, local->fd->inode); - mdc_inode_iatt_invalidate (this, local->fd->inode); + ret = dict_get_iatt (xdata, GF_PRESTAT, &prestat); + if (ret >= 0) { + ret = dict_get_iatt (xdata, GF_POSTSTAT, &poststat); + mdc_inode_iatt_set_validate (this, local->fd->inode, &prestat, + &poststat, _gf_true); + } + + if (ret < 0) + mdc_inode_iatt_invalidate (this, local->fd->inode); + out: MDC_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata); diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index 4241b574bc4..9089603c0fa 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -1238,7 +1238,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this, "fstat failed on fd=%d", fd); goto out; } - op_ret = posix_set_iatt_in_dict (unwind_dict, &postbuf); + op_ret = posix_set_iatt_in_dict (unwind_dict, NULL, &postbuf); } op_ret = posix_pstat (this, loc->parent, loc->pargfid, par_path, diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index b02adf308ff..f4165cc1111 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -2846,25 +2846,56 @@ posix_is_bulk_removexattr (char *name, dict_t *xdata) } int32_t -posix_set_iatt_in_dict (dict_t *dict, struct iatt *in_stbuf) +posix_set_iatt_in_dict (dict_t *dict, struct iatt *preop, struct iatt *postop) { int ret = -1; struct iatt *stbuf = NULL; int32_t len = sizeof(struct iatt); + struct iatt *prebuf = NULL; + struct iatt *postbuf = NULL; - if (!dict || !in_stbuf) + if (!dict) return ret; - stbuf = GF_CALLOC (1, len, gf_common_mt_char); - if (!stbuf) - return ret; + if (postop) { + stbuf = GF_CALLOC (1, len, gf_common_mt_char); + if (!stbuf) + goto out; + memcpy (stbuf, postop, len); + ret = dict_set_iatt (dict, DHT_IATT_IN_XDATA_KEY, stbuf, + false); + if (ret < 0) { + GF_FREE (stbuf); + goto out; + } + } - memcpy (stbuf, in_stbuf, len); + if (preop) { + prebuf = GF_CALLOC (1, len, gf_common_mt_char); + if (!prebuf) + goto out; + memcpy (prebuf, preop, len); + ret = dict_set_iatt (dict, GF_PRESTAT, prebuf, false); + if (ret < 0) { + GF_FREE (prebuf); + goto out; + } + } - ret = dict_set_iatt (dict, DHT_IATT_IN_XDATA_KEY, stbuf, false); - if (ret) - GF_FREE (stbuf); + if (postop) { + postbuf = GF_CALLOC (1, len, gf_common_mt_char); + if (!postbuf) + goto out; + memcpy (postbuf, postop, len); + ret = dict_set_iatt (dict, GF_POSTSTAT, postbuf, false); + if (ret < 0) { + GF_FREE (postbuf); + goto out; + } + } + ret = 0; +out: return ret; } diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c index af13a622feb..0e7d3762ac8 100644 --- a/xlators/storage/posix/src/posix-inode-fd-ops.c +++ b/xlators/storage/posix/src/posix-inode-fd-ops.c @@ -2212,7 +2212,8 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, int32_t op_errno = 0; char * real_path = NULL; char *acl_xattr = NULL; - struct iatt stbuf = {0}; + struct iatt preop = {0}; + struct iatt postop = {0}; int32_t ret = 0; ssize_t acl_size = 0; dict_t *xattr = NULL; @@ -2245,7 +2246,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, goto out; } - posix_pstat(this, loc->inode, loc->gfid, real_path, &stbuf, _gf_false); + posix_pstat(this, loc->inode, loc->gfid, real_path, &preop, _gf_false); op_ret = -1; @@ -2259,7 +2260,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, /*TODO: move the following to a different function */ LOCK (&loc->inode->lock); { - state = posix_cs_check_status (this, real_path, NULL, &stbuf); + state = posix_cs_check_status (this, real_path, NULL, &preop); if (state != GF_CS_LOCAL) { op_errno = EINVAL; ret = posix_cs_set_state (this, &xattr, state, real_path, @@ -2350,7 +2351,7 @@ unlock: filler.real_path = real_path; filler.this = this; - filler.stbuf = &stbuf; + filler.stbuf = &preop; #ifdef GF_DARWIN_HOST_OS filler.flags = map_xattr_flags(flags); @@ -2374,14 +2375,12 @@ unlock: * This is used by DHT to redirect FOPs if the file is being migrated * Ignore errors for now */ - if (xdata && dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { - ret = posix_pstat(this, loc->inode, loc->gfid, real_path, - &stbuf, _gf_false); - if (ret) - goto out; + ret = posix_pstat(this, loc->inode, loc->gfid, real_path, &postop, + _gf_false); + if (ret) + goto out; - ret = posix_set_iatt_in_dict (xattr, &stbuf); - } + ret = posix_set_iatt_in_dict (xattr, &preop, &postop); /* * ACL can be set on a file/folder using GF_POSIX_ACL_*_KEY xattrs which @@ -3720,7 +3719,8 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, struct posix_fd *pfd = NULL; int _fd = -1; int ret = -1; - struct iatt stbuf = {0,}; + struct iatt preop = {0,}; + struct iatt postop = {0,}; dict_t *xattr = NULL; posix_xattr_filler_t filler = {0,}; struct posix_private *priv = NULL; @@ -3744,7 +3744,7 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, } _fd = pfd->fd; - ret = posix_fdstat (this, fd->inode, pfd->fd, &stbuf); + ret = posix_fdstat (this, fd->inode, pfd->fd, &preop); if (ret == -1) { op_errno = errno; gf_msg (this->name, GF_LOG_ERROR, op_errno, @@ -3759,7 +3759,7 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, filler.fdnum = _fd; filler.this = this; filler.frame = frame; - filler.stbuf = &stbuf; + filler.stbuf = &preop; filler.fd = fd; #ifdef GF_DARWIN_HOST_OS filler.flags = map_xattr_flags(flags); @@ -3785,21 +3785,19 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, } } - if (xdata && dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { - ret = posix_fdstat (this, fd->inode, pfd->fd, &stbuf); - if (ret == -1) { - op_errno = errno; - gf_msg (this->name, GF_LOG_ERROR, op_errno, - P_MSG_XATTR_FAILED, "fsetxattr (fstat)" - "failed on fd=%p", fd); - goto out; - } - - xattr = dict_new (); - if (!xattr) - goto out; - ret = posix_set_iatt_in_dict (xattr, &stbuf); + ret = posix_fdstat (this, fd->inode, pfd->fd, &postop); + if (ret == -1) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, op_errno, + P_MSG_XATTR_FAILED, "fsetxattr (fstat)" + "failed on fd=%p", fd); + goto out; } + xattr = dict_new (); + if (!xattr) + goto out; + + ret = posix_set_iatt_in_dict (xattr, &preop, &postop); out: SET_TO_OLD_FS_ID (); @@ -3877,7 +3875,8 @@ posix_common_removexattr (call_frame_t *frame, loc_t *loc, fd_t *fd, char *real_path = NULL; struct posix_fd *pfd = NULL; int op_ret = 0; - struct iatt stbuf = {0}; + struct iatt preop = {0,}; + struct iatt postop = {0,}; int ret = 0; int _fd = -1; xlator_t *this = frame->this; @@ -3913,6 +3912,12 @@ posix_common_removexattr (call_frame_t *frame, loc_t *loc, fd_t *fd, goto out; } + if (loc) + ret = posix_pstat(this, inode, loc->gfid, real_path, + &preop, _gf_false); + else + ret = posix_fdstat (this, inode, _fd, &preop); + if (gf_get_index_by_elem (disallow_removexattrs, (char *)name) >= 0) { gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_NOT_REMOVED, "Remove xattr called on %s for file/dir %s with gfid: " @@ -3968,24 +3973,20 @@ posix_common_removexattr (call_frame_t *frame, loc_t *loc, fd_t *fd, if (loc) { posix_set_ctime (frame, this, real_path, -1, inode, NULL); + ret = posix_pstat(this, inode, loc->gfid, real_path, &postop, + _gf_false); } else { posix_set_ctime (frame, this, NULL, _fd, inode, NULL); + ret = posix_fdstat (this, inode, _fd, &postop); } + if (ret) + goto out; + *xdata_rsp = dict_new(); + if (!*xdata_rsp) + goto out; - if (xdata && dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { - if (loc) - ret = posix_pstat(this, inode, loc->gfid, - real_path, &stbuf, _gf_false); - else - ret = posix_fdstat (this, inode, _fd, &stbuf); - if (ret) - goto out; - *xdata_rsp = dict_new(); - if (!*xdata_rsp) - goto out; + ret = posix_set_iatt_in_dict (*xdata_rsp, &preop, &postop); - ret = posix_set_iatt_in_dict (*xdata_rsp, &stbuf); - } op_ret = 0; out: SET_TO_OLD_FS_ID (); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index db525ad9379..a58d510df2e 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -396,7 +396,7 @@ gf_boolean_t posix_is_bulk_removexattr (char *name, dict_t *dict); int32_t -posix_set_iatt_in_dict (dict_t *, struct iatt *); +posix_set_iatt_in_dict (dict_t *, struct iatt *, struct iatt *); mode_t posix_override_umask (mode_t , mode_t); |