add patch fix-ocfs2-corrupt-when-updating-journal-superblock-fails
[ext4-patch-queue.git] / speedup-jbd2_journal_dirty_metadata
blob382abe7e8d64d11c73523ea2382ebf45c62d6b57
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
10 references.
12 Signed-off-by: Jan Kara <jack@suse.cz>
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 ---
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));
24  }
28  /**
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))
34                 return -EROFS;
35 -       journal = transaction->t_journal;
36 -       jh = jbd2_journal_grab_journal_head(bh);
37 -       if (!jh) {
38 +       if (!buffer_jbd(bh)) {
39                 ret = -EUCLEAN;
40                 goto out;
41         }
42 +       /*
43 +        * We don't grab jh reference here since the buffer must be part
44 +        * of the running transaction.
45 +        */
46 +       jh = bh2jh(bh);
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);
53 +               goto out;
54 +       }
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);
62  out_unlock_bh:
63         jbd_unlock_bh_state(bh);
64 -       jbd2_journal_put_journal_head(jh);
65  out:
66         JBUFFER_TRACE(jh, "exit");
67         return ret;
68 -- 
69 2.1.4