Commit 16c523dd authored by Jens Axboe's avatar Jens Axboe

[PATCH] splice: cleanup __generic_file_splice_read()

The whole shadow/pages logic got overly complex, and this simpler
approach is actually faster in testing.
Signed-off-by: default avatarJens Axboe <axboe@suse.de>
parent c0bd1f65
...@@ -220,10 +220,10 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, ...@@ -220,10 +220,10 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
{ {
struct address_space *mapping = in->f_mapping; struct address_space *mapping = in->f_mapping;
unsigned int offset, nr_pages; unsigned int offset, nr_pages;
struct page *pages[PIPE_BUFFERS], *shadow[PIPE_BUFFERS]; struct page *pages[PIPE_BUFFERS];
struct page *page; struct page *page;
pgoff_t index, pidx; pgoff_t index;
int i, j; int i;
index = in->f_pos >> PAGE_CACHE_SHIFT; index = in->f_pos >> PAGE_CACHE_SHIFT;
offset = in->f_pos & ~PAGE_CACHE_MASK; offset = in->f_pos & ~PAGE_CACHE_MASK;
...@@ -237,42 +237,14 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, ...@@ -237,42 +237,14 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
*/ */
do_page_cache_readahead(mapping, in, index, nr_pages); do_page_cache_readahead(mapping, in, index, nr_pages);
/*
* Get as many pages from the page cache as possible..
* Start IO on the page cache entries we create (we
* can assume that any pre-existing ones we find have
* already had IO started on them).
*/
i = find_get_pages(mapping, index, nr_pages, pages);
/*
* common case - we found all pages and they are contiguous,
* kick them off
*/
if (i && (pages[i - 1]->index == index + i - 1))
goto splice_them;
/*
* fill shadow[] with pages at the right locations, so we only
* have to fill holes
*/
memset(shadow, 0, nr_pages * sizeof(struct page *));
for (j = 0; j < i; j++)
shadow[pages[j]->index - index] = pages[j];
/* /*
* now fill in the holes * now fill in the holes
*/ */
for (i = 0, pidx = index; i < nr_pages; pidx++, i++) { for (i = 0; i < nr_pages; i++, index++) {
int error;
if (shadow[i])
continue;
/* /*
* no page there, look one up / create it * no page there, look one up / create it
*/ */
page = find_or_create_page(mapping, pidx, page = find_or_create_page(mapping, index,
mapping_gfp_mask(mapping)); mapping_gfp_mask(mapping));
if (!page) if (!page)
break; break;
...@@ -280,31 +252,20 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, ...@@ -280,31 +252,20 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
if (PageUptodate(page)) if (PageUptodate(page))
unlock_page(page); unlock_page(page);
else { else {
error = mapping->a_ops->readpage(in, page); int error = mapping->a_ops->readpage(in, page);
if (unlikely(error)) { if (unlikely(error)) {
page_cache_release(page); page_cache_release(page);
break; break;
} }
} }
shadow[i] = page; pages[i] = page;
}
if (!i) {
for (i = 0; i < nr_pages; i++) {
if (shadow[i])
page_cache_release(shadow[i]);
}
return 0;
} }
memcpy(pages, shadow, i * sizeof(struct page *)); if (i)
return move_to_pipe(pipe, pages, i, offset, len, flags);
/* return 0;
* Now we splice them into the pipe..
*/
splice_them:
return move_to_pipe(pipe, pages, i, offset, len, flags);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment