summaryrefslogtreecommitdiff
path: root/fs/bcachefs/bkey_methods.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-02-03 01:09:10 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:12 +0300
commit7a7d17b2f7c23c0891b0cbd13fafd3bc805b1b29 (patch)
treedc4c22912655b6b21e721d05baa07646cbf52396 /fs/bcachefs/bkey_methods.c
parent8c6d298ab22fc1b2912ccef4ffd4a01b35f9c5b4 (diff)
downloadlinux-7a7d17b2f7c23c0891b0cbd13fafd3bc805b1b29.tar.xz
bcachefs: Whiteouts for snapshots
This patch adds KEY_TYPE_whiteout, a new type of whiteout for snapshots, when we're deleting and the key being deleted is in an ancestor snapshot - and updates the transaction update/commit path to use it. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/bkey_methods.c')
-rw-r--r--fs/bcachefs/bkey_methods.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/fs/bcachefs/bkey_methods.c b/fs/bcachefs/bkey_methods.c
index 42fdcc4487de..3133db236b7b 100644
--- a/fs/bcachefs/bkey_methods.c
+++ b/fs/bcachefs/bkey_methods.c
@@ -31,7 +31,7 @@ static const char *deleted_key_invalid(const struct bch_fs *c,
.key_invalid = deleted_key_invalid, \
}
-#define bch2_bkey_ops_discard (struct bkey_ops) { \
+#define bch2_bkey_ops_whiteout (struct bkey_ops) { \
.key_invalid = deleted_key_invalid, \
}
@@ -101,6 +101,8 @@ const char *bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k)
static unsigned bch2_key_types_allowed[] = {
[BKEY_TYPE_extents] =
+ (1U << KEY_TYPE_deleted)|
+ (1U << KEY_TYPE_whiteout)|
(1U << KEY_TYPE_error)|
(1U << KEY_TYPE_cookie)|
(1U << KEY_TYPE_extent)|
@@ -108,30 +110,43 @@ static unsigned bch2_key_types_allowed[] = {
(1U << KEY_TYPE_reflink_p)|
(1U << KEY_TYPE_inline_data),
[BKEY_TYPE_inodes] =
+ (1U << KEY_TYPE_deleted)|
+ (1U << KEY_TYPE_whiteout)|
(1U << KEY_TYPE_inode)|
(1U << KEY_TYPE_inode_generation),
[BKEY_TYPE_dirents] =
+ (1U << KEY_TYPE_deleted)|
+ (1U << KEY_TYPE_whiteout)|
(1U << KEY_TYPE_hash_whiteout)|
(1U << KEY_TYPE_dirent),
[BKEY_TYPE_xattrs] =
+ (1U << KEY_TYPE_deleted)|
+ (1U << KEY_TYPE_whiteout)|
(1U << KEY_TYPE_cookie)|
(1U << KEY_TYPE_hash_whiteout)|
(1U << KEY_TYPE_xattr),
[BKEY_TYPE_alloc] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_alloc)|
(1U << KEY_TYPE_alloc_v2),
[BKEY_TYPE_quotas] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_quota),
[BKEY_TYPE_stripes] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_stripe),
[BKEY_TYPE_reflink] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_reflink_v)|
(1U << KEY_TYPE_indirect_inline_data),
[BKEY_TYPE_subvolumes] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_subvolume),
[BKEY_TYPE_snapshots] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_snapshot),
[BKEY_TYPE_btree] =
+ (1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_btree_ptr)|
(1U << KEY_TYPE_btree_ptr_v2),
};
@@ -139,21 +154,18 @@ static unsigned bch2_key_types_allowed[] = {
const char *__bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
enum btree_node_type type)
{
- unsigned key_types_allowed = (1U << KEY_TYPE_deleted)|
- bch2_key_types_allowed[type] ;
-
if (k.k->u64s < BKEY_U64s)
return "u64s too small";
- if (!(key_types_allowed & (1U << k.k->type)))
+ if (!(bch2_key_types_allowed[type] & (1U << k.k->type)))
return "invalid key type for this btree";
if (type == BKEY_TYPE_btree &&
bkey_val_u64s(k.k) > BKEY_BTREE_PTR_VAL_U64s_MAX)
return "value too big";
- if (btree_node_type_is_extents(type)) {
- if ((k.k->size == 0) != bkey_deleted(k.k))
+ if (btree_node_type_is_extents(type) && !bkey_whiteout(k.k)) {
+ if (k.k->size == 0)
return "bad size field";
if (k.k->size > k.k->p.offset)