1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

bcachefs: __lookup_dirent() works in snapshot, not subvol

Add a new helper, bch2_hash_lookup_in_snapshot(), for when we're not
operating in a subvolume and already have a snapshot ID, and then use it
in lookup_lostfound() -> __lookup_dirent().

This is a bugfix - lookup_lostfound() doesn't take a subvolume ID, we
were passing a nonsense subvolume ID before, and don't have one to pass
since we may be operating in an interior snapshot node that doesn't have
a subvolume ID.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2024-01-24 17:26:33 -05:00
parent 096386a5bc
commit d2fda304bb
2 changed files with 27 additions and 18 deletions

View file

@ -119,22 +119,19 @@ static int lookup_inode(struct btree_trans *trans, u64 inode_nr,
if (!ret) if (!ret)
*snapshot = iter.pos.snapshot; *snapshot = iter.pos.snapshot;
err: err:
bch_err_msg(trans->c, ret, "fetching inode %llu:%u", inode_nr, *snapshot);
bch2_trans_iter_exit(trans, &iter); bch2_trans_iter_exit(trans, &iter);
return ret; return ret;
} }
static int __lookup_dirent(struct btree_trans *trans, static int lookup_dirent_in_snapshot(struct btree_trans *trans,
struct bch_hash_info hash_info, struct bch_hash_info hash_info,
subvol_inum dir, struct qstr *name, subvol_inum dir, struct qstr *name,
u64 *target, unsigned *type) u64 *target, unsigned *type, u32 snapshot)
{ {
struct btree_iter iter; struct btree_iter iter;
struct bkey_s_c_dirent d; struct bkey_s_c_dirent d;
int ret; int ret = bch2_hash_lookup_in_snapshot(trans, &iter, bch2_dirent_hash_desc,
&hash_info, dir, name, 0, snapshot);
ret = bch2_hash_lookup(trans, &iter, bch2_dirent_hash_desc,
&hash_info, dir, name, 0);
if (ret) if (ret)
return ret; return ret;
@ -225,15 +222,16 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
struct bch_inode_unpacked root_inode; struct bch_inode_unpacked root_inode;
struct bch_hash_info root_hash_info; struct bch_hash_info root_hash_info;
ret = lookup_inode(trans, root_inum.inum, &root_inode, &snapshot); u32 root_inode_snapshot = snapshot;
ret = lookup_inode(trans, root_inum.inum, &root_inode, &root_inode_snapshot);
bch_err_msg(c, ret, "looking up root inode"); bch_err_msg(c, ret, "looking up root inode");
if (ret) if (ret)
return ret; return ret;
root_hash_info = bch2_hash_info_init(c, &root_inode); root_hash_info = bch2_hash_info_init(c, &root_inode);
ret = __lookup_dirent(trans, root_hash_info, root_inum, ret = lookup_dirent_in_snapshot(trans, root_hash_info, root_inum,
&lostfound_str, &inum, &d_type); &lostfound_str, &inum, &d_type, snapshot);
if (bch2_err_matches(ret, ENOENT)) if (bch2_err_matches(ret, ENOENT))
goto create_lostfound; goto create_lostfound;
@ -250,7 +248,10 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
* The bch2_check_dirents pass has already run, dangling dirents * The bch2_check_dirents pass has already run, dangling dirents
* shouldn't exist here: * shouldn't exist here:
*/ */
return lookup_inode(trans, inum, lostfound, &snapshot); ret = lookup_inode(trans, inum, lostfound, &snapshot);
bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)",
inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot));
return ret;
create_lostfound: create_lostfound:
/* /*

View file

@ -160,21 +160,16 @@ static inline bool is_visible_key(struct bch_hash_desc desc, subvol_inum inum, s
} }
static __always_inline int static __always_inline int
bch2_hash_lookup(struct btree_trans *trans, bch2_hash_lookup_in_snapshot(struct btree_trans *trans,
struct btree_iter *iter, struct btree_iter *iter,
const struct bch_hash_desc desc, const struct bch_hash_desc desc,
const struct bch_hash_info *info, const struct bch_hash_info *info,
subvol_inum inum, const void *key, subvol_inum inum, const void *key,
unsigned flags) unsigned flags, u32 snapshot)
{ {
struct bkey_s_c k; struct bkey_s_c k;
u32 snapshot;
int ret; int ret;
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
if (ret)
return ret;
for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id, for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id,
SPOS(inum.inum, desc.hash_key(info, key), snapshot), SPOS(inum.inum, desc.hash_key(info, key), snapshot),
POS(inum.inum, U64_MAX), POS(inum.inum, U64_MAX),
@ -194,6 +189,19 @@ bch2_hash_lookup(struct btree_trans *trans,
return ret ?: -BCH_ERR_ENOENT_str_hash_lookup; return ret ?: -BCH_ERR_ENOENT_str_hash_lookup;
} }
static __always_inline int
bch2_hash_lookup(struct btree_trans *trans,
struct btree_iter *iter,
const struct bch_hash_desc desc,
const struct bch_hash_info *info,
subvol_inum inum, const void *key,
unsigned flags)
{
u32 snapshot;
return bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot) ?:
bch2_hash_lookup_in_snapshot(trans, iter, desc, info, inum, key, flags, snapshot);
}
static __always_inline int static __always_inline int
bch2_hash_hole(struct btree_trans *trans, bch2_hash_hole(struct btree_trans *trans,
struct btree_iter *iter, struct btree_iter *iter,