summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/str_hash.h
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/str_hash.h
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/str_hash.h')
-rw-r--r--fs/bcachefs/str_hash.h45
1 files changed, 32 insertions, 13 deletions
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,