diff options
author | Kent Overstreet <kmo@daterainc.com> | 2015-02-11 14:20:12 -0800 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2015-02-12 23:44:11 -0800 |
commit | d49160a317281562f2c64f4c46455e222feb1e70 (patch) | |
tree | 7e0cf762ef026a29e643b335e00bc63b91dea945 | |
parent | b354cf6ccab5f9934e88b8c2f91b47e2152f84b2 (diff) |
bcache: Validate bkey formatbcache-dev-february
Change-Id: Ie30284518f55388925da92e7e0c4e13e77f54a90
-rw-r--r-- | drivers/md/bcache/bkey.c | 20 | ||||
-rw-r--r-- | drivers/md/bcache/bkey.h | 1 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 4 |
3 files changed, 25 insertions, 0 deletions
diff --git a/drivers/md/bcache/bkey.c b/drivers/md/bcache/bkey.c index ab3a034f407a..b60a2481f92e 100644 --- a/drivers/md/bcache/bkey.c +++ b/drivers/md/bcache/bkey.c @@ -296,6 +296,26 @@ struct bkey_format bch_bkey_format_done(struct bkey_format_state *s) return ret; } +const char *bch_bkey_format_validate(struct bkey_format *f) +{ + unsigned i, bits = KEY_PACKED_BITS_START; + + if (f->nr_fields != BKEY_NR_FIELDS) + return "invalid format: incorrect number of fields"; + + for (i = 0; i < f->nr_fields; i++) { + if (f->bits_per_field[i] > 64) + return "invalid format: field too large"; + + bits += f->bits_per_field[i]; + } + + if (f->key_u64s != DIV_ROUND_UP(bits, 64)) + return "invalid format: incorrect key_u64s"; + + return NULL; +} + /* Most significant differing bit */ unsigned bkey_greatest_differing_bit(const struct bkey_format *format, const struct bkey_packed *l_k, diff --git a/drivers/md/bcache/bkey.h b/drivers/md/bcache/bkey.h index 666920d080f6..6ab9203b2fb0 100644 --- a/drivers/md/bcache/bkey.h +++ b/drivers/md/bcache/bkey.h @@ -57,6 +57,7 @@ void bch_bkey_format_init(struct bkey_format_state *); void bch_bkey_format_add_key(struct bkey_format_state *, struct bkey *); void bch_bkey_format_add_pos(struct bkey_format_state *, struct bpos); struct bkey_format bch_bkey_format_done(struct bkey_format_state *); +const char *bch_bkey_format_validate(struct bkey_format *); unsigned bkey_greatest_differing_bit(const struct bkey_format *, const struct bkey_packed *, diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index c4f9851b8b78..1ca4629ee08e 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -348,6 +348,10 @@ void bch_btree_node_read_done(struct btree *b, struct cache *ca, if (BSET_BTREE_LEVEL(i) != b->level) goto err; + err = bch_bkey_format_validate(&b->data->format); + if (err) + goto err; + b->keys.format = b->data->format; b->keys.set->data = &b->data->keys; |