Skip to content

Commit 2b3e79f

Browse files
author
Kent Overstreet
committed
bcachefs: Don't use bch2_btree_node_lock_write_nofail() in btree split path
It turns out - btree splits happen with the rest of the transaction still locked, to avoid unnecessary restarts, which means using nofail doesn't work here - we can deadlock. Fortunately, we now have the ability to return errors here. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 1189bdd commit 2b3e79f

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

fs/bcachefs/btree_update_interior.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,23 +1280,29 @@ static void bch2_btree_set_root_inmem(struct bch_fs *c, struct btree *b)
12801280
bch2_recalc_btree_reserve(c);
12811281
}
12821282

1283-
static void bch2_btree_set_root(struct btree_update *as,
1284-
struct btree_trans *trans,
1285-
struct btree_path *path,
1286-
struct btree *b)
1283+
static int bch2_btree_set_root(struct btree_update *as,
1284+
struct btree_trans *trans,
1285+
struct btree_path *path,
1286+
struct btree *b,
1287+
bool nofail)
12871288
{
12881289
struct bch_fs *c = as->c;
1289-
struct btree *old;
12901290

12911291
trace_and_count(c, btree_node_set_root, trans, b);
12921292

1293-
old = btree_node_root(c, b);
1293+
struct btree *old = btree_node_root(c, b);
12941294

12951295
/*
12961296
* Ensure no one is using the old root while we switch to the
12971297
* new root:
12981298
*/
1299-
bch2_btree_node_lock_write_nofail(trans, path, &old->c);
1299+
if (nofail) {
1300+
bch2_btree_node_lock_write_nofail(trans, path, &old->c);
1301+
} else {
1302+
int ret = bch2_btree_node_lock_write(trans, path, &old->c);
1303+
if (ret)
1304+
return ret;
1305+
}
13001306

13011307
bch2_btree_set_root_inmem(c, b);
13021308

@@ -1310,6 +1316,7 @@ static void bch2_btree_set_root(struct btree_update *as,
13101316
* depend on the new root would have to update the new root.
13111317
*/
13121318
bch2_btree_node_unlock_write(trans, path, old);
1319+
return 0;
13131320
}
13141321

13151322
/* Interior node updates: */
@@ -1652,15 +1659,16 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
16521659
if (parent) {
16531660
/* Split a non root node */
16541661
ret = bch2_btree_insert_node(as, trans, path, parent, &as->parent_keys);
1655-
if (ret)
1656-
goto err;
16571662
} else if (n3) {
1658-
bch2_btree_set_root(as, trans, trans->paths + path, n3);
1663+
ret = bch2_btree_set_root(as, trans, trans->paths + path, n3, false);
16591664
} else {
16601665
/* Root filled up but didn't need to be split */
1661-
bch2_btree_set_root(as, trans, trans->paths + path, n1);
1666+
ret = bch2_btree_set_root(as, trans, trans->paths + path, n1, false);
16621667
}
16631668

1669+
if (ret)
1670+
goto err;
1671+
16641672
if (n3) {
16651673
bch2_btree_update_get_open_buckets(as, n3);
16661674
bch2_btree_node_write(c, n3, SIX_LOCK_intent, 0);
@@ -1863,7 +1871,9 @@ static void __btree_increase_depth(struct btree_update *as, struct btree_trans *
18631871
bch2_keylist_add(&as->parent_keys, &b->key);
18641872
btree_split_insert_keys(as, trans, path_idx, n, &as->parent_keys);
18651873

1866-
bch2_btree_set_root(as, trans, path, n);
1874+
int ret = bch2_btree_set_root(as, trans, path, n, true);
1875+
BUG_ON(ret);
1876+
18671877
bch2_btree_update_get_open_buckets(as, n);
18681878
bch2_btree_node_write(c, n, SIX_LOCK_intent, 0);
18691879
bch2_trans_node_add(trans, path, n);
@@ -2106,12 +2116,13 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
21062116
if (parent) {
21072117
bch2_keylist_add(&as->parent_keys, &n->key);
21082118
ret = bch2_btree_insert_node(as, trans, iter->path, parent, &as->parent_keys);
2109-
if (ret)
2110-
goto err;
21112119
} else {
2112-
bch2_btree_set_root(as, trans, btree_iter_path(trans, iter), n);
2120+
ret = bch2_btree_set_root(as, trans, btree_iter_path(trans, iter), n, false);
21132121
}
21142122

2123+
if (ret)
2124+
goto err;
2125+
21152126
bch2_btree_update_get_open_buckets(as, n);
21162127
bch2_btree_node_write(c, n, SIX_LOCK_intent, 0);
21172128

0 commit comments

Comments
 (0)