diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2007-07-20 09:18:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-20 12:07:01 -0400 |
commit | 6a860c979b35469e4d77da781a96bdb2ca05ae64 (patch) | |
tree | 3160a7a4c76743fa4ca9a9eb9ccb0d67bc363d9b | |
parent | 9d1ca6f13cfedfd127f3be7e447bd6d922806a65 (diff) |
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>
-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 22496d2a73fa..0a0973218084 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -594,7 +594,7 @@ find_page: | |||
594 | ret = add_to_page_cache_lru(page, mapping, index, | 594 | ret = add_to_page_cache_lru(page, mapping, index, |
595 | GFP_KERNEL); | 595 | GFP_KERNEL); |
596 | if (unlikely(ret)) | 596 | if (unlikely(ret)) |
597 | goto out; | 597 | goto out_release; |
598 | } | 598 | } |
599 | 599 | ||
600 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 600 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
@@ -650,8 +650,9 @@ find_page: | |||
650 | */ | 650 | */ |
651 | mark_page_accessed(page); | 651 | mark_page_accessed(page); |
652 | out: | 652 | out: |
653 | page_cache_release(page); | ||
654 | unlock_page(page); | 653 | unlock_page(page); |
654 | out_release: | ||
655 | page_cache_release(page); | ||
655 | out_ret: | 656 | out_ret: |
656 | return ret; | 657 | return ret; |
657 | } | 658 | } |