Blob Blame History Raw
From b7b6e80a0e097593fb80e679f75df9afe2560373 Mon Sep 17 00:00:00 2001
From: Poornima G <pgurusid@redhat.com>
Date: Fri, 29 Jul 2016 12:20:11 +0530
Subject: [PATCH 118/141] md-cache/upcall: In case of mode bit change invalidate xattr

When the mode bits are changed, the ACL entries also do get affected.
Currently in upcall, setattr invalidates only the stat info.

With this patch, if mode bits are changed, the upcall will invalidate
all the xattrs.

Change-Id: Iccda2e1a7440ee845aa5442bf51970f74d9b0862
BUG: 1284873
Signed-off-by: Poornima G <pgurusid@redhat.com>
Reviewed-on: http://review.gluster.org/15043
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Prashanth Pai <ppai@redhat.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/87031
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
Tested-by: Rajesh Joseph <rjoseph@redhat.com>
---
 libglusterfs/src/iatt.h                     |   76 +++++++++++++++++----------
 xlators/features/upcall/src/upcall.c        |    9 +++
 xlators/performance/md-cache/src/md-cache.c |    5 ++-
 3 files changed, 62 insertions(+), 28 deletions(-)

diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
index 5b95c93..b890759 100644
--- a/libglusterfs/src/iatt.h
+++ b/libglusterfs/src/iatt.h
@@ -177,6 +177,43 @@ ia_type_from_st_mode (mode_t mode)
 }
 
 
+static inline uint32_t
+st_mode_prot_from_ia (ia_prot_t prot)
+{
+        uint32_t  prot_bit = 0;
+
+        if (prot.suid)
+                prot_bit |= S_ISUID;
+        if (prot.sgid)
+                prot_bit |= S_ISGID;
+        if (prot.sticky)
+                prot_bit |= S_ISVTX;
+
+        if (prot.owner.read)
+                prot_bit |= S_IRUSR;
+        if (prot.owner.write)
+                prot_bit |= S_IWUSR;
+        if (prot.owner.exec)
+                prot_bit |= S_IXUSR;
+
+        if (prot.group.read)
+                prot_bit |= S_IRGRP;
+        if (prot.group.write)
+                prot_bit |= S_IWGRP;
+        if (prot.group.exec)
+                prot_bit |= S_IXGRP;
+
+        if (prot.other.read)
+                prot_bit |= S_IROTH;
+        if (prot.other.write)
+                prot_bit |= S_IWOTH;
+        if (prot.other.exec)
+                prot_bit |= S_IXOTH;
+
+        return prot_bit;
+}
+
+
 static inline mode_t
 st_mode_from_ia (ia_prot_t prot, ia_type_t type)
 {
@@ -210,33 +247,7 @@ st_mode_from_ia (ia_prot_t prot, ia_type_t type)
                 break;
         }
 
-        if (prot.suid)
-                prot_bit |= S_ISUID;
-        if (prot.sgid)
-                prot_bit |= S_ISGID;
-        if (prot.sticky)
-                prot_bit |= S_ISVTX;
-
-        if (prot.owner.read)
-                prot_bit |= S_IRUSR;
-        if (prot.owner.write)
-                prot_bit |= S_IWUSR;
-        if (prot.owner.exec)
-                prot_bit |= S_IXUSR;
-
-        if (prot.group.read)
-                prot_bit |= S_IRGRP;
-        if (prot.group.write)
-                prot_bit |= S_IWGRP;
-        if (prot.group.exec)
-                prot_bit |= S_IXGRP;
-
-        if (prot.other.read)
-                prot_bit |= S_IROTH;
-        if (prot.other.write)
-                prot_bit |= S_IWOTH;
-        if (prot.other.exec)
-                prot_bit |= S_IXOTH;
+        prot_bit = st_mode_prot_from_ia (prot);
 
         st_mode = (type_bit | prot_bit);
 
@@ -326,5 +337,16 @@ iatt_to_stat (struct iatt *iatt, struct stat *stat)
         return 0;
 }
 
+static inline int
+is_same_mode (ia_prot_t prot1, ia_prot_t prot2)
+{
+        int ret = 0;
+
+        if (st_mode_prot_from_ia(prot1) != st_mode_prot_from_ia(prot2))
+                ret = -1;
+
+        return ret;
+}
+
 
 #endif /* _IATT_H */
diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c
index 68f1572..912d222 100644
--- a/xlators/features/upcall/src/upcall.c
+++ b/xlators/features/upcall/src/upcall.c
@@ -333,6 +333,15 @@ up_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
          * Bug1200271.
          */
         flags = UP_ATTR_FLAGS;
+        /* If mode bits have changed invalidate the xattrs, as posix-acl and
+         * others store permission related information in xattrs. With changing
+         * of permissions/mode, we need to make clients to forget all the
+         * xattrs related to permissions.
+         * TODO: Invalidate the xattr system.posix_acl_access alone.
+         */
+        if (is_same_mode(statpre->ia_prot, statpost->ia_prot) != 0)
+                flags |= UP_XATTR;
+
         upcall_cache_invalidate (frame, this, client, local->inode, flags,
                                  statpost, NULL, NULL, NULL);
 
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c
index 12a383d..d15da04 100644
--- a/xlators/performance/md-cache/src/md-cache.c
+++ b/xlators/performance/md-cache/src/md-cache.c
@@ -2418,7 +2418,10 @@ mdc_invalidate (xlator_t *this, void *data)
                         goto out;
         }
         if (up_ci->flags & UP_XATTR) {
-                ret = mdc_inode_xatt_update (this, inode, up_ci->dict);
+                if (up_ci->dict)
+                        ret = mdc_inode_xatt_update (this, inode, up_ci->dict);
+                else
+                        ret = mdc_inode_xatt_invalidate (this, inode);
         } else if (up_ci->flags & UP_XATTR_RM) {
                 tmp.inode = inode;
                 tmp.this = this;
-- 
1.7.1