aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/bset.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
index 14032e8c773..1b27cbd822e 100644
--- a/drivers/md/bcache/bset.c
+++ b/drivers/md/bcache/bset.c
@@ -927,7 +927,7 @@ static void sort_key_next(struct btree_iter *iter,
*i = iter->data[--iter->used];
}
-static void btree_sort_fixup(struct btree_iter *iter)
+static struct bkey *btree_sort_fixup(struct btree_iter *iter, struct bkey *tmp)
{
while (iter->used > 1) {
struct btree_iter_set *top = iter->data, *i = top + 1;
@@ -955,9 +955,22 @@ static void btree_sort_fixup(struct btree_iter *iter)
} else {
/* can't happen because of comparison func */
BUG_ON(!bkey_cmp(&START_KEY(top->k), &START_KEY(i->k)));
- bch_cut_back(&START_KEY(i->k), top->k);
+
+ if (bkey_cmp(i->k, top->k) < 0) {
+ bkey_copy(tmp, top->k);
+
+ bch_cut_back(&START_KEY(i->k), tmp);
+ bch_cut_front(i->k, top->k);
+ heap_sift(iter, 0, btree_iter_cmp);
+
+ return tmp;
+ } else {
+ bch_cut_back(&START_KEY(i->k), top->k);
+ }
}
}
+
+ return NULL;
}
static void btree_mergesort(struct btree *b, struct bset *out,
@@ -965,15 +978,20 @@ static void btree_mergesort(struct btree *b, struct bset *out,
bool fixup, bool remove_stale)
{
struct bkey *k, *last = NULL;
+ BKEY_PADDED(k) tmp;
bool (*bad)(struct btree *, const struct bkey *) = remove_stale
? bch_ptr_bad
: bch_ptr_invalid;
while (!btree_iter_end(iter)) {
if (fixup && !b->level)
- btree_sort_fixup(iter);
+ k = btree_sort_fixup(iter, &tmp.k);
+ else
+ k = NULL;
+
+ if (!k)
+ k = bch_btree_iter_next(iter);
- k = bch_btree_iter_next(iter);
if (bad(b, k))
continue;