summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/btree_iter.c31
-rw-r--r--fs/bcachefs/btree_iter.h4
-rw-r--r--fs/bcachefs/btree_types.h3
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;
/*