Commit 9dd6358a authored by Kent Overstreet's avatar Kent Overstreet

bcache: Fix auxiliary search trees for key size > cacheline size

Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
parent 3b3e9e50
...@@ -511,9 +511,11 @@ static unsigned bkey_to_cacheline(struct bset_tree *t, struct bkey *k) ...@@ -511,9 +511,11 @@ static unsigned bkey_to_cacheline(struct bset_tree *t, struct bkey *k)
return ((void *) k - (void *) t->data) / BSET_CACHELINE; return ((void *) k - (void *) t->data) / BSET_CACHELINE;
} }
static unsigned bkey_to_cacheline_offset(struct bkey *k) static unsigned bkey_to_cacheline_offset(struct bset_tree *t,
unsigned cacheline,
struct bkey *k)
{ {
return ((size_t) k & (BSET_CACHELINE - 1)) / sizeof(uint64_t); return (u64 *) k - (u64 *) cacheline_to_bkey(t, cacheline, 0);
} }
static struct bkey *tree_to_bkey(struct bset_tree *t, unsigned j) static struct bkey *tree_to_bkey(struct bset_tree *t, unsigned j)
...@@ -608,7 +610,7 @@ static void bch_bset_build_unwritten_tree(struct btree_keys *b) ...@@ -608,7 +610,7 @@ static void bch_bset_build_unwritten_tree(struct btree_keys *b)
bset_alloc_tree(b, t); bset_alloc_tree(b, t);
if (t->tree != b->set->tree + btree_keys_cachelines(b)) { if (t->tree != b->set->tree + btree_keys_cachelines(b)) {
t->prev[0] = bkey_to_cacheline_offset(t->data->start); t->prev[0] = bkey_to_cacheline_offset(t, 0, t->data->start);
t->size = 1; t->size = 1;
} }
} }
...@@ -632,7 +634,7 @@ EXPORT_SYMBOL(bch_bset_init_next); ...@@ -632,7 +634,7 @@ EXPORT_SYMBOL(bch_bset_init_next);
void bch_bset_build_written_tree(struct btree_keys *b) void bch_bset_build_written_tree(struct btree_keys *b)
{ {
struct bset_tree *t = bset_tree_last(b); struct bset_tree *t = bset_tree_last(b);
struct bkey *k = t->data->start; struct bkey *prev = NULL, *k = t->data->start;
unsigned j, cacheline = 1; unsigned j, cacheline = 1;
b->last_set_unwritten = 0; b->last_set_unwritten = 0;
...@@ -654,13 +656,11 @@ void bch_bset_build_written_tree(struct btree_keys *b) ...@@ -654,13 +656,11 @@ void bch_bset_build_written_tree(struct btree_keys *b)
for (j = inorder_next(0, t->size); for (j = inorder_next(0, t->size);
j; j;
j = inorder_next(j, t->size)) { j = inorder_next(j, t->size)) {
while (bkey_to_cacheline(t, k) != cacheline) while (bkey_to_cacheline(t, k) < cacheline)
k = bkey_next(k); prev = k, k = bkey_next(k);
t->prev[j] = bkey_u64s(k); t->prev[j] = bkey_u64s(prev);
k = bkey_next(k); t->tree[j].m = bkey_to_cacheline_offset(t, cacheline++, k);
cacheline++;
t->tree[j].m = bkey_to_cacheline_offset(k);
} }
while (bkey_next(k) != bset_bkey_last(t->data)) while (bkey_next(k) != bset_bkey_last(t->data))
...@@ -739,8 +739,8 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b, ...@@ -739,8 +739,8 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b,
* lookup table for the first key that is strictly greater than k: * lookup table for the first key that is strictly greater than k:
* it's either k's cacheline or the next one * it's either k's cacheline or the next one
*/ */
if (j < t->size && while (j < t->size &&
table_to_bkey(t, j) <= k) table_to_bkey(t, j) <= k)
j++; j++;
/* Adjust all the lookup table entries, and find a new key for any that /* Adjust all the lookup table entries, and find a new key for any that
...@@ -755,7 +755,7 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b, ...@@ -755,7 +755,7 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b,
while (k < cacheline_to_bkey(t, j, 0)) while (k < cacheline_to_bkey(t, j, 0))
k = bkey_next(k); k = bkey_next(k);
t->prev[j] = bkey_to_cacheline_offset(k); t->prev[j] = bkey_to_cacheline_offset(t, j, k);
} }
} }
...@@ -768,7 +768,7 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b, ...@@ -768,7 +768,7 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b,
k != bset_bkey_last(t->data); k != bset_bkey_last(t->data);
k = bkey_next(k)) k = bkey_next(k))
if (t->size == bkey_to_cacheline(t, k)) { if (t->size == bkey_to_cacheline(t, k)) {
t->prev[t->size] = bkey_to_cacheline_offset(k); t->prev[t->size] = bkey_to_cacheline_offset(t, t->size, k);
t->size++; t->size++;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment