From 4536f7bdf16f8286d67598eda9a46c029f0c0bf4 Mon Sep 17 00:00:00 2001 From: Poornima G Date: Tue, 8 Nov 2016 10:32:29 +0530 Subject: dht/md-cache: Filter invalidate if the file is made a linkto file Upcall as a part of setattr, sends an invalidation and the invalidation carries the resulting stat value. When a file is converted to linkto files, even then an invalidation is set and as a result the mountpoint shows the sticky bit in the stat of the file. eg: ---------T. 945 root root 0 Nov 8 10:14 hardlink.999 Fix: When dht recieves a notification of sticky bit change, it updates the flag, to indicate md-cache to send the subsequent lookup. Change-Id: Ic2fd7a5b196db0754f9b97072e644e6bf69da606 BUG: 1392713 Signed-off-by: Poornima G Reviewed-on: http://review.gluster.org/15789 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Niels de Vos CentOS-regression: Gluster Build System Reviewed-by: Susant Palai Reviewed-by: Rajesh Joseph --- libglusterfs/src/upcall-utils.h | 2 ++ rpc/xdr/src/glusterfs3.h | 10 +++++- xlators/cluster/dht/src/dht-common.c | 8 ++++- xlators/performance/md-cache/src/md-cache.c | 51 +++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/libglusterfs/src/upcall-utils.h b/libglusterfs/src/upcall-utils.h index 64571c5bdf8..47049fd7014 100644 --- a/libglusterfs/src/upcall-utils.h +++ b/libglusterfs/src/upcall-utils.h @@ -33,6 +33,8 @@ #define UP_XATTR 0x00000400 /* update the xattrs and ctime */ #define UP_XATTR_RM 0x00000800 /* Remove the xattrs and update ctime */ +#define UP_EXPLICIT_LOOKUP 0x00001000 /* Request an explicit lookup */ + /* for fops - open, read, lk, */ #define UP_UPDATE_CLIENT (UP_ATIME) diff --git a/rpc/xdr/src/glusterfs3.h b/rpc/xdr/src/glusterfs3.h index e95252a73be..b74ab933800 100644 --- a/rpc/xdr/src/glusterfs3.h +++ b/rpc/xdr/src/glusterfs3.h @@ -410,8 +410,16 @@ gf_proto_cache_invalidation_to_upcall (xlator_t *this, (gf_c_req->xdata).xdata_val, (gf_c_req->xdata).xdata_len, ret, ret, out); - if (ret > 0) + if (ret > 0) { ret = -ret; + goto out; + } + + /* If no dict was sent, create an empty dict, so that each xlator + * need not check if empty then create new dict. Will be unref'd by the + * caller */ + if (!gf_c_data->dict) + gf_c_data->dict = dict_new (); out: return ret; } diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 4e3d7026c4a..af3b7a24838 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -9054,7 +9054,13 @@ unlock: * notify all the md-cache clients to invalidate the existing * stat cache and send the lookup next time*/ if (up_ci->dict && dict_get (up_ci->dict, conf->xattr_name)) - ret = dict_set_int8 (up_ci->dict, MDC_INVALIDATE_IATT , 0); + up_ci->flags |= UP_EXPLICIT_LOOKUP; + + /* TODO: Instead of invalidating iatt, update the new + * hashed/cached subvolume in dht inode_ctx */ + if (IS_DHT_LINKFILE_MODE (&up_ci->stat)) + up_ci->flags |= UP_EXPLICIT_LOOKUP; + propagate = 1; break; default: diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index aa1c22ade51..9edbdf4aebe 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -40,6 +40,8 @@ struct mdc_statistics { sent to bricks */ uint64_t stat_invals; /* No. of invalidates recieved from upcall*/ uint64_t xattr_invals; /* No. of invalidates recieved from upcall*/ + uint64_t need_lookup; /* No. of lookups issued, because other xlators + * requested for explicit lookup */ gf_lock_t lock; }; @@ -153,6 +155,7 @@ struct md_cache { char *linkname; time_t ia_time; time_t xa_time; + gf_boolean_t need_lookup; gf_lock_t lock; }; @@ -791,6 +794,43 @@ out: return ret; } +gf_boolean_t +mdc_inode_reset_need_lookup (xlator_t *this, inode_t *inode) +{ + struct md_cache *mdc = NULL; + gf_boolean_t need = _gf_false; + + if (mdc_inode_ctx_get (this, inode, &mdc) != 0) + goto out; + + LOCK (&mdc->lock); + { + need = mdc->need_lookup; + mdc->need_lookup = _gf_false; + } + UNLOCK (&mdc->lock); + +out: + return need; +} + +void +mdc_inode_set_need_lookup (xlator_t *this, inode_t *inode, gf_boolean_t need) +{ + struct md_cache *mdc = NULL; + + if (mdc_inode_ctx_get (this, inode, &mdc) != 0) + goto out; + + LOCK (&mdc->lock); + { + mdc->need_lookup = need; + } + UNLOCK (&mdc->lock); + +out: + return; +} void mdc_inode_iatt_invalidate (xlator_t *this, inode_t *inode) @@ -1034,6 +1074,12 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, goto uncached; } + if (mdc_inode_reset_need_lookup (this, loc->inode)) { + INCREMENT_ATOMIC (conf->mdc_counter.lock, + conf->mdc_counter.need_lookup); + goto uncached; + } + ret = mdc_inode_iatt_get (this, loc->inode, &stbuf); if (ret != 0) { INCREMENT_ATOMIC (conf->mdc_counter.lock, @@ -2593,6 +2639,11 @@ mdc_invalidate (xlator_t *this, void *data) mdc_update_gfid_stat (this, &up_ci->oldp_stat); } + if (up_ci->flags & UP_EXPLICIT_LOOKUP) { + mdc_inode_set_need_lookup (this, inode, _gf_true); + goto out; + } + if ((up_ci->flags & (UP_NLINK | UP_RENAME_FLAGS | UP_FORGET)) || (up_ci->dict && dict_get (up_ci->dict, MDC_INVALIDATE_IATT))) { mdc_inode_iatt_invalidate (this, inode); -- cgit