aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-09-02 06:52:59 -0400
committerBen Myers <bpm@sgi.com>2013-09-10 14:56:25 -0400
commit2dc164f2965b92a6efd2edb9e2813271741e96db (patch)
tree2687c83330c2328b0ffc49ff5a414a4d53280b77 /fs
parent0a4edc8f0b54cd5f613e7fda7dc8106cb9869bc9 (diff)
xfs: fix memory allocation failures with ACLs
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_acl.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 69518960b2ba..4ea73cc44259 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -152,9 +152,12 @@ xfs_get_acl(struct inode *inode, int type)
152 * go out to the disk. 152 * go out to the disk.
153 */ 153 */
154 len = XFS_ACL_MAX_SIZE(ip->i_mount); 154 len = XFS_ACL_MAX_SIZE(ip->i_mount);
155 xfs_acl = kzalloc(len, GFP_KERNEL); 155 xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
156 if (!xfs_acl) 156 if (!xfs_acl) {
157 return ERR_PTR(-ENOMEM); 157 xfs_acl = kmem_zalloc_large(len);
158 if (!xfs_acl)
159 return ERR_PTR(-ENOMEM);
160 }
158 161
159 error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl, 162 error = -xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl,
160 &len, ATTR_ROOT); 163 &len, ATTR_ROOT);
@@ -175,10 +178,13 @@ xfs_get_acl(struct inode *inode, int type)
175 if (IS_ERR(acl)) 178 if (IS_ERR(acl))
176 goto out; 179 goto out;
177 180
178 out_update_cache: 181out_update_cache:
179 set_cached_acl(inode, type, acl); 182 set_cached_acl(inode, type, acl);
180 out: 183out:
181 kfree(xfs_acl); 184 if (is_vmalloc_addr(xfs_acl))
185 kmem_free_large(xfs_acl);
186 else
187 kfree(xfs_acl);
182 return acl; 188 return acl;
183} 189}
184 190
@@ -209,9 +215,12 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
209 struct xfs_acl *xfs_acl; 215 struct xfs_acl *xfs_acl;
210 int len = XFS_ACL_MAX_SIZE(ip->i_mount); 216 int len = XFS_ACL_MAX_SIZE(ip->i_mount);
211 217
212 xfs_acl = kzalloc(len, GFP_KERNEL); 218 xfs_acl = kmem_zalloc(len, KM_SLEEP | KM_MAYFAIL);
213 if (!xfs_acl) 219 if (!xfs_acl) {
214 return -ENOMEM; 220 xfs_acl = kmem_zalloc_large(len);
221 if (!xfs_acl)
222 return -ENOMEM;
223 }
215 224
216 xfs_acl_to_disk(xfs_acl, acl); 225 xfs_acl_to_disk(xfs_acl, acl);
217 226
@@ -222,7 +231,10 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
222 error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl, 231 error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
223 len, ATTR_ROOT); 232 len, ATTR_ROOT);
224 233
225 kfree(xfs_acl); 234 if (is_vmalloc_addr(xfs_acl))
235 kmem_free_large(xfs_acl);
236 else
237 kfree(xfs_acl);
226 } else { 238 } else {
227 /* 239 /*
228 * A NULL ACL argument means we want to remove the ACL. 240 * A NULL ACL argument means we want to remove the ACL.