jbd2: add sparse annotations for add_transaction_credits()
authorTheodore Ts'o <tytso@mit.edu>
Sat, 14 Aug 2021 14:54:09 +0000 (10:54 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 31 Aug 2021 03:36:50 +0000 (23:36 -0400)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/jbd2/transaction.c

index 8804e12..5347411 100644 (file)
@@ -223,9 +223,15 @@ static void sub_reserved_credits(journal_t *journal, int blocks)
  * with j_state_lock held for reading. Returns 0 if handle joined the running
  * transaction. Returns 1 if we had to wait, j_state_lock is dropped, and
  * caller must retry.
+ *
+ * Note: because j_state_lock may be dropped depending on the return
+ * value, we need to fake out sparse so ti doesn't complain about a
+ * locking imbalance.  Callers of add_transaction_credits will need to
+ * make a similar accomodation.
  */
 static int add_transaction_credits(journal_t *journal, int blocks,
                                   int rsv_blocks)
+__must_hold(&journal->j_state_lock)
 {
        transaction_t *t = journal->j_running_transaction;
        int needed;
@@ -238,6 +244,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
        if (t->t_state != T_RUNNING) {
                WARN_ON_ONCE(t->t_state >= T_FLUSH);
                wait_transaction_locked(journal);
+               __acquire(&journal->j_state_lock); /* fake out sparse */
                return 1;
        }
 
@@ -266,10 +273,12 @@ static int add_transaction_credits(journal_t *journal, int blocks,
                        wait_event(journal->j_wait_reserved,
                                   atomic_read(&journal->j_reserved_credits) + total <=
                                   journal->j_max_transaction_buffers);
+                       __acquire(&journal->j_state_lock); /* fake out sparse */
                        return 1;
                }
 
                wait_transaction_locked(journal);
+               __acquire(&journal->j_state_lock); /* fake out sparse */
                return 1;
        }
 
@@ -293,6 +302,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
                                        journal->j_max_transaction_buffers)
                        __jbd2_log_wait_for_space(journal);
                write_unlock(&journal->j_state_lock);
+               __acquire(&journal->j_state_lock); /* fake out sparse */
                return 1;
        }
 
@@ -310,6 +320,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
                wait_event(journal->j_wait_reserved,
                         atomic_read(&journal->j_reserved_credits) + rsv_blocks
                         <= journal->j_max_transaction_buffers / 2);
+               __acquire(&journal->j_state_lock); /* fake out sparse */
                return 1;
        }
        return 0;
@@ -413,8 +424,14 @@ repeat:
 
        if (!handle->h_reserved) {
                /* We may have dropped j_state_lock - restart in that case */
-               if (add_transaction_credits(journal, blocks, rsv_blocks))
+               if (add_transaction_credits(journal, blocks, rsv_blocks)) {
+                       /*
+                        * add_transaction_credits releases
+                        * j_state_lock on a non-zero return
+                        */
+                       __release(&journal->j_state_lock);
                        goto repeat;
+               }
        } else {
                /*
                 * We have handle reserved so we are allowed to join T_LOCKED