aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ioctl32.c
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@sandeen.net>2013-04-25 12:13:06 -0400
committerBen Myers <bpm@sgi.com>2013-05-07 20:00:10 -0400
commit7dfbcbefad4b24d9822d04dbd7b5dd5c3fd45076 (patch)
tree9b993f704d23a9678380171e6870306d34541afb /fs/xfs/xfs_ioctl32.c
parentdd700d9452023a5b6820815a88f93c8f7010c270 (diff)
xfs: fallback to vmalloc for large buffers in xfs_compat_attrlist_by_handle
Shamelessly copied from dchinner's: ad650f5b xfs: fallback to vmalloc for large buffers in xfs_attrmulti_attr_get xfsdump uses a large buffer for extended attributes, which has a kmalloc'd shadow buffer in the kernel. This can fail after the system has been running for some time as it is a high order allocation. Add a fallback to vmalloc so that it doesn't require contiguous memory and so won't randomly fail while xfsdump is running. This was done for xfs_attrlist_by_handle but xfs_compat_attrlist_by_handle (the 32-bit version) needs the same attention. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_ioctl32.c')
-rw-r--r--fs/xfs/xfs_ioctl32.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 63b8fc432151..c0c66259cc91 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -373,9 +373,12 @@ xfs_compat_attrlist_by_handle(
373 return PTR_ERR(dentry); 373 return PTR_ERR(dentry);
374 374
375 error = -ENOMEM; 375 error = -ENOMEM;
376 kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); 376 kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL);
377 if (!kbuf) 377 if (!kbuf) {
378 goto out_dput; 378 kbuf = kmem_zalloc_large(al_hreq.buflen);
379 if (!kbuf)
380 goto out_dput;
381 }
379 382
380 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 383 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
381 error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, 384 error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
@@ -387,7 +390,10 @@ xfs_compat_attrlist_by_handle(
387 error = -EFAULT; 390 error = -EFAULT;
388 391
389 out_kfree: 392 out_kfree:
390 kfree(kbuf); 393 if (is_vmalloc_addr(kbuf))
394 kmem_free_large(kbuf);
395 else
396 kmem_free(kbuf);
391 out_dput: 397 out_dput:
392 dput(dentry); 398 dput(dentry);
393 return error; 399 return error;