aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2013-04-04 01:05:13 -0400
committerBen Myers <bpm@sgi.com>2013-05-07 19:56:38 -0400
commitdd700d9452023a5b6820815a88f93c8f7010c270 (patch)
tree49132456e58a9cd79a74e43954a8dac054db09a3 /fs/xfs
parent742ae1e35b038ed65ddd86182723441ea74db765 (diff)
xfs: fallback to vmalloc for large buffers in xfs_attrlist_by_handle
Shamelessly copied from dchinner's: ad650f5b xfs: fallback to vmalloc for large buffers in xfs_attrmulti_attr_get xfsdump uses for 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. 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')
-rw-r--r--fs/xfs/xfs_ioctl.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index d681e34c2950..5e999680094a 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -422,9 +422,12 @@ xfs_attrlist_by_handle(
422 if (IS_ERR(dentry)) 422 if (IS_ERR(dentry))
423 return PTR_ERR(dentry); 423 return PTR_ERR(dentry);
424 424
425 kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL); 425 kbuf = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL);
426 if (!kbuf) 426 if (!kbuf) {
427 goto out_dput; 427 kbuf = kmem_zalloc_large(al_hreq.buflen);
428 if (!kbuf)
429 goto out_dput;
430 }
428 431
429 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 432 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
430 error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, 433 error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
@@ -436,7 +439,10 @@ xfs_attrlist_by_handle(
436 error = -EFAULT; 439 error = -EFAULT;
437 440
438 out_kfree: 441 out_kfree:
439 kfree(kbuf); 442 if (is_vmalloc_addr(kbuf))
443 kmem_free_large(kbuf);
444 else
445 kmem_free(kbuf);
440 out_dput: 446 out_dput:
441 dput(dentry); 447 dput(dentry);
442 return error; 448 return error;