xfs: fallback to vmalloc for large buffers in xfs_getbmap
xfs_getbmap uses for a large buffer for extents, which is kmalloc'd. 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 on files with large extent lists. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
Родитель
ad650f5b27
Коммит
f074211f60
|
@ -5536,8 +5536,12 @@ xfs_getbmap(
|
|||
if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx))
|
||||
return XFS_ERROR(ENOMEM);
|
||||
out = kmem_zalloc(bmv->bmv_count * sizeof(struct getbmapx), KM_MAYFAIL);
|
||||
if (!out) {
|
||||
out = kmem_zalloc_large(bmv->bmv_count *
|
||||
sizeof(struct getbmapx));
|
||||
if (!out)
|
||||
return XFS_ERROR(ENOMEM);
|
||||
}
|
||||
|
||||
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
||||
if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
|
||||
|
@ -5661,6 +5665,9 @@ xfs_getbmap(
|
|||
break;
|
||||
}
|
||||
|
||||
if (is_vmalloc_addr(out))
|
||||
kmem_free_large(out);
|
||||
else
|
||||
kmem_free(out);
|
||||
return error;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче