[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>
This commit is contained in:
parent
16c523ddab
commit
49d0b21be2
42
fs/splice.c
42
fs/splice.c
|
@ -84,26 +84,43 @@ static void *page_cache_pipe_buf_map(struct file *file,
|
||||||
struct pipe_buffer *buf)
|
struct pipe_buffer *buf)
|
||||||
{
|
{
|
||||||
struct page *page = buf->page;
|
struct page *page = buf->page;
|
||||||
|
int err;
|
||||||
lock_page(page);
|
|
||||||
|
|
||||||
if (!PageUptodate(page)) {
|
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);
|
unlock_page(page);
|
||||||
return ERR_PTR(-EIO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!page->mapping) {
|
return kmap(page);
|
||||||
unlock_page(page);
|
error:
|
||||||
return ERR_PTR(-ENODATA);
|
unlock_page(page);
|
||||||
}
|
return ERR_PTR(err);
|
||||||
|
|
||||||
return kmap(buf->page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
|
static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
|
||||||
struct pipe_buffer *buf)
|
struct pipe_buffer *buf)
|
||||||
{
|
{
|
||||||
unlock_page(buf->page);
|
|
||||||
kunmap(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;
|
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);
|
src = buf->ops->map(file, info, buf);
|
||||||
if (IS_ERR(src))
|
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))
|
if (buf->ops->steal(info, buf))
|
||||||
goto find_page;
|
goto find_page;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this will also set the page locked
|
||||||
|
*/
|
||||||
page = buf->page;
|
page = buf->page;
|
||||||
if (add_to_page_cache(page, mapping, index, gfp_mask))
|
if (add_to_page_cache(page, mapping, index, gfp_mask))
|
||||||
goto find_page;
|
goto find_page;
|
||||||
|
|
Loading…
Reference in New Issue