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; - } + ret = bch2_subvolume_get(trans, *subvol, !is_fsck, BTREE_ITER_CACHED, &s); - 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); - - 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);