summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-11-18 15:27:57 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2017-01-18 21:41:03 -0900
commit6614085ddf310d7733af78407d3fa2942ef84b70 (patch)
treec24289bce6f44b7a58152f0258d2265e548f1490
parent7cd6bf669428a0fe817b3f50e69a7d85ce7efe48 (diff)
bcache: add support for BSET_SEPARATE_WHITEOUTS()
-rw-r--r--drivers/md/bcache/btree_io.c22
-rw-r--r--drivers/md/bcache/super.c2
-rw-r--r--include/uapi/linux/bcache.h2
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;