[PATCH] splice: optimize the splice buffer mapping
We don't really need to lock down the pages, just make sure they
are uptodate.
Signed-off-by: Jens Axboe <axboe@suse.de>
diff --git a/fs/splice.c b/fs/splice.c
index 8b5efcc..50c43a1 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -84,26 +84,43 @@
struct pipe_buffer *buf)
{
struct page *page = buf->page;
-
- lock_page(page);
+ int err;
if (!PageUptodate(page)) {
+ lock_page(page);
+
+ /*
+ * Page got truncated/unhashed. This will cause a 0-byte
+ * splice, if this is the first page
+ */
+ if (!page->mapping) {
+ err = -ENODATA;
+ goto error;
+ }
+
+ /*
+ * uh oh, read-error from disk
+ */
+ if (!PageUptodate(page)) {
+ err = -EIO;
+ goto error;
+ }
+
+ /*
+ * page is ok afterall, fall through to mapping
+ */
unlock_page(page);
- return ERR_PTR(-EIO);
}
- if (!page->mapping) {
- unlock_page(page);
- return ERR_PTR(-ENODATA);
- }
-
- return kmap(buf->page);
+ return kmap(page);
+error:
+ unlock_page(page);
+ return ERR_PTR(err);
}
static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
struct pipe_buffer *buf)
{
- unlock_page(buf->page);
kunmap(buf->page);
}
@@ -379,7 +396,7 @@
int ret;
/*
- * after this, page will be locked and unmapped
+ * make sure the data in this buffer is uptodate
*/
src = buf->ops->map(file, info, buf);
if (IS_ERR(src))
@@ -399,6 +416,9 @@
if (buf->ops->steal(info, buf))
goto find_page;
+ /*
+ * this will also set the page locked
+ */
page = buf->page;
if (add_to_page_cache(page, mapping, index, gfp_mask))
goto find_page;