mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
splice: fix repeated kmap()'s in default_file_splice_read()
We cannot reliably map more than one page at the time, or we risk deadlocking. Just allocate the pages from low mem instead. Reported-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
2b1ccc0ee9
commit
4f23122858
1 changed files with 4 additions and 6 deletions
10
fs/splice.c
10
fs/splice.c
|
@ -580,13 +580,13 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
for (i = 0; i < nr_pages && i < PIPE_BUFFERS && len; i++) {
|
for (i = 0; i < nr_pages && i < PIPE_BUFFERS && len; i++) {
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
page = alloc_page(GFP_HIGHUSER);
|
page = alloc_page(GFP_USER);
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
if (!page)
|
if (!page)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
|
this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
|
||||||
vec[i].iov_base = (void __user *) kmap(page);
|
vec[i].iov_base = (void __user *) page_address(page);
|
||||||
vec[i].iov_len = this_len;
|
vec[i].iov_len = this_len;
|
||||||
pages[i] = page;
|
pages[i] = page;
|
||||||
spd.nr_pages++;
|
spd.nr_pages++;
|
||||||
|
@ -604,7 +604,6 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
|
|
||||||
nr_freed = 0;
|
nr_freed = 0;
|
||||||
for (i = 0; i < spd.nr_pages; i++) {
|
for (i = 0; i < spd.nr_pages; i++) {
|
||||||
kunmap(pages[i]);
|
|
||||||
this_len = min_t(size_t, vec[i].iov_len, res);
|
this_len = min_t(size_t, vec[i].iov_len, res);
|
||||||
partial[i].offset = 0;
|
partial[i].offset = 0;
|
||||||
partial[i].len = this_len;
|
partial[i].len = this_len;
|
||||||
|
@ -624,10 +623,9 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
for (i = 0; i < spd.nr_pages; i++) {
|
for (i = 0; i < spd.nr_pages; i++)
|
||||||
kunmap(pages[i]);
|
|
||||||
__free_page(pages[i]);
|
__free_page(pages[i]);
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(default_file_splice_read);
|
EXPORT_SYMBOL(default_file_splice_read);
|
||||||
|
|
Loading…
Reference in a new issue