Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

jbd2: track more dependencies on transaction commit

So far we were tracking only dependency on transaction commit due to
starting a new handle (which may require commit to start a new
transaction). Now add tracking also for other cases where we wait for
transaction commit. This way lockdep can catch deadlocks e. g. because we
call jbd2_journal_stop() for a synchronous handle with some locks held
which rank below transaction start.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Jan Kara and committed by
Theodore Ts'o
1eaa566d ab714aff

+11
+1
fs/jbd2/journal.c
··· 691 691 { 692 692 int err = 0; 693 693 694 + jbd2_might_wait_for_commit(journal); 694 695 read_lock(&journal->j_state_lock); 695 696 #ifdef CONFIG_JBD2_DEBUG 696 697 if (!tid_geq(journal->j_commit_request, tid)) {
+4
fs/jbd2/transaction.c
··· 182 182 int needed; 183 183 int total = blocks + rsv_blocks; 184 184 185 + jbd2_might_wait_for_commit(journal); 186 + 185 187 /* 186 188 * If the current transaction is locked down for commit, wait 187 189 * for the lock to be released. ··· 696 694 void jbd2_journal_lock_updates(journal_t *journal) 697 695 { 698 696 DEFINE_WAIT(wait); 697 + 698 + jbd2_might_wait_for_commit(journal); 699 699 700 700 write_lock(&journal->j_state_lock); 701 701 ++journal->j_barrier_count;
+6
include/linux/jbd2.h
··· 1046 1046 #endif 1047 1047 }; 1048 1048 1049 + #define jbd2_might_wait_for_commit(j) \ 1050 + do { \ 1051 + rwsem_acquire(&j->j_trans_commit_map, 0, 0, _THIS_IP_); \ 1052 + rwsem_release(&j->j_trans_commit_map, 1, _THIS_IP_); \ 1053 + } while (0) 1054 + 1049 1055 /* journal feature predicate functions */ 1050 1056 #define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \ 1051 1057 static inline bool jbd2_has_feature_##name(journal_t *j) \