summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-09-30 19:46:23 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-03-13 11:34:06 -0400
commitf5b245286086048d48c88681402bc0eb6e55cd7e (patch)
treefd2c30a8471d1d548488b7bdbba84c022204c3a8
parent42986e3d837bac171769f460a595889c979d351e (diff)
bcachefs: bch2_subvolume_get()
Factor out a little helper. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/dirent.c27
-rw-r--r--fs/bcachefs/fs-common.c22
-rw-r--r--fs/bcachefs/fsck.c23
-rw-r--r--fs/bcachefs/subvolume.c59
-rw-r--r--fs/bcachefs/subvolume.h2
5 files changed, 41 insertions, 92 deletions
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c
index 8653a106809d..c7344ac87fcd 100644
--- a/fs/bcachefs/dirent.c
+++ b/fs/bcachefs/dirent.c
@@ -191,34 +191,15 @@ int __bch2_dirent_read_target(struct btree_trans *trans,
if (likely(d.v->d_type != DT_SUBVOL)) {
*inum = le64_to_cpu(d.v->d_inum);
} else {
- struct btree_iter iter;
- struct bkey_s_c k;
- struct bkey_s_c_subvolume s;
+ struct bch_subvolume s;
int ret;
*subvol = le64_to_cpu(d.v->d_inum);
- bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
- POS(0, *subvol),
- BTREE_ITER_CACHED);
- k = bch2_btree_iter_peek_slot(&iter);
- ret = bkey_err(k);
- if (ret)
- goto err;
-
- if (k.k->type != KEY_TYPE_subvolume) {
- ret = -ENOENT;
- goto err;
- }
- s = bkey_s_c_to_subvolume(k);
- *snapshot = le32_to_cpu(s.v->snapshot);
- *inum = le64_to_cpu(s.v->inode);
-err:
- if (ret == -ENOENT && !is_fsck)
- bch2_fs_inconsistent(trans->c, "pointer to missing subvolume %u",
- *subvol);
+ ret = bch2_subvolume_get(trans, *subvol, !is_fsck, BTREE_ITER_CACHED, &s);
- bch2_trans_iter_exit(trans, &iter);
+ *snapshot = le32_to_cpu(s.snapshot);
+ *inum = le64_to_cpu(s.inode);
}
return ret;
diff --git a/fs/bcachefs/fs-common.c b/fs/bcachefs/fs-common.c
index 3e8e3c5bf870..00c7ba17f6c8 100644
--- a/fs/bcachefs/fs-common.c
+++ b/fs/bcachefs/fs-common.c
@@ -67,26 +67,14 @@ int bch2_create_trans(struct btree_trans *trans,
if (!snapshot_src.inum) {
/* Inode wasn't specified, just snapshot: */
- struct btree_iter subvol_iter;
- struct bkey_s_c k;
-
- bch2_trans_iter_init(trans, &subvol_iter, BTREE_ID_subvolumes,
- POS(0, snapshot_src.subvol), 0);
- k = bch2_btree_iter_peek_slot(&subvol_iter);
-
- ret = bkey_err(k);
- if (!ret && k.k->type != KEY_TYPE_subvolume) {
- bch_err(c, "subvolume %u not found",
- snapshot_src.subvol);
- ret = -ENOENT;
- }
-
- if (!ret)
- snapshot_src.inum = le64_to_cpu(bkey_s_c_to_subvolume(k).v->inode);
- bch2_trans_iter_exit(trans, &subvol_iter);
+ struct bch_subvolume s;
+ ret = bch2_subvolume_get(trans, snapshot_src.subvol, true,
+ BTREE_ITER_CACHED, &s);
if (ret)
goto err;
+
+ snapshot_src.inum = le64_to_cpu(s.inode);
}
ret = bch2_inode_peek(trans, &inode_iter, new_inode, snapshot_src,
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index 3622fb4d18e2..208bf6df82b5 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -103,29 +103,14 @@ static int snapshot_lookup_subvol(struct btree_trans *trans, u32 snapshot,
static int __subvol_lookup(struct btree_trans *trans, u32 subvol,
u32 *snapshot, u64 *inum)
{
- struct btree_iter iter;
- struct bkey_s_c k;
+ struct bch_subvolume s;
int ret;
- bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
- POS(0, subvol), 0);
- k = bch2_btree_iter_peek_slot(&iter);
- ret = bkey_err(k);
- if (ret)
- goto err;
+ ret = bch2_subvolume_get(trans, subvol, false, 0, &s);
- if (k.k->type != KEY_TYPE_subvolume) {
- bch_err(trans->c, "subvolume %u not fonud", subvol);
- ret = -ENOENT;
- goto err;
- }
-
- *snapshot = le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot);
- *inum = le64_to_cpu(bkey_s_c_to_subvolume(k).v->inode);
-err:
- bch2_trans_iter_exit(trans, &iter);
+ *snapshot = le32_to_cpu(s.snapshot);
+ *inum = le64_to_cpu(s.inode);
return ret;
-
}
static int subvol_lookup(struct btree_trans *trans, u32 subvol,
diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c
index ff3b4d2d86b9..d1c111050c35 100644
--- a/fs/bcachefs/subvolume.c
+++ b/fs/bcachefs/subvolume.c
@@ -89,23 +89,6 @@ int bch2_mark_snapshot(struct bch_fs *c,
return 0;
}
-static int subvol_lookup(struct btree_trans *trans, unsigned id, struct bch_subvolume *s)
-{
- struct btree_iter iter;
- struct bkey_s_c k;
- int ret;
-
- bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes, POS(0, id), 0);
- k = bch2_btree_iter_peek_slot(&iter);
- ret = bkey_err(k) ?: k.k->type == KEY_TYPE_subvolume ? 0 : -ENOENT;
-
- if (!ret)
- *s = *bkey_s_c_to_subvolume(k).v;
-
- bch2_trans_iter_exit(trans, &iter);
- return ret;
-}
-
static int snapshot_lookup(struct btree_trans *trans, u32 id,
struct bch_snapshot *s)
{
@@ -195,7 +178,7 @@ static int bch2_snapshot_check(struct btree_trans *trans,
int ret;
id = le32_to_cpu(s.v->subvol);
- ret = lockrestart_do(trans, subvol_lookup(trans, id, &subvol));
+ ret = lockrestart_do(trans, bch2_subvolume_get(trans, id, 0, false, &subvol));
if (ret == -ENOENT)
bch_err(trans->c, "snapshot node %llu has nonexistent subvolume %u",
s.k->p.offset, id);
@@ -798,34 +781,44 @@ void bch2_subvolume_to_text(struct printbuf *out, struct bch_fs *c,
le32_to_cpu(s.v->snapshot));
}
-int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvol,
- u32 *snapid)
+int bch2_subvolume_get(struct btree_trans *trans, unsigned subvol,
+ bool inconsistent_if_not_found,
+ int iter_flags,
+ struct bch_subvolume *s)
{
struct btree_iter iter;
struct bkey_s_c k;
int ret;
- bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
- POS(0, subvol),
- BTREE_ITER_CACHED|
- BTREE_ITER_WITH_UPDATES);
+ bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes, POS(0, subvol),
+ iter_flags);
k = bch2_btree_iter_peek_slot(&iter);
- ret = bkey_err(k);
- if (ret)
- goto err;
+ ret = bkey_err(k) ?: k.k->type == KEY_TYPE_subvolume ? 0 : -ENOENT;
- if (k.k->type != KEY_TYPE_subvolume) {
+ if (ret == -ENOENT && inconsistent_if_not_found)
bch2_fs_inconsistent(trans->c, "missing subvolume %u", subvol);
- ret = -EIO;
- goto err;
- }
+ if (!ret)
+ *s = *bkey_s_c_to_subvolume(k).v;
- *snapid = le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot);
-err:
bch2_trans_iter_exit(trans, &iter);
return ret;
}
+int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvol,
+ u32 *snapid)
+{
+ struct bch_subvolume s;
+ int ret;
+
+ ret = bch2_subvolume_get(trans, subvol, true,
+ BTREE_ITER_CACHED|
+ BTREE_ITER_WITH_UPDATES,
+ &s);
+
+ *snapid = le32_to_cpu(s.snapshot);
+ return ret;
+}
+
/* XXX: mark snapshot id for deletion, walk btree and delete: */
int bch2_subvolume_delete(struct btree_trans *trans, u32 subvolid,
int deleting_snapshot)
diff --git a/fs/bcachefs/subvolume.h b/fs/bcachefs/subvolume.h
index 0740c7b7f772..ed02b982ff96 100644
--- a/fs/bcachefs/subvolume.h
+++ b/fs/bcachefs/subvolume.h
@@ -104,6 +104,8 @@ void bch2_subvolume_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c)
.val_to_text = bch2_subvolume_to_text, \
}
+int bch2_subvolume_get(struct btree_trans *, unsigned,
+ bool, int, struct bch_subvolume *);
int bch2_subvolume_get_snapshot(struct btree_trans *, u32, u32 *);
int bch2_subvolume_delete(struct btree_trans *, u32, int);