summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;