From: Kent Overstreet Date: Wed, 28 May 2025 20:25:11 +0000 (-0400) Subject: bcachefs: bch2_str_hash_check_key() may now be called without snapshots_seen X-Git-Tag: v6.16-rc1~48^2~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5922682602788a0f9b37d58e15d7247ad6c54d4;p=thirdparty%2Fkernel%2Flinux.git bcachefs: bch2_str_hash_check_key() may now be called without snapshots_seen We don't track snapshot overwrites outside of fsck, so for this to be called at runtime outside of fsck we need to create it on demand, when we have repair to do. Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 8e07a365b24c2..950fa9685d3e8 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -643,11 +643,6 @@ static int reconstruct_inode(struct btree_trans *trans, enum btree_id btree, u32 return __bch2_fsck_write_inode(trans, &new_inode); } -struct snapshots_seen { - struct bpos pos; - snapshot_id_list ids; -}; - static inline void snapshots_seen_exit(struct snapshots_seen *s) { darray_exit(&s->ids); diff --git a/fs/bcachefs/fsck.h b/fs/bcachefs/fsck.h index 574948278cd4d..e5fe7cf7b2514 100644 --- a/fs/bcachefs/fsck.h +++ b/fs/bcachefs/fsck.h @@ -4,6 +4,12 @@ #include "str_hash.h" +/* recoverds snapshot IDs of overwrites at @pos */ +struct snapshots_seen { + struct bpos pos; + snapshot_id_list ids; +}; + int bch2_fsck_update_backpointers(struct btree_trans *, struct snapshots_seen *, const struct bch_hash_desc, diff --git a/fs/bcachefs/str_hash.c b/fs/bcachefs/str_hash.c index bfd4346a4d931..f101ca8581d99 100644 --- a/fs/bcachefs/str_hash.c +++ b/fs/bcachefs/str_hash.c @@ -231,6 +231,7 @@ int __bch2_str_hash_check_key(struct btree_trans *trans, struct btree_iter iter = {}; struct printbuf buf = PRINTBUF; struct bkey_s_c k; + bool free_snapshots_seen = false; int ret = 0; u64 hash = desc->hash_bkey(hash_info, hash_k); @@ -256,6 +257,8 @@ int __bch2_str_hash_check_key(struct btree_trans *trans, out: bch2_trans_iter_exit(trans, &iter); printbuf_exit(&buf); + if (free_snapshots_seen) + darray_exit(&s->ids); return ret; bad_hash: /* @@ -265,6 +268,22 @@ bad_hash: if (ret) goto out; + if (!s) { + s = bch2_trans_kmalloc(trans, sizeof(*s)); + ret = PTR_ERR_OR_ZERO(s); + if (ret) + goto out; + + s->pos = k_iter->pos; + darray_init(&s->ids); + + ret = bch2_get_snapshot_overwrites(trans, desc->btree_id, k_iter->pos, &s->ids); + if (ret) + goto out; + + free_snapshots_seen = true; + } + if (fsck_err(trans, hash_table_key_wrong_offset, "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n%s", bch2_btree_id_str(desc->btree_id), hash_k.k->p.inode, hash_k.k->p.offset, hash, @@ -286,7 +305,9 @@ bad_hash: if (k.k) goto duplicate_entries; - ret = bch2_hash_delete_at(trans, *desc, hash_info, k_iter, + ret = bch2_insert_snapshot_whiteouts(trans, desc->btree_id, + k_iter->pos, new->k.p) ?: + bch2_hash_delete_at(trans, *desc, hash_info, k_iter, BTREE_ITER_with_updates| BTREE_UPDATE_internal_snapshot_node) ?: bch2_fsck_update_backpointers(trans, s, *desc, hash_info, new) ?: