Blob Blame History Raw
From 3b082665ad86a7c3c617c501eee2c0c700169fed Mon Sep 17 00:00:00 2001
From: Poornima G <pgurusid@redhat.com>
Date: Tue, 8 Nov 2016 10:32:29 +0530
Subject: [PATCH 224/227] dht/md-cache: Filter invalidate if the file is made a
 linkto file

Backport of http://review.gluster.org/15789/

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.

>Reviewed-on: http://review.gluster.org/15789
>Smoke: Gluster Build System <jenkins@build.gluster.org>
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
>Reviewed-by: Niels de Vos <ndevos@redhat.com>
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
>Reviewed-by: Susant Palai <spalai@redhat.com>
>Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>

Change-Id: Ic2fd7a5b196db0754f9b97072e644e6bf69da606
BUG: 1384070
Signed-off-by: Poornima G <pgurusid@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/91957
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 libglusterfs/src/upcall-utils.h             |  2 ++
 rpc/xdr/src/glusterfs3.h                    | 12 +++++--
 xlators/cluster/dht/src/dht-common.c        |  8 ++++-
 xlators/performance/md-cache/src/md-cache.c | 51 +++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/libglusterfs/src/upcall-utils.h b/libglusterfs/src/upcall-utils.h
index 64571c5..47049fd 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 1977b48..dc03c20 100644
--- a/rpc/xdr/src/glusterfs3.h
+++ b/rpc/xdr/src/glusterfs3.h
@@ -412,9 +412,17 @@ 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;
-out:
+                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;
 }
 #endif /* !_GLUSTERFS3_H */
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index ca84826..62657a0 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -8861,7 +8861,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 1e802c3..8187570 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;
 };
 
@@ -169,6 +171,7 @@ struct md_cache {
         char         *linkname;
 	time_t        ia_time;
 	time_t        xa_time;
+        gf_boolean_t  need_lookup;
         gf_lock_t     lock;
 };
 
@@ -807,6 +810,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)
@@ -1050,6 +1090,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,
@@ -2610,6 +2656,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);
-- 
2.9.3