Skip to content

Commit

Permalink
xfs: fix memory allocation failures with ACLs
Browse files Browse the repository at this point in the history
Ever since increasing the number of supported ACLs from 25 to as
many as can fit in an xattr, there have been reports of order 4
memory allocations failing in the ACL code. Fix it in the same way
we've fixed all the xattr read/write code that has the same problem.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
  • Loading branch information
Dave Chinner authored and Ben Myers committed Sep 10, 2013
1 parent 0a4edc8 commit 2dc164f
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions fs/xfs/xfs_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,12 @@ 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);
if (!xfs_acl)
return ERR_PTR(-ENOMEM);
xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
if (!xfs_acl) {
xfs_acl = kmem_zalloc_large(len);
if (!xfs_acl)
return ERR_PTR(-ENOMEM);
}

error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl,
&len, ATTR_ROOT);
Expand All @@ -175,10 +178,13 @@ 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:
if (is_vmalloc_addr(xfs_acl))
kmem_free_large(xfs_acl);
else
kfree(xfs_acl);
return acl;
}

Expand Down Expand Up @@ -209,9 +215,12 @@ 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);
if (!xfs_acl)
return -ENOMEM;
xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
if (!xfs_acl) {
xfs_acl = kmem_zalloc_large(len);
if (!xfs_acl)
return -ENOMEM;
}

xfs_acl_to_disk(xfs_acl, acl);

Expand All @@ -222,7 +231,10 @@ 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);
if (is_vmalloc_addr(xfs_acl))
kmem_free_large(xfs_acl);
else
kfree(xfs_acl);
} else {
/*
* A NULL ACL argument means we want to remove the ACL.
Expand Down

0 comments on commit 2dc164f

Please sign in to comment.