summary refs log tree commit diff
path: root/fs/splice.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-05-20 21:27:41 +0200
committerJens Axboe <jens.axboe@oracle.com>2008-05-28 14:49:27 +0200
commitca39d651d17df49b6d11f851d56c0ce0ce01ea1a (patch)
tree4bb546d7c8897f028dba7a099799b777e3602cb4 /fs/splice.c
parenta82c53a0e3f57f02782330372b7adad67b417645 (diff)
downloadlinux-ca39d651d17df49b6d11f851d56c0ce0ce01ea1a.tar.gz
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>
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c5
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;
 }