|
@@ -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);
|