summaryrefslogtreecommitdiff
path: root/fs/bcachefs/snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/snapshot.c')
-rw-r--r--fs/bcachefs/snapshot.c214
1 files changed, 74 insertions, 140 deletions
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
index 1b7b21494479..5a1f81749661 100644
--- a/fs/bcachefs/snapshot.c
+++ b/fs/bcachefs/snapshot.c
@@ -431,9 +431,7 @@ static int bch2_snapshot_tree_master_subvol(struct btree_trans *trans,
u32 snapshot_root, u32 *subvol_id)
{
struct bch_fs *c = trans->c;
- struct btree_iter iter;
struct bkey_s_c k;
- bool found = false;
int ret;
for_each_btree_key_norestart(trans, iter, BTREE_ID_subvolumes, POS_MIN,
@@ -446,28 +444,23 @@ static int bch2_snapshot_tree_master_subvol(struct btree_trans *trans,
continue;
if (!BCH_SUBVOLUME_SNAP(s.v)) {
*subvol_id = s.k->p.offset;
- found = true;
- break;
+ return 0;
}
}
- bch2_trans_iter_exit(&iter);
-
- if (!ret && !found) {
- struct bkey_i_subvolume *u;
+ if (ret)
+ return ret;
- *subvol_id = bch2_snapshot_oldest_subvol(c, snapshot_root, NULL);
+ *subvol_id = bch2_snapshot_oldest_subvol(c, snapshot_root, NULL);
- u = bch2_bkey_get_mut_typed(trans, &iter,
- BTREE_ID_subvolumes, POS(0, *subvol_id),
- 0, subvolume);
- ret = PTR_ERR_OR_ZERO(u);
- if (ret)
- return ret;
-
- SET_BCH_SUBVOLUME_SNAP(&u->v, false);
- }
+ struct bkey_i_subvolume *u =
+ bch2_bkey_get_mut_typed(trans, BTREE_ID_subvolumes, POS(0, *subvol_id),
+ 0, subvolume);
+ ret = PTR_ERR_OR_ZERO(u);
+ if (ret)
+ return ret;
- return ret;
+ SET_BCH_SUBVOLUME_SNAP(&u->v, false);
+ return 0;
}
static int check_snapshot_tree(struct btree_trans *trans,
@@ -475,27 +468,21 @@ static int check_snapshot_tree(struct btree_trans *trans,
struct bkey_s_c k)
{
struct bch_fs *c = trans->c;
- struct bkey_s_c_snapshot_tree st;
- struct bch_snapshot s;
- struct bch_subvolume subvol;
CLASS(printbuf, buf)();
- struct btree_iter snapshot_iter = {};
- u32 root_id;
- int ret;
if (k.k->type != KEY_TYPE_snapshot_tree)
return 0;
- st = bkey_s_c_to_snapshot_tree(k);
- root_id = le32_to_cpu(st.v->root_snapshot);
+ struct bkey_s_c_snapshot_tree st = bkey_s_c_to_snapshot_tree(k);
+ u32 root_id = le32_to_cpu(st.v->root_snapshot);
- struct bkey_s_c_snapshot snapshot_k =
- bch2_bkey_get_iter_typed(trans, &snapshot_iter, BTREE_ID_snapshots,
- POS(0, root_id), 0, snapshot);
- ret = bkey_err(snapshot_k);
+ CLASS(btree_iter, snapshot_iter)(trans, BTREE_ID_snapshots, POS(0, root_id), 0);
+ struct bkey_s_c_snapshot snapshot_k = bch2_bkey_get_typed(&snapshot_iter, snapshot);
+ int ret = bkey_err(snapshot_k);
if (ret && !bch2_err_matches(ret, ENOENT))
- goto err;
+ return ret;
+ struct bch_snapshot s;
if (!ret)
bkey_val_copy(&s, snapshot_k);
@@ -509,17 +496,16 @@ static int check_snapshot_tree(struct btree_trans *trans,
ret
? prt_printf(&buf, "(%s)", bch2_err_str(ret))
: bch2_bkey_val_to_text(&buf, c, snapshot_k.s_c),
- buf.buf))) {
- ret = bch2_btree_delete_at(trans, iter, 0);
- goto err;
- }
+ buf.buf)))
+ return bch2_btree_delete_at(trans, iter, 0);
if (!st.v->master_subvol)
- goto out;
+ return 0;
+ struct bch_subvolume subvol;
ret = bch2_subvolume_get(trans, le32_to_cpu(st.v->master_subvol), false, &subvol);
if (ret && !bch2_err_matches(ret, ENOENT))
- goto err;
+ return ret;
if (fsck_err_on(ret,
trans, snapshot_tree_to_missing_subvol,
@@ -544,26 +530,21 @@ static int check_snapshot_tree(struct btree_trans *trans,
ret = bch2_snapshot_tree_master_subvol(trans, root_id, &subvol_id);
bch_err_fn(c, ret);
- if (bch2_err_matches(ret, ENOENT)) { /* nothing to be done here */
- ret = 0;
- goto err;
- }
+ if (bch2_err_matches(ret, ENOENT)) /* nothing to be done here */
+ return 0;
if (ret)
- goto err;
+ return ret;
u = bch2_bkey_make_mut_typed(trans, iter, &k, 0, snapshot_tree);
ret = PTR_ERR_OR_ZERO(u);
if (ret)
- goto err;
+ return ret;
u->v.master_subvol = cpu_to_le32(subvol_id);
st = snapshot_tree_i_to_s_c(u);
}
-out:
-err:
fsck_err:
- bch2_trans_iter_exit(&snapshot_iter);
return ret;
}
@@ -641,22 +622,19 @@ static int snapshot_tree_ptr_repair(struct btree_trans *trans,
struct bch_snapshot *s)
{
struct bch_fs *c = trans->c;
- struct btree_iter root_iter;
- struct bch_snapshot_tree s_t;
- struct bkey_s_c_snapshot root;
struct bkey_i_snapshot *u;
- u32 root_id = bch2_snapshot_root(c, k.k->p.offset), tree_id;
- int ret;
+ u32 root_id = bch2_snapshot_root(c, k.k->p.offset);
- root = bch2_bkey_get_iter_typed(trans, &root_iter,
- BTREE_ID_snapshots, POS(0, root_id),
- BTREE_ITER_with_updates, snapshot);
- ret = bkey_err(root);
+ CLASS(btree_iter, root_iter)(trans, BTREE_ID_snapshots, POS(0, root_id),
+ BTREE_ITER_with_updates);
+ struct bkey_s_c_snapshot root = bch2_bkey_get_typed(&root_iter, snapshot);
+ int ret = bkey_err(root);
if (ret)
- goto err;
+ return ret;
- tree_id = le32_to_cpu(root.v->tree);
+ u32 tree_id = le32_to_cpu(root.v->tree);
+ struct bch_snapshot_tree s_t;
ret = bch2_snapshot_tree_lookup(trans, tree_id, &s_t);
if (ret && !bch2_err_matches(ret, ENOENT))
return ret;
@@ -668,7 +646,7 @@ static int snapshot_tree_ptr_repair(struct btree_trans *trans,
bch2_snapshot_oldest_subvol(c, root_id, NULL),
&tree_id);
if (ret)
- goto err;
+ return ret;
u->v.tree = cpu_to_le32(tree_id);
if (k.k->p.offset == root_id)
@@ -679,14 +657,13 @@ static int snapshot_tree_ptr_repair(struct btree_trans *trans,
u = bch2_bkey_make_mut_typed(trans, iter, &k, 0, snapshot);
ret = PTR_ERR_OR_ZERO(u);
if (ret)
- goto err;
+ return ret;
u->v.tree = cpu_to_le32(tree_id);
*s = u->v;
}
-err:
- bch2_trans_iter_exit(&root_iter);
- return ret;
+
+ return 0;
}
static int check_snapshot(struct btree_trans *trans,
@@ -855,7 +832,6 @@ static int check_snapshot_exists(struct btree_trans *trans, u32 id)
struct bch_fs *c = trans->c;
/* Do we need to reconstruct the snapshot_tree entry as well? */
- struct btree_iter iter;
struct bkey_s_c k;
int ret = 0;
u32 tree_id = 0;
@@ -868,7 +844,6 @@ static int check_snapshot_exists(struct btree_trans *trans, u32 id)
break;
}
}
- bch2_trans_iter_exit(&iter);
if (ret)
return ret;
@@ -898,7 +873,6 @@ static int check_snapshot_exists(struct btree_trans *trans, u32 id)
break;
}
}
- bch2_trans_iter_exit(&iter);
return bch2_snapshot_table_make_room(c, id) ?:
bch2_btree_insert_trans(trans, BTREE_ID_snapshots, &snapshot->k_i, 0);
@@ -1083,7 +1057,6 @@ int __bch2_get_snapshot_overwrites(struct btree_trans *trans,
snapshot_id_list *s)
{
struct bch_fs *c = trans->c;
- struct btree_iter iter;
struct bkey_s_c k;
int ret = 0;
@@ -1100,7 +1073,6 @@ int __bch2_get_snapshot_overwrites(struct btree_trans *trans,
if (ret)
break;
}
- bch2_trans_iter_exit(&iter);
if (ret)
darray_exit(s);
@@ -1112,28 +1084,21 @@ int __bch2_get_snapshot_overwrites(struct btree_trans *trans,
*/
int bch2_snapshot_node_set_deleted(struct btree_trans *trans, u32 id)
{
- struct btree_iter iter;
struct bkey_i_snapshot *s =
- bch2_bkey_get_mut_typed(trans, &iter,
- BTREE_ID_snapshots, POS(0, id),
- 0, snapshot);
+ bch2_bkey_get_mut_typed(trans, BTREE_ID_snapshots, POS(0, id), 0, snapshot);
int ret = PTR_ERR_OR_ZERO(s);
- if (unlikely(ret)) {
- bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT),
- trans->c, "missing snapshot %u", id);
+ bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), trans->c, "missing snapshot %u", id);
+ if (unlikely(ret))
return ret;
- }
/* already deleted? */
if (BCH_SNAPSHOT_WILL_DELETE(&s->v))
- goto err;
+ return 0;
SET_BCH_SNAPSHOT_WILL_DELETE(&s->v, true);
SET_BCH_SNAPSHOT_SUBVOL(&s->v, false);
s->v.subvol = 0;
-err:
- bch2_trans_iter_exit(&iter);
- return ret;
+ return 0;
}
static inline void normalize_snapshot_child_pointers(struct bch_snapshot *s)
@@ -1145,22 +1110,17 @@ static inline void normalize_snapshot_child_pointers(struct bch_snapshot *s)
static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
{
struct bch_fs *c = trans->c;
- struct btree_iter iter, p_iter = {};
- struct btree_iter c_iter = {};
- struct btree_iter tree_iter = {};
u32 parent_id, child_id;
unsigned i;
- int ret = 0;
struct bkey_i_snapshot *s =
- bch2_bkey_get_mut_typed(trans, &iter, BTREE_ID_snapshots, POS(0, id),
- BTREE_ITER_intent, snapshot);
- ret = PTR_ERR_OR_ZERO(s);
+ bch2_bkey_get_mut_typed(trans, BTREE_ID_snapshots, POS(0, id), 0, snapshot);
+ int ret = PTR_ERR_OR_ZERO(s);
bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), c,
"missing snapshot %u", id);
if (ret)
- goto err;
+ return ret;
BUG_ON(BCH_SNAPSHOT_DELETED(&s->v));
BUG_ON(s->v.children[1]);
@@ -1169,16 +1129,14 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
child_id = le32_to_cpu(s->v.children[0]);
if (parent_id) {
- struct bkey_i_snapshot *parent;
-
- parent = bch2_bkey_get_mut_typed(trans, &p_iter,
- BTREE_ID_snapshots, POS(0, parent_id),
- 0, snapshot);
+ struct bkey_i_snapshot *parent =
+ bch2_bkey_get_mut_typed(trans, BTREE_ID_snapshots, POS(0, parent_id),
+ 0, snapshot);
ret = PTR_ERR_OR_ZERO(parent);
bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), c,
"missing snapshot %u", parent_id);
if (unlikely(ret))
- goto err;
+ return ret;
/* find entry in parent->children for node being deleted */
for (i = 0; i < 2; i++)
@@ -1188,7 +1146,7 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
if (bch2_fs_inconsistent_on(i == 2, c,
"snapshot %u missing child pointer to %u",
parent_id, id))
- goto err;
+ return ret;
parent->v.children[i] = cpu_to_le32(child_id);
@@ -1196,16 +1154,14 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
}
if (child_id) {
- struct bkey_i_snapshot *child;
-
- child = bch2_bkey_get_mut_typed(trans, &c_iter,
- BTREE_ID_snapshots, POS(0, child_id),
- 0, snapshot);
+ struct bkey_i_snapshot *child =
+ bch2_bkey_get_mut_typed(trans, BTREE_ID_snapshots, POS(0, child_id),
+ 0, snapshot);
ret = PTR_ERR_OR_ZERO(child);
bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), c,
"missing snapshot %u", child_id);
if (unlikely(ret))
- goto err;
+ return ret;
child->v.parent = cpu_to_le32(parent_id);
@@ -1222,16 +1178,15 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
* snapshot_tree entry to point to the new root, or delete it if
* this is the last snapshot ID in this tree:
*/
- struct bkey_i_snapshot_tree *s_t;
BUG_ON(s->v.children[1]);
- s_t = bch2_bkey_get_mut_typed(trans, &tree_iter,
+ struct bkey_i_snapshot_tree *s_t = bch2_bkey_get_mut_typed(trans,
BTREE_ID_snapshot_trees, POS(0, le32_to_cpu(s->v.tree)),
0, snapshot_tree);
ret = PTR_ERR_OR_ZERO(s_t);
if (ret)
- goto err;
+ return ret;
if (s->v.children[0]) {
s_t->v.root_snapshot = s->v.children[0];
@@ -1256,12 +1211,8 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
s->k.type = KEY_TYPE_deleted;
set_bkey_val_u64s(&s->k, 0);
}
-err:
- bch2_trans_iter_exit(&tree_iter);
- bch2_trans_iter_exit(&p_iter);
- bch2_trans_iter_exit(&c_iter);
- bch2_trans_iter_exit(&iter);
- return ret;
+
+ return 0;
}
static int create_snapids(struct btree_trans *trans, u32 parent, u32 tree,
@@ -1273,8 +1224,7 @@ static int create_snapids(struct btree_trans *trans, u32 parent, u32 tree,
struct bkey_i_snapshot *n;
u32 depth = bch2_snapshot_depth(c, parent);
- CLASS(btree_iter, iter)(trans, BTREE_ID_snapshots,
- POS_MIN, BTREE_ITER_intent);
+ CLASS(btree_iter, iter)(trans, BTREE_ID_snapshots, POS_MIN, BTREE_ITER_intent);
struct bkey_s_c k = bch2_btree_iter_peek(&iter);
int ret = bkey_err(k);
if (ret)
@@ -1328,14 +1278,9 @@ static int bch2_snapshot_node_create_children(struct btree_trans *trans, u32 par
u32 *snapshot_subvols,
unsigned nr_snapids)
{
- struct btree_iter iter;
- struct bkey_i_snapshot *n_parent;
- int ret = 0;
-
- n_parent = bch2_bkey_get_mut_typed(trans, &iter,
- BTREE_ID_snapshots, POS(0, parent),
- 0, snapshot);
- ret = PTR_ERR_OR_ZERO(n_parent);
+ struct bkey_i_snapshot *n_parent =
+ bch2_bkey_get_mut_typed(trans, BTREE_ID_snapshots, POS(0, parent), 0, snapshot);
+ int ret = PTR_ERR_OR_ZERO(n_parent);
if (unlikely(ret)) {
if (bch2_err_matches(ret, ENOENT))
bch_err(trans->c, "snapshot %u not found", parent);
@@ -1344,22 +1289,19 @@ static int bch2_snapshot_node_create_children(struct btree_trans *trans, u32 par
if (n_parent->v.children[0] || n_parent->v.children[1]) {
bch_err(trans->c, "Trying to add child snapshot nodes to parent that already has children");
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
ret = create_snapids(trans, parent, le32_to_cpu(n_parent->v.tree),
new_snapids, snapshot_subvols, nr_snapids);
if (ret)
- goto err;
+ return ret;
n_parent->v.children[0] = cpu_to_le32(new_snapids[0]);
n_parent->v.children[1] = cpu_to_le32(new_snapids[1]);
n_parent->v.subvol = 0;
SET_BCH_SNAPSHOT_SUBVOL(&n_parent->v, false);
-err:
- bch2_trans_iter_exit(&iter);
- return ret;
+ return 0;
}
/*
@@ -1468,23 +1410,19 @@ static int delete_dead_snapshots_process_key(struct btree_trans *trans,
new->k.p.snapshot = live_child;
- struct btree_iter dst_iter;
- struct bkey_s_c dst_k = bch2_bkey_get_iter(trans, &dst_iter,
- iter->btree_id, new->k.p,
- BTREE_ITER_all_snapshots|
- BTREE_ITER_intent);
+ CLASS(btree_iter, dst_iter)(trans, iter->btree_id, new->k.p,
+ BTREE_ITER_all_snapshots|BTREE_ITER_intent);
+ struct bkey_s_c dst_k = bch2_btree_iter_peek_slot(&dst_iter);
ret = bkey_err(dst_k);
if (ret)
return ret;
- ret = (bkey_deleted(dst_k.k)
+ return (bkey_deleted(dst_k.k)
? bch2_trans_update(trans, &dst_iter, new,
BTREE_UPDATE_internal_snapshot_node)
: 0) ?:
bch2_btree_delete_at(trans, iter,
BTREE_UPDATE_internal_snapshot_node);
- bch2_trans_iter_exit(&dst_iter);
- return ret;
}
return 0;
@@ -1931,7 +1869,6 @@ int __bch2_key_has_snapshot_overwrites(struct btree_trans *trans,
struct bpos pos)
{
struct bch_fs *c = trans->c;
- struct btree_iter iter;
struct bkey_s_c k;
int ret;
@@ -1942,12 +1879,9 @@ int __bch2_key_has_snapshot_overwrites(struct btree_trans *trans,
if (!bkey_eq(pos, k.k->p))
break;
- if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, pos.snapshot)) {
- ret = 1;
- break;
- }
+ if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, pos.snapshot))
+ return 1;
}
- bch2_trans_iter_exit(&iter);
return ret;
}