@@ -1351,7 +1351,7 @@ int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
13511351 * that key to snapshot leaf nodes, where we can mutate it
13521352 */
13531353
1354- static int snapshot_delete_key (struct btree_trans * trans ,
1354+ static int delete_dead_snapshots_process_key (struct btree_trans * trans ,
13551355 struct btree_iter * iter ,
13561356 struct bkey_s_c k ,
13571357 snapshot_id_list * deleted ,
@@ -1360,26 +1360,26 @@ static int snapshot_delete_key(struct btree_trans *trans,
13601360{
13611361 struct bch_fs * c = trans -> c ;
13621362 u32 equiv = bch2_snapshot_equiv (c , k .k -> p .snapshot );
1363+ if (!equiv ) /* key for invalid snapshot node, but we chose not to delete */
1364+ return 0 ;
13631365
13641366 if (!bkey_eq (k .k -> p , * last_pos ))
13651367 equiv_seen -> nr = 0 ;
1366- * last_pos = k .k -> p ;
13671368
1368- if (snapshot_list_has_id (deleted , k .k -> p .snapshot ) ||
1369- snapshot_list_has_id (equiv_seen , equiv )) {
1369+ if (snapshot_list_has_id (deleted , k .k -> p .snapshot ))
13701370 return bch2_btree_delete_at (trans , iter ,
13711371 BTREE_UPDATE_internal_snapshot_node );
1372- } else {
1373- return snapshot_list_add (c , equiv_seen , equiv );
1374- }
1375- }
13761372
1377- static int move_key_to_correct_snapshot (struct btree_trans * trans ,
1378- struct btree_iter * iter ,
1379- struct bkey_s_c k )
1380- {
1381- struct bch_fs * c = trans -> c ;
1382- u32 equiv = bch2_snapshot_equiv (c , k .k -> p .snapshot );
1373+ if (!bpos_eq (* last_pos , k .k -> p ) &&
1374+ snapshot_list_has_id (equiv_seen , equiv ))
1375+ return bch2_btree_delete_at (trans , iter ,
1376+ BTREE_UPDATE_internal_snapshot_node );
1377+
1378+ * last_pos = k .k -> p ;
1379+
1380+ int ret = snapshot_list_add_nodup (c , equiv_seen , equiv );
1381+ if (ret )
1382+ return ret ;
13831383
13841384 /*
13851385 * When we have a linear chain of snapshot nodes, we consider
@@ -1389,21 +1389,20 @@ static int move_key_to_correct_snapshot(struct btree_trans *trans,
13891389 *
13901390 * If there are multiple keys in different snapshots at the same
13911391 * position, we're only going to keep the one in the newest
1392- * snapshot - the rest have been overwritten and are redundant,
1393- * and for the key we're going to keep we need to move it to the
1394- * equivalance class ID if it's not there already.
1392+ * snapshot (we delete the others above) - the rest have been
1393+ * overwritten and are redundant, and for the key we're going to keep we
1394+ * need to move it to the equivalance class ID if it's not there
1395+ * already.
13951396 */
13961397 if (equiv != k .k -> p .snapshot ) {
13971398 struct bkey_i * new = bch2_bkey_make_mut_noupdate (trans , k );
1398- struct btree_iter new_iter ;
1399- int ret ;
1400-
1401- ret = PTR_ERR_OR_ZERO (new );
1399+ int ret = PTR_ERR_OR_ZERO (new );
14021400 if (ret )
14031401 return ret ;
14041402
14051403 new -> k .p .snapshot = equiv ;
14061404
1405+ struct btree_iter new_iter ;
14071406 bch2_trans_iter_init (trans , & new_iter , iter -> btree_id , new -> k .p ,
14081407 BTREE_ITER_all_snapshots |
14091408 BTREE_ITER_cached |
@@ -1538,7 +1537,6 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
15381537 struct btree_trans * trans ;
15391538 snapshot_id_list deleted = { 0 };
15401539 snapshot_id_list deleted_interior = { 0 };
1541- u32 id ;
15421540 int ret = 0 ;
15431541
15441542 if (!test_and_clear_bit (BCH_FS_need_delete_dead_snapshots , & c -> flags ))
@@ -1585,33 +1583,20 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
15851583 if (ret )
15861584 goto err ;
15871585
1588- for (id = 0 ; id < BTREE_ID_NR ; id ++ ) {
1586+ for (unsigned btree = 0 ; btree < BTREE_ID_NR ; btree ++ ) {
15891587 struct bpos last_pos = POS_MIN ;
15901588 snapshot_id_list equiv_seen = { 0 };
15911589 struct disk_reservation res = { 0 };
15921590
1593- if (!btree_type_has_snapshots (id ))
1594- continue ;
1595-
1596- /*
1597- * deleted inodes btree is maintained by a trigger on the inodes
1598- * btree - no work for us to do here, and it's not safe to scan
1599- * it because we'll see out of date keys due to the btree write
1600- * buffer:
1601- */
1602- if (id == BTREE_ID_deleted_inodes )
1591+ if (!btree_type_has_snapshots (btree ))
16031592 continue ;
16041593
16051594 ret = for_each_btree_key_commit (trans , iter ,
1606- id , POS_MIN ,
1607- BTREE_ITER_prefetch |BTREE_ITER_all_snapshots , k ,
1608- & res , NULL , BCH_TRANS_COMMIT_no_enospc ,
1609- snapshot_delete_key (trans , & iter , k , & deleted , & equiv_seen , & last_pos )) ?:
1610- for_each_btree_key_commit (trans , iter ,
1611- id , POS_MIN ,
1595+ btree , POS_MIN ,
16121596 BTREE_ITER_prefetch |BTREE_ITER_all_snapshots , k ,
16131597 & res , NULL , BCH_TRANS_COMMIT_no_enospc ,
1614- move_key_to_correct_snapshot (trans , & iter , k ));
1598+ delete_dead_snapshots_process_key (trans , & iter , k , & deleted ,
1599+ & equiv_seen , & last_pos ));
16151600
16161601 bch2_disk_reservation_put (c , & res );
16171602 darray_exit (& equiv_seen );
0 commit comments