summaryrefslogtreecommitdiff
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c101
1 files changed, 38 insertions, 63 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 2fca6ebf4cc2..badc78ff1246 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -576,76 +576,51 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
if (this_len + offset > PAGE_CACHE_SIZE)
this_len = PAGE_CACHE_SIZE - offset;
- /*
- * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full
- * page.
- */
- if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) {
+find_page:
+ page = find_lock_page(mapping, index);
+ if (!page) {
+ ret = -ENOMEM;
+ page = page_cache_alloc_cold(mapping);
+ if (unlikely(!page))
+ goto out_ret;
+
/*
- * If steal succeeds, buf->page is now pruned from the
- * pagecache and we can reuse it. The page will also be
- * locked on successful return.
+ * This will also lock the page
*/
- if (buf->ops->steal(pipe, buf))
- goto find_page;
-
- page = buf->page;
- if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) {
- unlock_page(page);
- goto find_page;
- }
-
- page_cache_get(page);
-
- if (!(buf->flags & PIPE_BUF_FLAG_LRU))
- lru_cache_add(page);
- } else {
-find_page:
- page = find_lock_page(mapping, index);
- if (!page) {
- ret = -ENOMEM;
- page = page_cache_alloc_cold(mapping);
- if (unlikely(!page))
- goto out_ret;
+ ret = add_to_page_cache_lru(page, mapping, index,
+ GFP_KERNEL);
+ if (unlikely(ret))
+ goto out;
+ }
- /*
- * This will also lock the page
- */
- ret = add_to_page_cache_lru(page, mapping, index,
- GFP_KERNEL);
+ /*
+ * We get here with the page locked. If the page is also
+ * uptodate, we don't need to do more. If it isn't, we
+ * may need to bring it in if we are not going to overwrite
+ * the full page.
+ */
+ if (!PageUptodate(page)) {
+ if (this_len < PAGE_CACHE_SIZE) {
+ ret = mapping->a_ops->readpage(file, page);
if (unlikely(ret))
goto out;
- }
- /*
- * We get here with the page locked. If the page is also
- * uptodate, we don't need to do more. If it isn't, we
- * may need to bring it in if we are not going to overwrite
- * the full page.
- */
- if (!PageUptodate(page)) {
- if (this_len < PAGE_CACHE_SIZE) {
- ret = mapping->a_ops->readpage(file, page);
- if (unlikely(ret))
- goto out;
-
- lock_page(page);
-
- if (!PageUptodate(page)) {
- /*
- * Page got invalidated, repeat.
- */
- if (!page->mapping) {
- unlock_page(page);
- page_cache_release(page);
- goto find_page;
- }
- ret = -EIO;
- goto out;
+ lock_page(page);
+
+ if (!PageUptodate(page)) {
+ /*
+ * Page got invalidated, repeat.
+ */
+ if (!page->mapping) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto find_page;
}
- } else
- SetPageUptodate(page);
- }
+ ret = -EIO;
+ goto out;
+ }
+ } else
+ SetPageUptodate(page);
}
ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);