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 | 22 ++++++++++++++++------
16 1 file changed, 16 insertions(+), 6 deletions(-)
18 diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
19 index a91f639af6c3..ad10ca8fb9ef 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,25 @@ 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) {
50 + /* If it's in our transaction it must be in BJ_Metadata list */
51 + J_ASSERT_JH(jh, jh->b_transaction != transaction ||
52 + jh->b_jlist == BJ_Metadata);
56 + journal = transaction->t_journal;
57 jbd_debug(5, "journal_head %p\n", jh);
58 JBUFFER_TRACE(jh, "entry");
60 @@ -1421,7 +1432,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
61 spin_unlock(&journal->j_list_lock);
63 jbd_unlock_bh_state(bh);
64 - jbd2_journal_put_journal_head(jh);
66 JBUFFER_TRACE(jh, "exit");