| From d0869258353c2bb25e400e2d2b40e310edb39c52 Mon Sep 17 00:00:00 2001 |
| From: Jan Kara <jack@suse.cz> |
| Date: Fri, 23 Nov 2012 14:03:04 +0100 |
| Subject: [PATCH] jbd: Fix lock ordering bug in journal_unmap_buffer() |
| |
| commit 25389bb207987b5774182f763b9fb65ff08761c8 upstream. |
| |
| Commit 09e05d48 introduced a wait for transaction commit into |
| journal_unmap_buffer() in the case we are truncating a buffer undergoing commit |
| in the page stradding i_size on a filesystem with blocksize < pagesize. Sadly |
| we forgot to drop buffer lock before waiting for transaction commit and thus |
| deadlock is possible when kjournald wants to lock the buffer. |
| |
| Fix the problem by dropping the buffer lock before waiting for transaction |
| commit. Since we are still holding page lock (and that is OK), buffer cannot |
| disappear under us. |
| |
| Signed-off-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| fs/jbd/transaction.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c |
| index bc8ab97dcd90..590e23885c98 100644 |
| --- a/fs/jbd/transaction.c |
| +++ b/fs/jbd/transaction.c |
| @@ -1956,7 +1956,9 @@ retry: |
| spin_unlock(&journal->j_list_lock); |
| jbd_unlock_bh_state(bh); |
| spin_unlock(&journal->j_state_lock); |
| + unlock_buffer(bh); |
| log_wait_commit(journal, tid); |
| + lock_buffer(bh); |
| goto retry; |
| } |
| /* |
| -- |
| 1.8.5.2 |
| |