@@ -1399,35 +1399,44 @@ static bool bch2_btree_path_can_relock(struct btree_trans *trans, struct btree_p
1399
1399
1400
1400
void bch2_path_put (struct btree_trans * trans , btree_path_idx_t path_idx , bool intent )
1401
1401
{
1402
- struct btree_path * path = trans -> paths + path_idx , * dup ;
1402
+ struct btree_path * path = trans -> paths + path_idx , * dup = NULL ;
1403
1403
1404
1404
if (!__btree_path_put (trans , path , intent ))
1405
1405
return ;
1406
1406
1407
+ if (!path -> preserve && !path -> should_be_locked )
1408
+ goto free ;
1409
+
1407
1410
dup = path -> preserve
1408
1411
? have_path_at_pos (trans , path )
1409
1412
: have_node_at_pos (trans , path );
1410
-
1411
- trace_btree_path_free (trans , path_idx , dup );
1412
-
1413
- if (!dup && !(!path -> preserve && !is_btree_node (path , path -> level )))
1413
+ if (!dup )
1414
1414
return ;
1415
1415
1416
- if (path -> should_be_locked && !trans -> restarted ) {
1417
- if (!dup )
1418
- return ;
1419
-
1416
+ /*
1417
+ * If we need this path locked, the duplicate also has te be locked
1418
+ * before we free this one:
1419
+ */
1420
+ if (path -> should_be_locked &&
1421
+ !dup -> should_be_locked &&
1422
+ !trans -> restarted ) {
1420
1423
if (!(trans -> locked
1421
1424
? bch2_btree_path_relock_norestart (trans , dup )
1422
1425
: bch2_btree_path_can_relock (trans , dup )))
1423
1426
return ;
1424
- }
1425
1427
1426
- if (dup ) {
1427
- dup -> preserve |= path -> preserve ;
1428
- dup -> should_be_locked |= path -> should_be_locked ;
1428
+ dup -> should_be_locked = true;
1429
1429
}
1430
1430
1431
+ BUG_ON (path -> should_be_locked &&
1432
+ !trans -> restarted &&
1433
+ trans -> locked &&
1434
+ !btree_node_locked (dup , dup -> level ));
1435
+
1436
+ path -> should_be_locked = false;
1437
+ dup -> preserve |= path -> preserve ;
1438
+ free :
1439
+ trace_btree_path_free (trans , path_idx , dup );
1431
1440
__bch2_path_free (trans , path_idx );
1432
1441
}
1433
1442
0 commit comments