summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPoornima G <pgurusid@redhat.com>2016-07-29 12:20:11 +0530
committerJeff Darcy <jdarcy@redhat.com>2016-08-04 08:46:44 -0700
commit5ae0a5d1e92175c28cd5470b890e99ff4eac0673 (patch)
tree2654eceb637d64e73897bbb88b081ff277a25f9e
parent2650f8b1101a1f345f310475841569feb852bf4b (diff)
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: 1211863 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>
-rw-r--r--libglusterfs/src/iatt.h76
-rw-r--r--xlators/features/upcall/src/upcall.c9
-rw-r--r--xlators/performance/md-cache/src/md-cache.c5
3 files changed, 62 insertions, 28 deletions
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
index e89f94662aa..2b2f7b9e503 100644
--- a/libglusterfs/src/iatt.h
+++ b/libglusterfs/src/iatt.h
@@ -174,6 +174,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)
{
@@ -207,33 +244,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);
@@ -323,5 +334,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 40cfb6c7f11..ea716214a56 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 be42bf0a885..8a381b18981 100644
--- a/xlators/performance/md-cache/src/md-cache.c
+++ b/xlators/performance/md-cache/src/md-cache.c
@@ -2402,7 +2402,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;