diff options
| -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 3e2f7f21260..4658cad49d1 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 6ac2c6a8433..f8575710634 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)  | 
