summaryrefslogtreecommitdiff
path: root/fs/bcachefs/subvolume.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-07-17 07:44:19 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:36 +0300
commit6738dd19db5c96e574af79a3b7c1754fb2ecf2bd (patch)
tree301ee11c7264c0c4ef55b5a7238f1d0a17acbc7e /fs/bcachefs/subvolume.c
parent8933315689bcb57a3b282bad262ac584e095a2f5 (diff)
downloadlinux-6738dd19db5c96e574af79a3b7c1754fb2ecf2bd.tar.xz
bcachefs: Convert subvol code to for_each_btree_key_commit()
The new for_each_btree_key2() macro handles transaction retries, allowing us to avoid nested transactions - which we want to avoid since they're tricky to do completely correctly and upcoming assertions are going to be checking for that. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/subvolume.c')
-rw-r--r--fs/bcachefs/subvolume.c105
1 files changed, 34 insertions, 71 deletions
diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c
index 1a212bac2a04..76be8735c700 100644
--- a/fs/bcachefs/subvolume.c
+++ b/fs/bcachefs/subvolume.c
@@ -291,22 +291,14 @@ int bch2_fs_check_snapshots(struct bch_fs *c)
}
static int check_subvol(struct btree_trans *trans,
- struct btree_iter *iter)
+ struct btree_iter *iter,
+ struct bkey_s_c k)
{
- struct bkey_s_c k;
struct bkey_s_c_subvolume subvol;
struct bch_snapshot snapshot;
unsigned snapid;
int ret;
- k = bch2_btree_iter_peek(iter);
- if (!k.k)
- return 0;
-
- ret = bkey_err(k);
- if (ret)
- return ret;
-
if (k.k->type != KEY_TYPE_subvolume)
return 0;
@@ -336,22 +328,15 @@ int bch2_fs_check_subvols(struct bch_fs *c)
{
struct btree_trans trans;
struct btree_iter iter;
+ struct bkey_s_c k;
int ret;
bch2_trans_init(&trans, c, 0, 0);
- bch2_trans_iter_init(&trans, &iter, BTREE_ID_subvolumes,
- POS_MIN, BTREE_ITER_PREFETCH);
-
- do {
- ret = commit_do(&trans, NULL, NULL,
- BTREE_INSERT_LAZY_RW|
- BTREE_INSERT_NOFAIL,
- check_subvol(&trans, &iter));
- if (ret)
- break;
- } while (bch2_btree_iter_advance(&iter));
- bch2_trans_iter_exit(&trans, &iter);
+ ret = for_each_btree_key_commit(&trans, iter,
+ BTREE_ID_subvolumes, POS_MIN, BTREE_ITER_PREFETCH, k,
+ NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
+ check_subvol(&trans, &iter, k));
bch2_trans_exit(&trans);
@@ -595,59 +580,27 @@ err:
return ret;
}
-static int bch2_snapshot_delete_keys_btree(struct btree_trans *trans,
- snapshot_id_list *deleted,
- enum btree_id btree_id)
+static int snapshot_delete_key(struct btree_trans *trans,
+ struct btree_iter *iter,
+ struct bkey_s_c k,
+ snapshot_id_list *deleted,
+ snapshot_id_list *equiv_seen,
+ struct bpos *last_pos)
{
struct bch_fs *c = trans->c;
- struct btree_iter iter;
- struct bkey_s_c k;
- snapshot_id_list equiv_seen = { 0 };
- struct bpos last_pos = POS_MIN;
- int ret = 0;
+ u32 equiv = snapshot_t(c, k.k->p.snapshot)->equiv;
- /*
- * XXX: We should also delete whiteouts that no longer overwrite
- * anything
- */
-
- bch2_trans_iter_init(trans, &iter, btree_id, POS_MIN,
- BTREE_ITER_INTENT|
- BTREE_ITER_PREFETCH|
- BTREE_ITER_NOT_EXTENTS|
- BTREE_ITER_ALL_SNAPSHOTS);
-
- while ((bch2_trans_begin(trans),
- (k = bch2_btree_iter_peek(&iter)).k) &&
- !(ret = bkey_err(k))) {
- u32 equiv = snapshot_t(c, k.k->p.snapshot)->equiv;
-
- if (bkey_cmp(k.k->p, last_pos))
- equiv_seen.nr = 0;
- last_pos = k.k->p;
-
- if (snapshot_list_has_id(deleted, k.k->p.snapshot) ||
- snapshot_list_has_id(&equiv_seen, equiv)) {
- ret = commit_do(trans, NULL, NULL,
- BTREE_INSERT_NOFAIL,
- bch2_btree_iter_traverse(&iter) ?:
- bch2_btree_delete_at(trans, &iter,
- BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE));
- if (ret)
- break;
- } else {
- ret = snapshot_list_add(c, &equiv_seen, equiv);
- if (ret)
- break;
- }
+ if (bkey_cmp(k.k->p, *last_pos))
+ equiv_seen->nr = 0;
+ *last_pos = k.k->p;
- bch2_btree_iter_advance(&iter);
+ if (snapshot_list_has_id(deleted, k.k->p.snapshot) ||
+ snapshot_list_has_id(equiv_seen, equiv)) {
+ return bch2_btree_delete_at(trans, iter,
+ BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
+ } else {
+ return snapshot_list_add(c, equiv_seen, equiv);
}
- bch2_trans_iter_exit(trans, &iter);
-
- darray_exit(&equiv_seen);
-
- return ret;
}
static int bch2_delete_redundant_snapshot(struct btree_trans *trans, struct btree_iter *iter,
@@ -742,10 +695,20 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
}
for (id = 0; id < BTREE_ID_NR; id++) {
+ struct bpos last_pos = POS_MIN;
+ snapshot_id_list equiv_seen = { 0 };
+
if (!btree_type_has_snapshots(id))
continue;
- ret = bch2_snapshot_delete_keys_btree(&trans, &deleted, id);
+ ret = for_each_btree_key_commit(&trans, iter,
+ id, POS_MIN,
+ BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
+ NULL, NULL, BTREE_INSERT_NOFAIL,
+ snapshot_delete_key(&trans, &iter, k, &deleted, &equiv_seen, &last_pos));
+
+ darray_exit(&equiv_seen);
+
if (ret) {
bch_err(c, "error deleting snapshot keys: %i", ret);
goto err;