summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-03-06 21:17:43 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2022-10-03 22:52:14 -0400
commit4f745f703eb2941232b4cad573ac6ca57d7ededc (patch)
treee1758884e9c4748a3c3bc06e00c3e3cf37f4663a
parent6db5d1a487168ca6964432c67fdd9f9c21c6528f (diff)
bcachefs: Fix lock ordering under traverse_all()
traverse_all() traverses btree paths in sorted order, so it should never see transaction restarts due to lock ordering violations. But some code in __bch2_btree_path_upgrade(), while necessary when not running under traverse_all(), was causing some confusing lock ordering violations - disabling this code under traverse_all() will let us put in some more assertions. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/btree_iter.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 1f02422669eb..f13b2738480a 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -486,14 +486,15 @@ bool __bch2_btree_path_upgrade(struct btree_trans *trans,
* before interior nodes - now that's handled by
* bch2_btree_path_traverse_all().
*/
- trans_for_each_path(trans, linked)
- if (linked != path &&
- linked->cached == path->cached &&
- linked->btree_id == path->btree_id &&
- linked->locks_want < new_locks_want) {
- linked->locks_want = new_locks_want;
- btree_path_get_locks(trans, linked, true);
- }
+ if (!path->cached && !trans->in_traverse_all)
+ trans_for_each_path(trans, linked)
+ if (linked != path &&
+ linked->cached == path->cached &&
+ linked->btree_id == path->btree_id &&
+ linked->locks_want < new_locks_want) {
+ linked->locks_want = new_locks_want;
+ btree_path_get_locks(trans, linked, true);
+ }
return false;
}