summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-09-08 20:18:04 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-09-08 20:20:09 -0800
commiteeeb0b243c7eae69a752a969d4c56661ee6cdbb5 (patch)
tree99e66020d27d5393c091402c94acb1c6720426e4
parent24203d787c2b5ee1d69073aea935905848f02c77 (diff)
bcache: don't migrate same extent twice in same pass
With extent merging, we could end up migrating an extent that contains as a subset an extent we just saw and decided to migrate - which breaks with the new migration code.
-rw-r--r--drivers/md/bcache/keylist.c8
-rw-r--r--drivers/md/bcache/tier.c11
2 files changed, 15 insertions, 4 deletions
diff --git a/drivers/md/bcache/keylist.c b/drivers/md/bcache/keylist.c
index 638596300575..4f9d1865abdc 100644
--- a/drivers/md/bcache/keylist.c
+++ b/drivers/md/bcache/keylist.c
@@ -2,6 +2,7 @@
#include "bcache.h"
#include "btree_gc.h"
#include "btree_iter.h"
+#include "extents.h"
#include "keylist.h"
#include <trace/events/bcache.h>
@@ -247,7 +248,12 @@ static void bch_refill_scan_keylist(struct cache_set *c,
}
if (pred(kl, k)) {
- if (bch_scan_keylist_add(kl, k))
+ BKEY_PADDED(k) tmp;
+
+ bkey_reassemble(&tmp.k, k);
+ bch_cut_front(*last_scanned, &tmp.k);
+
+ if (bch_scan_keylist_add(kl, bkey_i_to_s_c(&tmp.k)))
goto done;
nr_found++;
diff --git a/drivers/md/bcache/tier.c b/drivers/md/bcache/tier.c
index 87f4971dfda7..524a304c367f 100644
--- a/drivers/md/bcache/tier.c
+++ b/drivers/md/bcache/tier.c
@@ -160,6 +160,8 @@ static void tiering_refill(struct cache_set *c, struct tiering_refill *refill)
trace_bcache_tiering_refill_start(c);
for_each_btree_key(&iter, c, BTREE_ID_EXTENTS, refill->start, k) {
+ BKEY_PADDED(k) tmp;
+
keys = &refill->ca->tiering_queue.keys;
if (!tiering_pred(keys, k)) {
@@ -167,13 +169,16 @@ static void tiering_refill(struct cache_set *c, struct tiering_refill *refill)
goto next;
}
+ bkey_reassemble(&tmp.k, k);
+ bch_cut_front(refill->start, &tmp.k);
+
/* Growing the keylist might fail */
- if (bch_scan_keylist_add(keys, k))
+ if (bch_scan_keylist_add(keys, bkey_i_to_s_c(&tmp.k)))
goto done;
/* TODO: split key if refill->sectors is now > stripe_size */
- refill->sectors += k.k->size;
- refill->start = k.k->p;
+ refill->sectors += tmp.k.k.size;
+ refill->start = tmp.k.k.p;
/* Check if we've added enough keys to this keylist */
if (tiering_keylist_full(refill)) {