diff options
-rw-r--r-- | drivers/md/bcache/bset.c | 64 | ||||
-rw-r--r-- | drivers/md/bcache/btree_iter.c | 24 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 2 |
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)); |