1 jbd2: speedup jbd2_journal_dirty_metadata()
3 From: Jan Kara <jack@suse.cz>
5 It is often the case that we mark buffer as having dirty metadata when
6 the buffer is already in that state (frequent for bitmaps, inode table
7 blocks, superblock). Thus it is unnecessary to contend on grabbing
8 journal head reference and bh_state lock. Avoid that by checking whether
9 any modification to the buffer is needed before grabbing any locks or
12 Signed-off-by: Jan Kara <jack@suse.cz>
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
15 fs/jbd2/transaction.c | 33 +++++++++++++++++++++++++++------
16 1 file changed, 27 insertions(+), 6 deletions(-)
18 diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
19 index a91f639af6c3..5887c880422b 100644
20 --- a/fs/jbd2/transaction.c
21 +++ b/fs/jbd2/transaction.c
22 @@ -1290,8 +1290,6 @@ void jbd2_buffer_abort_trigger(struct journal_head *jh,
23 triggers->t_abort(triggers, jh2bh(jh));
29 * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata
30 * @handle: transaction to add buffer to.
31 @@ -1325,12 +1323,36 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
32 WARN_ON(!transaction);
33 if (is_handle_aborted(handle))
35 - journal = transaction->t_journal;
36 - jh = jbd2_journal_grab_journal_head(bh);
38 + if (!buffer_jbd(bh)) {
43 + * We don't grab jh reference here since the buffer must be part
44 + * of the running transaction.
47 + J_ASSERT_JH(jh, jh->b_transaction == transaction ||
48 + jh->b_next_transaction == transaction);
49 + if (jh->b_modified == 1) {
51 + * If it's in our transaction it must be in BJ_Metadata list.
52 + * The assertion is unreliable since we may see jh in
53 + * inconsistent state unless we grab bh_state lock. But this
54 + * is crutial to catch bugs so let's do a reliable check until
55 + * the lockless handling is fully proven.
57 + if (jh->b_transaction == transaction &&
58 + jh->b_jlist != BJ_Metadata) {
59 + jbd_lock_bh_state(bh);
60 + J_ASSERT_JH(jh, jh->b_transaction != transaction ||
61 + jh->b_jlist == BJ_Metadata);
62 + jbd_unlock_bh_state(bh);
67 + journal = transaction->t_journal;
68 jbd_debug(5, "journal_head %p\n", jh);
69 JBUFFER_TRACE(jh, "entry");
71 @@ -1421,7 +1443,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
72 spin_unlock(&journal->j_list_lock);
74 jbd_unlock_bh_state(bh);
75 - jbd2_journal_put_journal_head(jh);
77 JBUFFER_TRACE(jh, "exit");