diff options
-rw-r--r-- | drivers/md/bcache/btree_io.c | 22 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 2 | ||||
-rw-r--r-- | include/uapi/linux/bcache.h | 2 |
3 files changed, 21 insertions, 5 deletions
diff --git a/drivers/md/bcache/btree_io.c b/drivers/md/bcache/btree_io.c index 4b03e6b32243..19ed5f085ab4 100644 --- a/drivers/md/bcache/btree_io.c +++ b/drivers/md/bcache/btree_io.c @@ -259,10 +259,12 @@ void bch_btree_init_next(struct cache_set *c, struct btree *b, static const char *validate_bset(struct cache_set *c, struct btree *b, struct cache *ca, const struct bch_extent_ptr *ptr, - struct bset *i, unsigned sectors) + struct bset *i, unsigned sectors, + unsigned *whiteout_u64s) { struct bkey_format *f = &b->keys.format; struct bkey_packed *k; + bool seen_non_whiteout = false; if (le16_to_cpu(i->version) != BCACHE_BSET_VERSION) return "unsupported bset version"; @@ -326,6 +328,13 @@ static const char *validate_bset(struct cache_set *c, struct btree *b, continue; } + if (BSET_SEPARATE_WHITEOUTS(i) && + !seen_non_whiteout && + !bkey_packed_is_whiteout(&b->keys, k)) { + *whiteout_u64s = k->_data - i->_data; + seen_non_whiteout = true; + } + k = bkey_next(k); } @@ -353,7 +362,7 @@ void bch_btree_node_read_done(struct cache_set *c, struct btree *b, goto err; while (b->written < c->sb.btree_node_size) { - unsigned sectors; + unsigned sectors, whiteout_u64s = 0; if (!b->written) { i = &b->data->keys; @@ -421,7 +430,7 @@ void bch_btree_node_read_done(struct cache_set *c, struct btree *b, block_bytes(c)) << c->block_bits; } - err = validate_bset(c, b, ca, ptr, i, sectors); + err = validate_bset(c, b, ca, ptr, i, sectors, &whiteout_u64s); if (err) goto err; @@ -434,7 +443,12 @@ void bch_btree_node_read_done(struct cache_set *c, struct btree *b, continue; __bch_btree_node_iter_push(iter, &b->keys, - i->start, bset_bkey_last(i)); + i->start, + bkey_idx(i, whiteout_u64s)); + + __bch_btree_node_iter_push(iter, &b->keys, + bkey_idx(i, whiteout_u64s), + bset_bkey_last(i)); } err = "corrupted btree"; diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index e1080b9e6e66..52abe0aabcf6 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1138,7 +1138,7 @@ static struct cache_set *bch_cache_set_alloc(struct cache_sb *sb, if (cache_set_init_fault("cache_set_alloc")) goto err; - iter_size = (btree_blocks(c) + 1) * + iter_size = (btree_blocks(c) + 1) * 2 * sizeof(struct btree_node_iter_set); if (!(c->wq = alloc_workqueue("bcache", diff --git a/include/uapi/linux/bcache.h b/include/uapi/linux/bcache.h index 53b2889259a3..5f2558b7a096 100644 --- a/include/uapi/linux/bcache.h +++ b/include/uapi/linux/bcache.h @@ -1132,6 +1132,8 @@ LE32_BITMASK(BSET_CSUM_TYPE, struct bset, flags, 0, 4); LE32_BITMASK(BSET_BTREE_LEVEL, struct bset, flags, 4, 8); LE32_BITMASK(BSET_BIG_ENDIAN, struct bset, flags, 8, 9); +LE32_BITMASK(BSET_SEPARATE_WHITEOUTS, + struct bset, flags, 9, 10); struct btree_node { __le64 csum; |