Prechádzať zdrojové kódy

[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>
Jens Axboe 19 rokov pred
rodič
commit
49d0b21be2
1 zmenil súbory, kde vykonal 30 pridanie a 10 odobranie
  1. 30 10
      fs/splice.c

+ 30 - 10
fs/splice.c

@@ -84,26 +84,43 @@ static void *page_cache_pipe_buf_map(struct file *file,
 				     struct pipe_buffer *buf)
 {
 	struct page *page = buf->page;
-
-	lock_page(page);
+	int err;
 
 	if (!PageUptodate(page)) {
-		unlock_page(page);
-		return ERR_PTR(-EIO);
-	}
+		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;
+		}
 
-	if (!page->mapping) {
+		/*
+		 * page is ok afterall, fall through to 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 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
 	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 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
 		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;