[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;