ext4: annotate data race in jbd2_journal_dirty_metadata()
authorJan Kara <jack@suse.cz>
Tue, 6 Apr 2021 16:18:00 +0000 (18:18 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 10 Apr 2021 01:19:33 +0000 (21:19 -0400)
Assertion checks in jbd2_journal_dirty_metadata() are known to be racy
but we don't want to be grabbing locks just for them.  We thus recheck
them under b_state_lock only if it looks like they would fail. Annotate
the checks with data_race().

Cc: stable@kernel.org
Reported-by: Hao Sun <sunhao.th@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20210406161804.20150-2-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/jbd2/transaction.c

index 398d1d9..e8fc45f 100644 (file)
@@ -1479,8 +1479,8 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
         * crucial to catch bugs so let's do a reliable check until the
         * lockless handling is fully proven.
         */
-       if (jh->b_transaction != transaction &&
-           jh->b_next_transaction != transaction) {
+       if (data_race(jh->b_transaction != transaction &&
+           jh->b_next_transaction != transaction)) {
                spin_lock(&jh->b_state_lock);
                J_ASSERT_JH(jh, jh->b_transaction == transaction ||
                                jh->b_next_transaction == transaction);
@@ -1488,8 +1488,8 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
        }
        if (jh->b_modified == 1) {
                /* If it's in our transaction it must be in BJ_Metadata list. */
-               if (jh->b_transaction == transaction &&
-                   jh->b_jlist != BJ_Metadata) {
+               if (data_race(jh->b_transaction == transaction &&
+                   jh->b_jlist != BJ_Metadata)) {
                        spin_lock(&jh->b_state_lock);
                        if (jh->b_transaction == transaction &&
                            jh->b_jlist != BJ_Metadata)