summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/bset.c64
-rw-r--r--drivers/md/bcache/btree_iter.c24
-rw-r--r--drivers/md/bcache/btree_update.c2
3 files changed, 57 insertions, 33 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
index 05d646787c88..82bceb26ade1 100644
--- a/drivers/md/bcache/bset.c
+++ b/drivers/md/bcache/bset.c
@@ -753,26 +753,42 @@ static inline unsigned bkey_mantissa(const struct bkey_packed *k,
return idx < BFLOAT_32BIT_NR ? (u32) v : (u16) v;
}
-static void make_bfloat(struct btree *b,
- struct bset_tree *t, unsigned j)
+static void make_bfloat(struct btree *b, struct bset_tree *t,
+ unsigned j,
+ struct bkey_packed *min_key)
{
+ struct bset *i = bset(b, t);
struct bkey_float *f = bkey_float(b, t, j);
struct bkey_packed *m = tree_to_bkey(b, t, j);
struct bkey_packed *p = tree_to_prev_bkey(b, t, j);
- struct bset *i = bset(b, t);
+ struct bkey_packed *l, *r;
unsigned bits = j < BFLOAT_32BIT_NR ? 32 : 16;
unsigned mantissa;
+ int shift, exponent;
- struct bkey_packed *l = is_power_of_2(j)
- ? i->start
- : tree_to_prev_bkey(b, t, j >> ffs(j));
+ if (is_power_of_2(j)) {
+ if (!min_key->u64s) {
+ if (!bkey_pack_pos(min_key, b->data->min_key, b)) {
+ struct bkey_i tmp;
- struct bkey_packed *r = is_power_of_2(j + 1)
+ bkey_init(&tmp.k);
+ tmp.k.p = b->data->min_key;
+ bkey_copy(min_key, &tmp);
+ }
+ }
+
+ l = min_key;
+ } else {
+ l = tree_to_prev_bkey(b, t, j >> ffs(j));
+
+ EBUG_ON(m < l);
+ }
+
+ r = is_power_of_2(j + 1)
? bset_bkey_idx(i, le16_to_cpu(i->u64s) - t->end.u64s)
: tree_to_bkey(b, t, j >> (ffz(j) + 1));
- int shift, exponent;
- EBUG_ON(m < l || m > r);
+ EBUG_ON(m > r);
EBUG_ON(bkey_next(p) != m);
/*
@@ -918,6 +934,7 @@ static void __build_ro_aux_tree(struct btree *b, struct bset_tree *t)
{
struct bset *i = bset(b, t);
struct bkey_packed *prev = NULL, *k = i->start;
+ struct bkey_packed min_key = { .u64s = 0 };
unsigned j, cacheline = 1;
t->size = min(bkey_to_cacheline(b, t, bset_bkey_last(i)),
@@ -960,7 +977,7 @@ retry:
for (j = inorder_next(0, t->size);
j;
j = inorder_next(j, t->size))
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
}
static void bset_alloc_tree(struct btree *b, struct bset_tree *t)
@@ -1109,22 +1126,26 @@ struct bkey_packed *bkey_prev(struct btree *b, struct bset_tree *t,
void bch_bset_fix_invalidated_key(struct btree *b, struct bset_tree *t,
struct bkey_packed *k)
{
+ struct bkey_packed min_key;
unsigned inorder, j = 1;
if (bset_aux_tree_type(t) != BSET_RO_AUX_TREE)
return;
+ /* signal to make_bfloat() that min_key is uninitialized: */
+ min_key.u64s = 0;
+
inorder = bkey_to_cacheline(b, t, k);
if (k == bset(b, t)->start)
for (j = 1; j < t->size; j = j * 2)
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
if (bkey_next(k) == bset_bkey_last(bset(b, t))) {
t->end = *k;
for (j = 1; j < t->size; j = j * 2 + 1)
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
}
j = inorder_to_tree(inorder, t);
@@ -1133,11 +1154,11 @@ void bch_bset_fix_invalidated_key(struct btree *b, struct bset_tree *t,
j < t->size &&
k == tree_to_bkey(b, t, j)) {
/* Fix the auxiliary search tree node this key corresponds to */
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
/* Children for which this key is the right side boundary */
for (j = j * 2; j < t->size; j = j * 2 + 1)
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
}
j = inorder_to_tree(inorder + 1, t);
@@ -1145,11 +1166,11 @@ void bch_bset_fix_invalidated_key(struct btree *b, struct bset_tree *t,
if (j &&
j < t->size &&
k == tree_to_prev_bkey(b, t, j)) {
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
/* Children for which this key is the left side boundary */
for (j = j * 2 + 1; j < t->size; j = j * 2)
- make_bfloat(b, t, j);
+ make_bfloat(b, t, j, &min_key);
}
}
EXPORT_SYMBOL(bch_bset_fix_invalidated_key);
@@ -1447,15 +1468,10 @@ static struct bkey_packed *bch_bset_search(struct btree *b,
* start and end - handle that here:
*/
- if (unlikely(bkey_cmp_p_or_unp(b, &t->end,
- packed_search, &search) < 0))
+ if (bkey_cmp_p_or_unp(b, &t->end, packed_search, &search) < 0)
return bset_bkey_last(bset(b, t));
- if (unlikely(bkey_cmp_p_or_unp(b, bset(b, t)->start,
- packed_search, &search) >= 0))
- m = bset(b, t)->start;
- else
- m = bset_search_tree(b, t, search, lossy_packed_search);
+ m = bset_search_tree(b, t, search, lossy_packed_search);
break;
}
@@ -1573,7 +1589,7 @@ void bch_btree_node_iter_init(struct btree_node_iter *iter,
struct bset_tree *t;
struct bkey_packed p, *packed_search;
- BUG_ON(b->nsets > MAX_BSETS);
+ EBUG_ON(bkey_cmp(search, b->data->min_key) < 0);
bset_aux_tree_verify(b);
diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c
index 684c0e89622e..e176108b3d7e 100644
--- a/drivers/md/bcache/btree_iter.c
+++ b/drivers/md/bcache/btree_iter.c
@@ -561,25 +561,27 @@ static inline void __btree_iter_init(struct btree_iter *iter,
bch_btree_node_iter_peek(&iter->node_iters[b->level], b);
}
+static inline bool btree_iter_pos_in_node(struct btree_iter *iter,
+ struct btree *b)
+{
+ return iter->btree_id == b->btree_id &&
+ bkey_cmp(iter->pos, b->data->min_key) >= 0 &&
+ btree_iter_pos_cmp(iter->pos, &b->key.k, iter->is_extents);
+}
+
static inline void btree_iter_node_set(struct btree_iter *iter,
struct btree *b)
{
btree_iter_verify_new_node(iter, b);
- BUG_ON(b->lock.state.seq & 1);
+ EBUG_ON(!btree_iter_pos_in_node(iter, b));
+ EBUG_ON(b->lock.state.seq & 1);
iter->lock_seq[b->level] = b->lock.state.seq;
iter->nodes[b->level] = b;
__btree_iter_init(iter, b);
}
-static bool btree_iter_pos_in_node(struct btree_iter *iter, struct btree *b)
-{
- return iter->btree_id == b->btree_id &&
- bkey_cmp(iter->pos, b->data->min_key) >= 0 &&
- btree_iter_pos_cmp(iter->pos, &b->key.k, iter->is_extents);
-}
-
/*
* A btree node is being replaced - update the iterator to point to the new
* node:
@@ -945,7 +947,11 @@ struct btree *bch_btree_iter_next_node(struct btree_iter *iter, unsigned depth)
if (bkey_cmp(iter->pos, b->key.k.p) < 0) {
/* Haven't gotten to the end of the parent node: */
- iter->pos = bkey_successor(iter->pos);
+
+ /* ick: */
+ iter->pos = iter->btree_id == BTREE_ID_INODES
+ ? btree_type_successor(iter->btree_id, iter->pos)
+ : bkey_successor(iter->pos);
iter->level = depth;
ret = bch_btree_iter_traverse(iter);
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c
index f91b388b1f72..ed634c519e29 100644
--- a/drivers/md/bcache/btree_update.c
+++ b/drivers/md/bcache/btree_update.c
@@ -30,6 +30,8 @@ void __bch_btree_calc_format(struct bkey_format_state *s, struct btree *b)
struct bset_tree *t;
struct bkey uk;
+ bch_bkey_format_add_pos(s, b->data->min_key);
+
for_each_bset(b, t)
for (k = bset(b, t)->start;
k != bset_bkey_last(bset(b, t));