diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2008-05-20 23:27:41 +0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-05-28 16:49:27 +0400 |
commit | ca39d651d17df49b6d11f851d56c0ce0ce01ea1a (patch) | |
tree | 4bb546d7c8897f028dba7a099799b777e3602cb4 | |
parent | a82c53a0e3f57f02782330372b7adad67b417645 (diff) | |
download | linux-ca39d651d17df49b6d11f851d56c0ce0ce01ea1a.tar.xz |
splice: handle try_to_release_page() failure
splice currently assumes that try_to_release_page() always suceeds,
but it can return failure. If it does, we cannot steal the page.
Acked-by: Mingming Cao <cmm@us.ibm.com
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | fs/splice.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/splice.c b/fs/splice.c index a048ad2130c3..aa5f6f60b305 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -58,8 +58,8 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, */ wait_on_page_writeback(page); - if (PagePrivate(page)) - try_to_release_page(page, GFP_KERNEL); + if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) + goto out_unlock; /* * If we succeeded in removing the mapping, set LRU flag @@ -75,6 +75,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, * Raced with truncate or failed to remove page from current * address space, unlock and return failure. */ +out_unlock: unlock_page(page); return 1; } |