Skip to content

Commit

Permalink
jbd2: speedup jbd2_journal_dirty_metadata()
Browse files Browse the repository at this point in the history
It is often the case that we mark buffer as having dirty metadata when
the buffer is already in that state (frequent for bitmaps, inode table
blocks, superblock). Thus it is unnecessary to contend on grabbing
journal head reference and bh_state lock. Avoid that by checking whether
any modification to the buffer is needed before grabbing any locks or
references.

Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
  • Loading branch information
jankara authored and tytso committed Jun 21, 2015
1 parent 7b506b1 commit 2143c19
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions fs/jbd2/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -1280,8 +1280,6 @@ 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.
Expand Down Expand Up @@ -1314,12 +1312,36 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)

if (is_handle_aborted(handle))
return -EROFS;
journal = transaction->t_journal;
jh = jbd2_journal_grab_journal_head(bh);
if (!jh) {
if (!buffer_jbd(bh)) {
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");

Expand Down Expand Up @@ -1410,7 +1432,6 @@ 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;
Expand Down

0 comments on commit 2143c19

Please sign in to comment.