diff options
-rw-r--r-- | fs/bcachefs/fsck.c | 13 | ||||
-rw-r--r-- | fs/bcachefs/str_hash.h | 45 |
2 files changed, 40 insertions, 18 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 9f768d774ba6..12f2ef4417cb 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -772,9 +772,6 @@ static int hash_redo_key(struct btree_trans *trans, struct bch_hash_info *hash_info, struct btree_iter *k_iter, struct bkey_s_c k) { - bch_err(trans->c, "hash_redo_key() not implemented yet"); - return -EINVAL; -#if 0 struct bkey_i *delete; struct bkey_i *tmp; @@ -792,8 +789,14 @@ static int hash_redo_key(struct btree_trans *trans, delete->k.p = k_iter->pos; return bch2_btree_iter_traverse(k_iter) ?: bch2_trans_update(trans, k_iter, delete, 0) ?: - bch2_hash_set(trans, desc, hash_info, k_iter->pos.inode, tmp, 0); -#endif + bch2_hash_set_snapshot(trans, desc, hash_info, + (subvol_inum) { 0, k.k->p.inode }, + k.k->p.snapshot, tmp, + BCH_HASH_SET_MUST_CREATE, + BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?: + bch2_trans_commit(trans, NULL, NULL, + BTREE_INSERT_NOFAIL| + BTREE_INSERT_LAZY_RW); } static int hash_check_key(struct btree_trans *trans, diff --git a/fs/bcachefs/str_hash.h b/fs/bcachefs/str_hash.h index 591bbb9f8beb..560983df13f0 100644 --- a/fs/bcachefs/str_hash.h +++ b/fs/bcachefs/str_hash.h @@ -144,7 +144,9 @@ struct bch_hash_desc { static inline bool is_visible_key(struct bch_hash_desc desc, subvol_inum inum, struct bkey_s_c k) { return k.k->type == desc.key_type && - (!desc.is_visible || desc.is_visible(inum, k)); + (!desc.is_visible || + !inum.inum || + desc.is_visible(inum, k)); } static __always_inline int @@ -239,27 +241,24 @@ int bch2_hash_needs_whiteout(struct btree_trans *trans, } static __always_inline -int bch2_hash_set(struct btree_trans *trans, - const struct bch_hash_desc desc, - const struct bch_hash_info *info, - subvol_inum inum, - struct bkey_i *insert, int flags) +int bch2_hash_set_snapshot(struct btree_trans *trans, + const struct bch_hash_desc desc, + const struct bch_hash_info *info, + subvol_inum inum, u32 snapshot, + struct bkey_i *insert, + int flags, + int update_flags) { struct btree_iter iter, slot = { NULL }; struct bkey_s_c k; bool found = false; - u32 snapshot; 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, - SPOS(inum.inum, + SPOS(insert->k.p.inode, desc.hash_bkey(info, bkey_i_to_s_c(insert)), snapshot), - POS(inum.inum, U64_MAX), + POS(insert->k.p.inode, U64_MAX), BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k, ret) { if (is_visible_key(desc, inum, k)) { if (!desc.cmp_bkey(k, bkey_i_to_s_c(insert))) @@ -304,6 +303,26 @@ not_found: } static __always_inline +int bch2_hash_set(struct btree_trans *trans, + const struct bch_hash_desc desc, + const struct bch_hash_info *info, + subvol_inum inum, + struct bkey_i *insert, int flags) +{ + u32 snapshot; + int ret; + + ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot); + if (ret) + return ret; + + insert->k.p.inode = inum.inum; + + return bch2_hash_set_snapshot(trans, desc, info, inum, + snapshot, insert, flags, 0); +} + +static __always_inline int bch2_hash_delete_at(struct btree_trans *trans, const struct bch_hash_desc desc, const struct bch_hash_info *info, |