3604df
From b7b6e80a0e097593fb80e679f75df9afe2560373 Mon Sep 17 00:00:00 2001
3604df
From: Poornima G <pgurusid@redhat.com>
3604df
Date: Fri, 29 Jul 2016 12:20:11 +0530
3604df
Subject: [PATCH 118/141] md-cache/upcall: In case of mode bit change invalidate xattr
3604df
3604df
When the mode bits are changed, the ACL entries also do get affected.
3604df
Currently in upcall, setattr invalidates only the stat info.
3604df
3604df
With this patch, if mode bits are changed, the upcall will invalidate
3604df
all the xattrs.
3604df
3604df
Change-Id: Iccda2e1a7440ee845aa5442bf51970f74d9b0862
3604df
BUG: 1284873
3604df
Signed-off-by: Poornima G <pgurusid@redhat.com>
3604df
Reviewed-on: http://review.gluster.org/15043
3604df
Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
Reviewed-by: Niels de Vos <ndevos@redhat.com>
3604df
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
Reviewed-by: Prashanth Pai <ppai@redhat.com>
3604df
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/87031
3604df
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
3604df
Tested-by: Rajesh Joseph <rjoseph@redhat.com>
3604df
---
3604df
 libglusterfs/src/iatt.h                     |   76 +++++++++++++++++----------
3604df
 xlators/features/upcall/src/upcall.c        |    9 +++
3604df
 xlators/performance/md-cache/src/md-cache.c |    5 ++-
3604df
 3 files changed, 62 insertions(+), 28 deletions(-)
3604df
3604df
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
3604df
index 5b95c93..b890759 100644
3604df
--- a/libglusterfs/src/iatt.h
3604df
+++ b/libglusterfs/src/iatt.h
3604df
@@ -177,6 +177,43 @@ ia_type_from_st_mode (mode_t mode)
3604df
 }
3604df
 
3604df
 
3604df
+static inline uint32_t
3604df
+st_mode_prot_from_ia (ia_prot_t prot)
3604df
+{
3604df
+        uint32_t  prot_bit = 0;
3604df
+
3604df
+        if (prot.suid)
3604df
+                prot_bit |= S_ISUID;
3604df
+        if (prot.sgid)
3604df
+                prot_bit |= S_ISGID;
3604df
+        if (prot.sticky)
3604df
+                prot_bit |= S_ISVTX;
3604df
+
3604df
+        if (prot.owner.read)
3604df
+                prot_bit |= S_IRUSR;
3604df
+        if (prot.owner.write)
3604df
+                prot_bit |= S_IWUSR;
3604df
+        if (prot.owner.exec)
3604df
+                prot_bit |= S_IXUSR;
3604df
+
3604df
+        if (prot.group.read)
3604df
+                prot_bit |= S_IRGRP;
3604df
+        if (prot.group.write)
3604df
+                prot_bit |= S_IWGRP;
3604df
+        if (prot.group.exec)
3604df
+                prot_bit |= S_IXGRP;
3604df
+
3604df
+        if (prot.other.read)
3604df
+                prot_bit |= S_IROTH;
3604df
+        if (prot.other.write)
3604df
+                prot_bit |= S_IWOTH;
3604df
+        if (prot.other.exec)
3604df
+                prot_bit |= S_IXOTH;
3604df
+
3604df
+        return prot_bit;
3604df
+}
3604df
+
3604df
+
3604df
 static inline mode_t
3604df
 st_mode_from_ia (ia_prot_t prot, ia_type_t type)
3604df
 {
3604df
@@ -210,33 +247,7 @@ st_mode_from_ia (ia_prot_t prot, ia_type_t type)
3604df
                 break;
3604df
         }
3604df
 
3604df
-        if (prot.suid)
3604df
-                prot_bit |= S_ISUID;
3604df
-        if (prot.sgid)
3604df
-                prot_bit |= S_ISGID;
3604df
-        if (prot.sticky)
3604df
-                prot_bit |= S_ISVTX;
3604df
-
3604df
-        if (prot.owner.read)
3604df
-                prot_bit |= S_IRUSR;
3604df
-        if (prot.owner.write)
3604df
-                prot_bit |= S_IWUSR;
3604df
-        if (prot.owner.exec)
3604df
-                prot_bit |= S_IXUSR;
3604df
-
3604df
-        if (prot.group.read)
3604df
-                prot_bit |= S_IRGRP;
3604df
-        if (prot.group.write)
3604df
-                prot_bit |= S_IWGRP;
3604df
-        if (prot.group.exec)
3604df
-                prot_bit |= S_IXGRP;
3604df
-
3604df
-        if (prot.other.read)
3604df
-                prot_bit |= S_IROTH;
3604df
-        if (prot.other.write)
3604df
-                prot_bit |= S_IWOTH;
3604df
-        if (prot.other.exec)
3604df
-                prot_bit |= S_IXOTH;
3604df
+        prot_bit = st_mode_prot_from_ia (prot);
3604df
 
3604df
         st_mode = (type_bit | prot_bit);
3604df
 
3604df
@@ -326,5 +337,16 @@ iatt_to_stat (struct iatt *iatt, struct stat *stat)
3604df
         return 0;
3604df
 }
3604df
 
3604df
+static inline int
3604df
+is_same_mode (ia_prot_t prot1, ia_prot_t prot2)
3604df
+{
3604df
+        int ret = 0;
3604df
+
3604df
+        if (st_mode_prot_from_ia(prot1) != st_mode_prot_from_ia(prot2))
3604df
+                ret = -1;
3604df
+
3604df
+        return ret;
3604df
+}
3604df
+
3604df
 
3604df
 #endif /* _IATT_H */
3604df
diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c
3604df
index 68f1572..912d222 100644
3604df
--- a/xlators/features/upcall/src/upcall.c
3604df
+++ b/xlators/features/upcall/src/upcall.c
3604df
@@ -333,6 +333,15 @@ up_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
          * Bug1200271.
3604df
          */
3604df
         flags = UP_ATTR_FLAGS;
3604df
+        /* If mode bits have changed invalidate the xattrs, as posix-acl and
3604df
+         * others store permission related information in xattrs. With changing
3604df
+         * of permissions/mode, we need to make clients to forget all the
3604df
+         * xattrs related to permissions.
3604df
+         * TODO: Invalidate the xattr system.posix_acl_access alone.
3604df
+         */
3604df
+        if (is_same_mode(statpre->ia_prot, statpost->ia_prot) != 0)
3604df
+                flags |= UP_XATTR;
3604df
+
3604df
         upcall_cache_invalidate (frame, this, client, local->inode, flags,
3604df
                                  statpost, NULL, NULL, NULL);
3604df
 
3604df
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c
3604df
index 12a383d..d15da04 100644
3604df
--- a/xlators/performance/md-cache/src/md-cache.c
3604df
+++ b/xlators/performance/md-cache/src/md-cache.c
3604df
@@ -2418,7 +2418,10 @@ mdc_invalidate (xlator_t *this, void *data)
3604df
                         goto out;
3604df
         }
3604df
         if (up_ci->flags & UP_XATTR) {
3604df
-                ret = mdc_inode_xatt_update (this, inode, up_ci->dict);
3604df
+                if (up_ci->dict)
3604df
+                        ret = mdc_inode_xatt_update (this, inode, up_ci->dict);
3604df
+                else
3604df
+                        ret = mdc_inode_xatt_invalidate (this, inode);
3604df
         } else if (up_ci->flags & UP_XATTR_RM) {
3604df
                 tmp.inode = inode;
3604df
                 tmp.this = this;
3604df
-- 
3604df
1.7.1
3604df