summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/str_hash.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-10-12 12:06:02 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:14 -0400
commit4db650277d42c0c80cde8fa3571ff1fb2fded8d9 (patch)
tree69697c049166bd3211c3b7266702ca8ee0d8b909 /fs/bcachefs/str_hash.h
parente5fa91d7ac88ac6a8385c14dbc8dcbe1a053e62f (diff)
downloadlinux-stable-4db650277d42c0c80cde8fa3571ff1fb2fded8d9.tar.gz
linux-stable-4db650277d42c0c80cde8fa3571ff1fb2fded8d9.tar.bz2
linux-stable-4db650277d42c0c80cde8fa3571ff1fb2fded8d9.zip
bcachefs: Subvol dirents are now only visible in parent subvol
This changes the on disk format for dirents that point to subvols so that they also record the subvolid of the parent subvol, so that we can filter them out in other subvolumes. This also updates the dirent code to do that filtering, and in particular tweaks the rename code - we need to ensure that there's only ever one dirent (counting multiplicities in different snapshots) that point to a subvolume. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/str_hash.h')
-rw-r--r--fs/bcachefs/str_hash.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/bcachefs/str_hash.h b/fs/bcachefs/str_hash.h
index 3e54d0b0fb5c..789dde7c6ac6 100644
--- a/fs/bcachefs/str_hash.h
+++ b/fs/bcachefs/str_hash.h
@@ -138,8 +138,15 @@ struct bch_hash_desc {
u64 (*hash_bkey)(const struct bch_hash_info *, struct bkey_s_c);
bool (*cmp_key)(struct bkey_s_c, const void *);
bool (*cmp_bkey)(struct bkey_s_c, struct bkey_s_c);
+ bool (*is_visible)(subvol_inum inum, struct bkey_s_c);
};
+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));
+}
+
static __always_inline int
bch2_hash_lookup(struct btree_trans *trans,
struct btree_iter *iter,
@@ -162,7 +169,7 @@ bch2_hash_lookup(struct btree_trans *trans,
if (iter->pos.inode != inum.inum)
break;
- if (k.k->type == desc.key_type) {
+ if (is_visible_key(desc, inum, k)) {
if (!desc.cmp_key(k, key))
return 0;
} else if (k.k->type == KEY_TYPE_hash_whiteout) {
@@ -198,7 +205,7 @@ bch2_hash_hole(struct btree_trans *trans,
if (iter->pos.inode != inum.inum)
break;
- if (k.k->type != desc.key_type)
+ if (!is_visible_key(desc, inum, k))
return 0;
}
bch2_trans_iter_exit(trans, iter);
@@ -261,7 +268,7 @@ int bch2_hash_set(struct btree_trans *trans,
if (iter.pos.inode != inum.inum)
break;
- if (k.k->type == desc.key_type) {
+ if (is_visible_key(desc, inum, k)) {
if (!desc.cmp_bkey(k, bkey_i_to_s_c(insert)))
goto found;