Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+10 −49
Original line number Original line Diff line number Diff line
@@ -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,
	 */
	 */
	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,
		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)

	/*
	 * Now we splice them into the pipe..
	 */
splice_them:
		return move_to_pipe(pipe, pages, i, offset, len, flags);
		return move_to_pipe(pipe, pages, i, offset, len, flags);

	return 0;
}
}


/**
/**