summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_acl.c')
-rw-r--r--fs/xfs/xfs_acl.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 306d883d89b..0e2f37efedd 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -16,11 +16,13 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
+#include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
#include "xfs_acl.h"
#include "xfs_attr.h"
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
-#include "xfs_vnodeops.h"
+#include "xfs_ag.h"
#include "xfs_sb.h"
#include "xfs_mount.h"
#include "xfs_trace.h"
@@ -68,14 +70,15 @@ xfs_acl_from_disk(
switch (acl_e->e_tag) {
case ACL_USER:
+ acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id));
+ break;
case ACL_GROUP:
- acl_e->e_id = be32_to_cpu(ace->ae_id);
+ acl_e->e_gid = xfs_gid_to_kgid(be32_to_cpu(ace->ae_id));
break;
case ACL_USER_OBJ:
case ACL_GROUP_OBJ:
case ACL_MASK:
case ACL_OTHER:
- acl_e->e_id = ACL_UNDEFINED_ID;
break;
default:
goto fail;
@@ -101,7 +104,18 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
acl_e = &acl->a_entries[i];
ace->ae_tag = cpu_to_be32(acl_e->e_tag);
- ace->ae_id = cpu_to_be32(acl_e->e_id);
+ switch (acl_e->e_tag) {
+ case ACL_USER:
+ ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(acl_e->e_uid));
+ break;
+ case ACL_GROUP:
+ ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(acl_e->e_gid));
+ break;
+ default:
+ ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID);
+ break;
+ }
+
ace->ae_perm = cpu_to_be16(acl_e->e_perm);
}
}
@@ -138,7 +152,7 @@ xfs_get_acl(struct inode *inode, int type)
* go out to the disk.
*/
len = XFS_ACL_MAX_SIZE(ip->i_mount);
- xfs_acl = kzalloc(len, GFP_KERNEL);
+ xfs_acl = kmem_zalloc_large(len, KM_SLEEP);
if (!xfs_acl)
return ERR_PTR(-ENOMEM);
@@ -161,10 +175,10 @@ xfs_get_acl(struct inode *inode, int type)
if (IS_ERR(acl))
goto out;
- out_update_cache:
+out_update_cache:
set_cached_acl(inode, type, acl);
- out:
- kfree(xfs_acl);
+out:
+ kmem_free(xfs_acl);
return acl;
}
@@ -195,7 +209,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
struct xfs_acl *xfs_acl;
int len = XFS_ACL_MAX_SIZE(ip->i_mount);
- xfs_acl = kzalloc(len, GFP_KERNEL);
+ xfs_acl = kmem_zalloc_large(len, KM_SLEEP);
if (!xfs_acl)
return -ENOMEM;
@@ -208,7 +222,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
len, ATTR_ROOT);
- kfree(xfs_acl);
+ kmem_free(xfs_acl);
} else {
/*
* A NULL ACL argument means we want to remove the ACL.
@@ -360,7 +374,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
return -EINVAL;
if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
return value ? -EACCES : 0;
- if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
+ if (!inode_owner_or_capable(inode))
return -EPERM;
if (!value)