[PATCH] splice: optimize the splice buffer mapping
authorJens Axboe <axboe@suse.de>
Mon, 10 Apr 2006 07:04:41 +0000 (09:04 +0200)
committerJens Axboe <axboe@suse.de>
Mon, 10 Apr 2006 07:04:41 +0000 (09:04 +0200)
We don't really need to lock down the pages, just make sure they
are uptodate.

Signed-off-by: Jens Axboe <axboe@suse.de>
fs/splice.c

index 8b5efcc906dcc8d6a52dbb98a51235841be8b80e..50c43a1e0923435bda007a5556930c483a95328c 100644 (file)
@@ -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;