Loading fs/bcachefs/bkey.h +6 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,12 @@ static inline unsigned bkeyp_key_u64s(const struct bkey_format *format, return bkey_packed(k) ? format->key_u64s : BKEY_U64s; } static inline bool bkeyp_u64s_valid(const struct bkey_format *f, const struct bkey_packed *k) { return ((unsigned) k->u64s - bkeyp_key_u64s(f, k) <= U8_MAX - BKEY_U64s); } static inline unsigned bkeyp_key_bytes(const struct bkey_format *format, const struct bkey_packed *k) { Loading fs/bcachefs/btree_io.c +8 −7 Original line number Diff line number Diff line Loading @@ -831,7 +831,7 @@ static int bset_key_invalid(struct bch_fs *c, struct btree *b, (rw == WRITE ? bch2_bkey_val_invalid(c, k, READ, err) : 0); } static bool __bkey_valid(struct bch_fs *c, struct btree *b, static bool bkey_packed_valid(struct bch_fs *c, struct btree *b, struct bset *i, struct bkey_packed *k) { if (bkey_p_next(k) > vstruct_last(i)) Loading @@ -840,7 +840,7 @@ static bool __bkey_valid(struct bch_fs *c, struct btree *b, if (k->format > KEY_FORMAT_CURRENT) return false; if (k->u64s < bkeyp_key_u64s(&b->format, k)) if (!bkeyp_u64s_valid(&b->format, k)) return false; struct printbuf buf = PRINTBUF; Loading Loading @@ -884,11 +884,13 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b, "invalid bkey format %u", k->format)) goto drop_this_key; if (btree_err_on(k->u64s < bkeyp_key_u64s(&b->format, k), if (btree_err_on(!bkeyp_u64s_valid(&b->format, k), -BCH_ERR_btree_node_read_err_fixable, c, NULL, b, i, btree_node_bkey_bad_u64s, "k->u64s too small (%u < %u)", k->u64s, bkeyp_key_u64s(&b->format, k))) "bad k->u64s %u (min %u max %lu)", k->u64s, bkeyp_key_u64s(&b->format, k), U8_MAX - BKEY_U64s + bkeyp_key_u64s(&b->format, k))) goto drop_this_key; if (!write) Loading Loading @@ -947,13 +949,12 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b, * do */ if (!__bkey_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) { if (!bkey_packed_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) { for (next_good_key = 1; next_good_key < (u64 *) vstruct_last(i) - (u64 *) k; next_good_key++) if (__bkey_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) if (bkey_packed_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) goto got_good_key; } /* Loading Loading
fs/bcachefs/bkey.h +6 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,12 @@ static inline unsigned bkeyp_key_u64s(const struct bkey_format *format, return bkey_packed(k) ? format->key_u64s : BKEY_U64s; } static inline bool bkeyp_u64s_valid(const struct bkey_format *f, const struct bkey_packed *k) { return ((unsigned) k->u64s - bkeyp_key_u64s(f, k) <= U8_MAX - BKEY_U64s); } static inline unsigned bkeyp_key_bytes(const struct bkey_format *format, const struct bkey_packed *k) { Loading
fs/bcachefs/btree_io.c +8 −7 Original line number Diff line number Diff line Loading @@ -831,7 +831,7 @@ static int bset_key_invalid(struct bch_fs *c, struct btree *b, (rw == WRITE ? bch2_bkey_val_invalid(c, k, READ, err) : 0); } static bool __bkey_valid(struct bch_fs *c, struct btree *b, static bool bkey_packed_valid(struct bch_fs *c, struct btree *b, struct bset *i, struct bkey_packed *k) { if (bkey_p_next(k) > vstruct_last(i)) Loading @@ -840,7 +840,7 @@ static bool __bkey_valid(struct bch_fs *c, struct btree *b, if (k->format > KEY_FORMAT_CURRENT) return false; if (k->u64s < bkeyp_key_u64s(&b->format, k)) if (!bkeyp_u64s_valid(&b->format, k)) return false; struct printbuf buf = PRINTBUF; Loading Loading @@ -884,11 +884,13 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b, "invalid bkey format %u", k->format)) goto drop_this_key; if (btree_err_on(k->u64s < bkeyp_key_u64s(&b->format, k), if (btree_err_on(!bkeyp_u64s_valid(&b->format, k), -BCH_ERR_btree_node_read_err_fixable, c, NULL, b, i, btree_node_bkey_bad_u64s, "k->u64s too small (%u < %u)", k->u64s, bkeyp_key_u64s(&b->format, k))) "bad k->u64s %u (min %u max %lu)", k->u64s, bkeyp_key_u64s(&b->format, k), U8_MAX - BKEY_U64s + bkeyp_key_u64s(&b->format, k))) goto drop_this_key; if (!write) Loading Loading @@ -947,13 +949,12 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b, * do */ if (!__bkey_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) { if (!bkey_packed_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) { for (next_good_key = 1; next_good_key < (u64 *) vstruct_last(i) - (u64 *) k; next_good_key++) if (__bkey_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) if (bkey_packed_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) goto got_good_key; } /* Loading