diff options
Diffstat (limited to 'libbcachefs/bkey_methods.c')
-rw-r--r-- | libbcachefs/bkey_methods.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/libbcachefs/bkey_methods.c b/libbcachefs/bkey_methods.c index 711bc88f..27f196ef 100644 --- a/libbcachefs/bkey_methods.c +++ b/libbcachefs/bkey_methods.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcachefs.h" #include "bkey_methods.h" @@ -81,9 +82,17 @@ const char *__bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k, if (k.k->u64s < BKEY_U64s) return "u64s too small"; + if ((btree_node_type_is_extents(type) || + type == BKEY_TYPE_BTREE) && + bkey_val_u64s(k.k) > BKEY_EXTENT_VAL_U64s_MAX) + return "value too big"; + if (btree_node_type_is_extents(type)) { if ((k.k->size == 0) != bkey_deleted(k.k)) return "bad size field"; + + if (k.k->size > k.k->p.offset) + return "size greater than offset"; } else { if (k.k->size) return "nonzero size field"; @@ -198,22 +207,22 @@ bool bch2_bkey_normalize(struct bch_fs *c, struct bkey_s k) } enum merge_result bch2_bkey_merge(struct bch_fs *c, - struct bkey_i *l, struct bkey_i *r) + struct bkey_s l, struct bkey_s r) { - const struct bkey_ops *ops = &bch2_bkey_ops[l->k.type]; + const struct bkey_ops *ops = &bch2_bkey_ops[l.k->type]; enum merge_result ret; if (key_merging_disabled(c) || !ops->key_merge || - l->k.type != r->k.type || - bversion_cmp(l->k.version, r->k.version) || - bkey_cmp(l->k.p, bkey_start_pos(&r->k))) + l.k->type != r.k->type || + bversion_cmp(l.k->version, r.k->version) || + bkey_cmp(l.k->p, bkey_start_pos(r.k))) return BCH_MERGE_NOMERGE; ret = ops->key_merge(c, l, r); if (ret != BCH_MERGE_NOMERGE) - l->k.needs_whiteout |= r->k.needs_whiteout; + l.k->needs_whiteout |= r.k->needs_whiteout; return ret; } |