#include <xfs.h>
#include <linux/posix_acl_xattr.h>
-STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *);
+STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *);
STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
STATIC void xfs_acl_get_endian(xfs_acl_t *);
STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
posix_acl_xattr_header *ext_acl = acl;
xfs_acl_t *xfs_acl;
int error;
+ int basicperms = 0; /* more than std unix perms? */
if (!acl)
return -EINVAL;
/* Incoming ACL exists, set file mode based on its value */
if (kind == _ACL_TYPE_ACCESS)
- xfs_acl_setmode(vp, xfs_acl);
- xfs_acl_set_attr(vp, xfs_acl, kind, &error);
+ xfs_acl_setmode(vp, xfs_acl, &basicperms);
+
+ /*
+ * If we have more than std unix permissions, set up the actual attr.
+ * Otherwise, delete any existing attr. This prevents us from
+ * having actual attrs for permissions that can be stored in the
+ * standard permission bits.
+ */
+ if (!basicperms) {
+ xfs_acl_set_attr(vp, xfs_acl, kind, &error);
+ } else {
+ xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
+ }
+
+
out:
VN_RELE(vp);
_ACL_FREE(xfs_acl);
{
xfs_acl_t *cacl;
int error = 0;
+ int basicperms = 0;
/*
* If the parent does not have a default ACL, or it's an
memcpy(cacl, pdaclp, sizeof(xfs_acl_t));
xfs_acl_filter_mode(vap->va_mode, cacl);
- xfs_acl_setmode(vp, cacl);
+ xfs_acl_setmode(vp, cacl, &basicperms);
/*
* Set the Default and Access ACL on the file. The mode is already
*/
if (vp->v_type == VDIR)
xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error);
- if (!error)
+ if (!error && !basicperms)
xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error);
_ACL_FREE(cacl);
return error;
STATIC int
xfs_acl_setmode(
vnode_t *vp,
- xfs_acl_t *acl)
+ xfs_acl_t *acl,
+ int *basicperms)
{
vattr_t va;
xfs_acl_entry_t *ap;
xfs_acl_entry_t *gap = NULL;
int i, error, nomask = 1;
+ *basicperms = 1;
+
if (acl->acl_cnt == XFS_ACL_NOT_PRESENT)
return 0;
case ACL_GROUP_OBJ:
gap = ap;
break;
- case ACL_MASK:
+ case ACL_MASK: /* more than just standard modes */
nomask = 0;
va.va_mode |= ap->ae_perm << 3;
+ *basicperms = 0;
break;
case ACL_OTHER:
va.va_mode |= ap->ae_perm;
break;
- default:
+ default: /* more than just standard modes */
+ *basicperms = 0;
break;
}
ap++;