diff options
author | Anand Avati <avati@redhat.com> | 2013-09-15 15:00:06 -0700 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-09-25 14:09:15 -0700 |
commit | 56769c4db9e25f10c35b7f9b6ccf24dc27b35f07 (patch) | |
tree | 2746758353de959cfabb11221e2325c07bca4a0e | |
parent | 22e982e31bc232f3d9597a41f49e715428e010ce (diff) |
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/6002
Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r-- | xlators/system/posix-acl/src/posix-acl.c | 46 | ||||
-rw-r--r-- | xlators/system/posix-acl/src/posix-acl.h | 1 |
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 3e2f7f212..4658cad49 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 6ac2c6a84..f85757106 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) |