summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2013-09-15 15:00:06 -0700
committerVijay Bellur <vbellur@redhat.com>2013-09-25 00:31:04 -0700
commit8737b4697ad555a1e49ef87b5d439bfb74d8b5b5 (patch)
tree37fa44c3dc97328974eab469f1a0c648a38b2655
parent83937d1666f1f5e395afc7b2df477e9aad4c2278 (diff)
posix-acl: fixup extended ACL entries properly
Typically when updating cached ACL from backend, we get both iatt and ACL xattrs (like lookup, readdirplus etc.) However in calls like setattr(), the mode would have updated but we receive only iatt and not the ACL xattrs. In such case we need to "spread" the effects of the changed mode properly into the cached ACL xattr ourselves. Change-Id: I23a7bc9c14722ff6848e175ed4bbe863a21ce2c9 BUG: 998967 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/5979 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amarts@redhat.com>
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c46
-rw-r--r--xlators/system/posix-acl/src/posix-acl.h1
2 files changed, 46 insertions, 1 deletions
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c
index 3e2f7f2..4658cad 100644
--- a/xlators/system/posix-acl/src/posix-acl.c
+++ b/xlators/system/posix-acl/src/posix-acl.c
@@ -186,7 +186,7 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want)
ace = acl->entries;
- if (acl->count > 3)
+ if (acl->count > POSIX_ACL_MINIMAL_ACE_COUNT)
acl_present = 1;
for (i = 0; i < acl->count; i++) {
@@ -663,7 +663,12 @@ int
posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)
{
struct posix_acl_ctx *ctx = NULL;
+ struct posix_acl *acl = NULL;
+ struct posix_ace *ace = NULL;
+ struct posix_ace *mask_ce = NULL;
+ struct posix_ace *group_ce = NULL;
int ret = 0;
+ int i = 0;
ctx = posix_acl_ctx_get (inode, this);
if (!ctx) {
@@ -676,7 +681,46 @@ posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)
ctx->uid = buf->ia_uid;
ctx->gid = buf->ia_gid;
ctx->perm = st_mode_from_ia (buf->ia_prot, buf->ia_type);
+
+ acl = ctx->acl_access;
+ if (!acl || !(acl->count > POSIX_ACL_MINIMAL_ACE_COUNT))
+ goto unlock;
+
+ /* This is an extended ACL (not minimal acl). In case we
+ are only refreshing from iatt and not ACL xattrs (for
+ e.g. from postattributes of setattr() call, we need to
+ update the corresponding ACEs as well.
+ */
+ ace = acl->entries;
+ for (i = 0; i < acl->count; i++) {
+ switch (ace->tag) {
+ case POSIX_ACL_USER_OBJ:
+ ace->perm = (ctx->perm & S_IRWXU) >> 6;
+ break;
+ case POSIX_ACL_USER:
+ case POSIX_ACL_GROUP:
+ break;
+ case POSIX_ACL_GROUP_OBJ:
+ group_ce = ace;
+ break;
+ case POSIX_ACL_MASK:
+ mask_ce = ace;
+ break;
+ case POSIX_ACL_OTHER:
+ ace->perm = (ctx->perm & S_IRWXO);
+ break;
+ }
+ ace++;
+ }
+
+ if (mask_ce)
+ mask_ce->perm = (ctx->perm & S_IRWXG) >> 3;
+ else if (group_ce)
+ group_ce->perm = (ctx->perm & S_IRWXG) >> 3;
+ else
+ ret = -1;
}
+unlock:
UNLOCK(&inode->lock);
out:
return ret;
diff --git a/xlators/system/posix-acl/src/posix-acl.h b/xlators/system/posix-acl/src/posix-acl.h
index 6ac2c6a..f857571 100644
--- a/xlators/system/posix-acl/src/posix-acl.h
+++ b/xlators/system/posix-acl/src/posix-acl.h
@@ -17,6 +17,7 @@
#include "common-utils.h"
#include "byte-order.h"
+#define POSIX_ACL_MINIMAL_ACE_COUNT 3
#define POSIX_ACL_READ (0x04)
#define POSIX_ACL_WRITE (0x02)