diff options
-rw-r--r-- | fs/bcachefs/btree_iter.c | 31 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.h | 4 | ||||
-rw-r--r-- | fs/bcachefs/btree_types.h | 3 |
3 files changed, 31 insertions, 7 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 8f7d37697281..eb1f6f867212 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -1175,10 +1175,17 @@ int bch2_btree_path_traverse_one(struct btree_trans *trans, path->uptodate = BTREE_ITER_UPTODATE; out: - if (bch2_err_matches(ret, BCH_ERR_transaction_restart) != !!trans->restarted) - panic("ret %s (%i) trans->restarted %s (%i)\n", - bch2_err_str(ret), ret, - bch2_err_str(trans->restarted), trans->restarted); + if (bch2_err_matches(ret, BCH_ERR_transaction_restart) != !!trans->restarted) { + struct printbuf buf = PRINTBUF; + + prt_printf(&buf, "ret %s (%i) trans->restarted %s (%i)\n", + bch2_err_str(ret), ret, + bch2_err_str(trans->restarted), trans->restarted); +#ifdef CONFIG_BCACHEFS_DEBUG + bch2_prt_backtrace(&buf, &trans->last_restarted); +#endif + panic("%s", buf.buf); + } bch2_btree_path_verify(trans, path); return ret; } @@ -1366,9 +1373,15 @@ void bch2_trans_restart_error(struct btree_trans *trans, u32 restart_count) void bch2_trans_in_restart_error(struct btree_trans *trans) { - panic("in transaction restart: %s, last restarted by %pS\n", - bch2_err_str(trans->restarted), - (void *) trans->last_restarted_ip); + struct printbuf buf = PRINTBUF; + + prt_printf(&buf, "in transaction restart: %s, last restarted by %pS\n", + bch2_err_str(trans->restarted), + (void *) trans->last_restarted_ip); +#ifdef CONFIG_BCACHEFS_DEBUG + bch2_prt_backtrace(&buf, &trans->last_restarted); +#endif + panic("%s", buf.buf); } noinline __cold @@ -3079,6 +3092,10 @@ void bch2_trans_exit(struct btree_trans *trans) if (trans->paths) mempool_free(trans->paths, &c->btree_paths_pool); +#ifdef CONFIG_BCACHEFS_DEBUG + darray_exit(&trans->last_restarted); +#endif + trans->mem = (void *) 0x1; trans->paths = (void *) 0x1; } diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 6b7cef145ced..4db24c9baa26 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -260,6 +260,10 @@ static inline int btree_trans_restart_nounlock(struct btree_trans *trans, int er BUG_ON(err <= 0); BUG_ON(!bch2_err_matches(err, BCH_ERR_transaction_restart)); +#ifdef CONFIG_BCACHEFS_DEBUG + bch2_save_backtrace(&trans->last_restarted, current); +#endif + trans->restarted = err; trans->last_restarted_ip = _THIS_IP_; return -err; diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 6250f34fe561..f1d94138d457 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -440,6 +440,9 @@ struct btree_trans { u32 restart_count; unsigned long last_begin_ip; unsigned long last_restarted_ip; +#ifdef CONFIG_BCACHEFS_DEBUG + bch_stacktrace last_restarted; +#endif unsigned long srcu_lock_time; /* |