summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-09-04 14:10:12 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:40 -0400
commit5877d8876afe1c5843731244f39d1739eba2665f (patch)
treec7b6d5807d5698e1ff3ebe3186567dfc4c275cec /fs/bcachefs
parent1ffb876fb0f31632b761ee721f633e0d7491ca7b (diff)
downloadlinux-stable-5877d8876afe1c5843731244f39d1739eba2665f.tar.gz
linux-stable-5877d8876afe1c5843731244f39d1739eba2665f.tar.bz2
linux-stable-5877d8876afe1c5843731244f39d1739eba2665f.zip
bcachefs: Re-enable hash_redo_key()
When subvolumes & snapshots were rolled out, hash_redo_key() was disabled due to some new complications - namely, bch2_hash_set() works at the subvolume level, and fsck does not run in a defined subvolume, instead working at the snapshot ID level. This patch splits out bch2_hash_set_snapshot() from bch2_hash_set(), and makes one small tweak for fsck: - Normally, bch2_hash_set() (and other dirent code) needs to know what subvolume we're in, because dirents that point to other subvolumes should only be visible in the subvolume they were created in, not other snapshots. We can't check that in fsck, so we just assume that all dirents are visible. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs')
-rw-r--r--fs/bcachefs/fsck.c13
-rw-r--r--fs/bcachefs/str_hash.h45
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,