diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2007-07-20 15:18:12 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-20 09:07:01 -0700 |
commit | 6a860c979b35469e4d77da781a96bdb2ca05ae64 (patch) | |
tree | 3160a7a4c76743fa4ca9a9eb9ccb0d67bc363d9b /fs | |
parent | 9d1ca6f13cfedfd127f3be7e447bd6d922806a65 (diff) | |
download | op-kernel-dev-6a860c979b35469e4d77da781a96bdb2ca05ae64.zip op-kernel-dev-6a860c979b35469e4d77da781a96bdb2ca05ae64.tar.gz |
splice: fix bad unlock_page() in error case
If add_to_page_cache_lru() fails, the page will not be locked. But
splice jumps to an error path that does a page release and unlock,
causing a BUG() in unlock_page().
Fix this by adding one more label that just releases the page. This bug
was actually triggered on EL5 by gurudas pai <gurudas.pai@oracle.com>
using fio.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-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 22496d2..0a09732 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -594,7 +594,7 @@ find_page: ret = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); if (unlikely(ret)) - goto out; + goto out_release; } ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); @@ -650,8 +650,9 @@ find_page: */ mark_page_accessed(page); out: - page_cache_release(page); unlock_page(page); +out_release: + page_cache_release(page); out_ret: return ret; } |