diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-27 19:41:50 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-27 19:41:50 +0300 |
commit | ebeaa8ddb3663b5c6cfc205605c35116381550c5 (patch) | |
tree | 47b9548dc8d0199625a8cb0ab7e8a3b567516549 | |
parent | e0dd880a545c36bd56489a97bb1d337cb873a9d5 (diff) | |
download | linux-ebeaa8ddb3663b5c6cfc205605c35116381550c5.tar.xz |
Revert "jbd2: speedup jbd2_journal_dirty_metadata()"
This reverts commit 2143c1965a761332ae417b22fd477b636e4f54ec.
This commit seems to be the cause of the following jbd2 assertion
failure:
------------[ cut here ]------------
kernel BUG at fs/jbd2/transaction.c:1325!
invalid opcode: 0000 [#1] SMP
Modules linked in: bnep bluetooth fuse ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 ...
CPU: 7 PID: 5509 Comm: gcc Not tainted 4.1.0-10944-g2a298679b411 #1
Hardware name: /DH87RL, BIOS RLH8710H.86A.0327.2014.0924.1645 09/24/2014
task: ffff8803bf866040 ti: ffff880308528000 task.ti: ffff880308528000
RIP: jbd2_journal_dirty_metadata+0x237/0x290
Call Trace:
__ext4_handle_dirty_metadata+0x43/0x1f0
ext4_handle_dirty_dirent_node+0xde/0x160
? jbd2_journal_get_write_access+0x36/0x50
ext4_delete_entry+0x112/0x160
? __ext4_journal_start_sb+0x52/0xb0
ext4_unlink+0xfa/0x260
vfs_unlink+0xec/0x190
do_unlinkat+0x24a/0x270
SyS_unlink+0x11/0x20
entry_SYSCALL_64_fastpath+0x12/0x6a
---[ end trace ae033ebde8d080b4 ]---
which is not easily reproducible (I've seen it just once, and then Ted
was able to reproduce it once). Revert it while Ted and Jan try to
figure out what is wrong.
Cc: Jan Kara <jack@suse.cz>
Acked-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/jbd2/transaction.c | 33 |
1 files changed, 6 insertions, 27 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index cbe8b3aece5b..f3d06174b051 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1280,6 +1280,8 @@ void jbd2_buffer_abort_trigger(struct journal_head *jh, triggers->t_abort(triggers, jh2bh(jh)); } + + /** * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata * @handle: transaction to add buffer to. @@ -1312,36 +1314,12 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) if (is_handle_aborted(handle)) return -EROFS; - if (!buffer_jbd(bh)) { + journal = transaction->t_journal; + jh = jbd2_journal_grab_journal_head(bh); + if (!jh) { ret = -EUCLEAN; goto out; } - /* - * We don't grab jh reference here since the buffer must be part - * of the running transaction. - */ - jh = bh2jh(bh); - J_ASSERT_JH(jh, jh->b_transaction == transaction || - jh->b_next_transaction == transaction); - if (jh->b_modified == 1) { - /* - * If it's in our transaction it must be in BJ_Metadata list. - * The assertion is unreliable since we may see jh in - * inconsistent state unless we grab bh_state lock. But this - * is crutial to catch bugs so let's do a reliable check until - * the lockless handling is fully proven. - */ - if (jh->b_transaction == transaction && - jh->b_jlist != BJ_Metadata) { - jbd_lock_bh_state(bh); - J_ASSERT_JH(jh, jh->b_transaction != transaction || - jh->b_jlist == BJ_Metadata); - jbd_unlock_bh_state(bh); - } - goto out; - } - - journal = transaction->t_journal; jbd_debug(5, "journal_head %p\n", jh); JBUFFER_TRACE(jh, "entry"); @@ -1432,6 +1410,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) spin_unlock(&journal->j_list_lock); out_unlock_bh: jbd_unlock_bh_state(bh); + jbd2_journal_put_journal_head(jh); out: JBUFFER_TRACE(jh, "exit"); return ret; |