X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_acl.c;h=4ca4beb7bb546b6fce761d4d8cc29fefdbb7732b;hb=0f285c8a1c4cacfd9f2aec077b06e2b537ee57ab;hp=4b0cb474be4c3906c79fa6e997f8b2e1e3c15639;hpb=816724e65c72a90a44fbad0ef0b59b186c85fa90;p=linux-2.6-omap-h63xx.git diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b0cb474be4..3e4648ad9cf 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -31,8 +31,8 @@ #include "xfs_inode.h" #include "xfs_btree.h" #include "xfs_acl.h" -#include "xfs_mac.h" #include "xfs_attr.h" +#include "xfs_vnodeops.h" #include #include @@ -72,7 +72,7 @@ xfs_acl_vhasacl_default( { int error; - if (!VN_ISDIR(vp)) + if (!S_ISDIR(vp->i_mode)) return 0; xfs_acl_get_attr(vp, NULL, _ACL_TYPE_DEFAULT, ATTR_KERNOVAL, &error); return (error == 0); @@ -238,15 +238,8 @@ xfs_acl_vget( error = EINVAL; goto out; } - if (kind == _ACL_TYPE_ACCESS) { - bhv_vattr_t va; - - va.va_mask = XFS_AT_MODE; - error = bhv_vop_getattr(vp, &va, 0, sys_cred); - if (error) - goto out; - xfs_acl_sync_mode(va.va_mode, xfs_acl); - } + if (kind == _ACL_TYPE_ACCESS) + xfs_acl_sync_mode(xfs_vtoi(vp)->i_d.di_mode, xfs_acl); error = -posix_acl_xfs_to_xattr(xfs_acl, ext_acl, size); } out: @@ -266,9 +259,10 @@ xfs_acl_vremove( VN_HOLD(vp); error = xfs_acl_allow_set(vp, kind); if (!error) { - error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT? + error = xfs_attr_remove(xfs_vtoi(vp), + kind == _ACL_TYPE_DEFAULT? SGI_ACL_DEFAULT: SGI_ACL_FILE, - ATTR_ROOT, sys_cred); + ATTR_ROOT); if (error == ENOATTR) error = 0; /* 'scool */ } @@ -306,12 +300,13 @@ xfs_acl_vset( 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 (!error && kind == _ACL_TYPE_ACCESS) + error = xfs_acl_setmode(vp, xfs_acl, &basicperms); + + if (error) + goto out; /* * If we have more than std unix permissions, set up the actual attr. @@ -322,7 +317,7 @@ xfs_acl_vset( if (!basicperms) { xfs_acl_set_attr(vp, xfs_acl, kind, &error); } else { - xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); + error = -xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); } out: @@ -339,14 +334,14 @@ xfs_acl_iaccess( { xfs_acl_t *acl; int rval; + struct xfs_name acl_name = {SGI_ACL_FILE, SGI_ACL_FILE_SIZE}; if (!(_ACL_ALLOC(acl))) return -1; /* If the file has no ACL return -1. */ rval = sizeof(xfs_acl_t); - if (xfs_attr_fetch(ip, SGI_ACL_FILE, SGI_ACL_FILE_SIZE, - (char *)acl, &rval, ATTR_ROOT | ATTR_KERNACCESS, cr)) { + if (xfs_attr_fetch(ip, &acl_name, (char *)acl, &rval, ATTR_ROOT)) { _ACL_FREE(acl); return -1; } @@ -371,47 +366,14 @@ xfs_acl_allow_set( bhv_vnode_t *vp, int kind) { - bhv_vattr_t va; - int error; - - if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) + if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) return EPERM; - if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) + if (kind == _ACL_TYPE_DEFAULT && !S_ISDIR(vp->i_mode)) return ENOTDIR; - if (vp->v_vfsp->vfs_flag & VFS_RDONLY) + if (vp->i_sb->s_flags & MS_RDONLY) return EROFS; - va.va_mask = XFS_AT_UID; - error = bhv_vop_getattr(vp, &va, 0, NULL); - if (error) - return error; - if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) + if (xfs_vtoi(vp)->i_d.di_uid != current->fsuid && !capable(CAP_FOWNER)) return EPERM; - return error; -} - -/* - * The access control process to determine the access permission: - * if uid == file owner id, use the file owner bits. - * if gid == file owner group id, use the file group bits. - * scan ACL for a matching user or group, and use matched entry - * permission. Use total permissions of all matching group entries, - * until all acl entries are exhausted. The final permission produced - * by matching acl entry or entries needs to be & with group permission. - * if not owner, owning group, or matching entry in ACL, use file - * other bits. - */ -STATIC int -xfs_acl_capability_check( - mode_t mode, - cred_t *cr) -{ - if ((mode & ACL_READ) && !capable_cred(cr, CAP_DAC_READ_SEARCH)) - return EACCES; - if ((mode & ACL_WRITE) && !capable_cred(cr, CAP_DAC_OVERRIDE)) - return EACCES; - if ((mode & ACL_EXECUTE) && !capable_cred(cr, CAP_DAC_OVERRIDE)) - return EACCES; - return 0; } @@ -436,7 +398,6 @@ xfs_acl_access( matched.ae_tag = 0; /* Invalid type */ matched.ae_perm = 0; - md >>= 6; /* Normalize the bits for comparison */ for (i = 0; i < fap->acl_cnt; i++) { /* @@ -518,7 +479,8 @@ xfs_acl_access( break; } - return xfs_acl_capability_check(md, cr); + /* EACCES tells generic_permission to check for capability overrides */ + return EACCES; } /* @@ -614,9 +576,10 @@ xfs_acl_get_attr( ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); flags |= ATTR_ROOT; - *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ? + *error = xfs_attr_get(xfs_vtoi(vp), + kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT, - (char *)aclp, &len, flags, sys_cred); + (char *)aclp, &len, flags); if (*error || (flags & ATTR_KERNOVAL)) return; xfs_acl_get_endian(aclp); @@ -652,9 +615,10 @@ xfs_acl_set_attr( INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); } INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); - *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ? + *error = xfs_attr_set(xfs_vtoi(vp), + kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT, - (char *)newacl, len, ATTR_ROOT, sys_cred); + (char *)newacl, len, ATTR_ROOT); _ACL_FREE(newacl); } @@ -664,7 +628,6 @@ xfs_acl_vtoacl( xfs_acl_t *access_acl, xfs_acl_t *default_acl) { - bhv_vattr_t va; int error = 0; if (access_acl) { @@ -673,16 +636,10 @@ xfs_acl_vtoacl( * be obtained for some reason, invalidate the access ACL. */ xfs_acl_get_attr(vp, access_acl, _ACL_TYPE_ACCESS, 0, &error); - if (!error) { - /* Got the ACL, need the mode... */ - va.va_mask = XFS_AT_MODE; - error = bhv_vop_getattr(vp, &va, 0, sys_cred); - } - if (error) access_acl->acl_cnt = XFS_ACL_NOT_PRESENT; else /* We have a good ACL and the file mode, synchronize. */ - xfs_acl_sync_mode(va.va_mode, access_acl); + xfs_acl_sync_mode(xfs_vtoi(vp)->i_d.di_mode, access_acl); } if (default_acl) { @@ -700,7 +657,7 @@ xfs_acl_vtoacl( int xfs_acl_inherit( bhv_vnode_t *vp, - bhv_vattr_t *vap, + mode_t mode, xfs_acl_t *pdaclp) { xfs_acl_t *cacl; @@ -728,8 +685,10 @@ xfs_acl_inherit( return ENOMEM; memcpy(cacl, pdaclp, sizeof(xfs_acl_t)); - xfs_acl_filter_mode(vap->va_mode, cacl); - xfs_acl_setmode(vp, cacl, &basicperms); + xfs_acl_filter_mode(mode, cacl); + error = xfs_acl_setmode(vp, cacl, &basicperms); + if (error) + goto out_error; /* * Set the Default and Access ACL on the file. The mode is already @@ -738,10 +697,11 @@ xfs_acl_inherit( * If the new file is a directory, its default ACL is a copy of * the containing directory's default ACL. */ - if (VN_ISDIR(vp)) + if (S_ISDIR(vp->i_mode)) xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error); if (!error && !basicperms) xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error); +out_error: _ACL_FREE(cacl); return error; } @@ -759,10 +719,10 @@ xfs_acl_setmode( xfs_acl_t *acl, int *basicperms) { - bhv_vattr_t va; + struct iattr iattr; xfs_acl_entry_t *ap; xfs_acl_entry_t *gap = NULL; - int i, error, nomask = 1; + int i, nomask = 1; *basicperms = 1; @@ -773,29 +733,25 @@ xfs_acl_setmode( * Copy the u::, g::, o::, and m:: bits from the ACL into the * mode. The m:: bits take precedence over the g:: bits. */ - va.va_mask = XFS_AT_MODE; - error = bhv_vop_getattr(vp, &va, 0, sys_cred); - if (error) - return error; - - va.va_mask = XFS_AT_MODE; - va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); + iattr.ia_valid = ATTR_MODE; + iattr.ia_mode = xfs_vtoi(vp)->i_d.di_mode; + iattr.ia_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); ap = acl->acl_entry; for (i = 0; i < acl->acl_cnt; ++i) { switch (ap->ae_tag) { case ACL_USER_OBJ: - va.va_mode |= ap->ae_perm << 6; + iattr.ia_mode |= ap->ae_perm << 6; break; case ACL_GROUP_OBJ: gap = ap; break; case ACL_MASK: /* more than just standard modes */ nomask = 0; - va.va_mode |= ap->ae_perm << 3; + iattr.ia_mode |= ap->ae_perm << 3; *basicperms = 0; break; case ACL_OTHER: - va.va_mode |= ap->ae_perm; + iattr.ia_mode |= ap->ae_perm; break; default: /* more than just standard modes */ *basicperms = 0; @@ -806,9 +762,9 @@ xfs_acl_setmode( /* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */ if (gap && nomask) - va.va_mode |= gap->ae_perm << 3; + iattr.ia_mode |= gap->ae_perm << 3; - return bhv_vop_setattr(vp, &va, 0, sys_cred); + return xfs_setattr(xfs_vtoi(vp), &iattr, 0, sys_cred); } /*