int xfs_acl_vset( xfs_vnode_t *vp, void *acl, size_t size, int kind) { 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; if (!(_ACL_ALLOC(xfs_acl))) return -ENOMEM; error = posix_acl_xattr_to_xfs(ext_acl, size, xfs_acl); if (error) { _ACL_FREE(xfs_acl); return -error; } if (!xfs_acl->acl_cnt) { _ACL_FREE(xfs_acl); return 0; } VN_HOLD(vp); error = xfs_acl_allow_set(vp, kind); if (error) goto out; /* Incoming ACL exists, set file mode based on its value */ if (kind == _ACL_TYPE_ACCESS) 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); return -error; }
int xfs_acl_vremove( xfs_vnode_t *vp, int kind) { int error; VN_HOLD(vp); error = xfs_acl_allow_set(vp, kind); if (!error) { XVOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT? SGI_ACL_DEFAULT: SGI_ACL_FILE, ATTR_ROOT, sys_cred, error); if (error == ENOATTR) error = 0; /* 'scool */ } VN_RELE(vp); return -error; }
int xfs_acl_vremove( bhv_vnode_t *vp, int kind) { int error; VN_HOLD(vp); error = xfs_acl_allow_set(vp, kind); if (!error) { error = xfs_attr_remove(xfs_vtoi(vp), kind == _ACL_TYPE_DEFAULT? SGI_ACL_DEFAULT: SGI_ACL_FILE, ATTR_ROOT); if (error == ENOATTR) error = 0; /* 'scool */ } VN_RELE(vp); return -error; }