aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/alloc.c5
-rw-r--r--drivers/md/bcache/bcache.h6
-rw-r--r--drivers/md/bcache/btree.c18
-rw-r--r--drivers/md/bcache/extents.c6
4 files changed, 21 insertions, 14 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index a3e1427945f2..5ba4eaea57f4 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -155,7 +155,8 @@ add:
155 155
156static bool can_invalidate_bucket(struct cache *ca, struct bucket *b) 156static bool can_invalidate_bucket(struct cache *ca, struct bucket *b)
157{ 157{
158 return GC_MARK(b) == GC_MARK_RECLAIMABLE && 158 return (!GC_MARK(b) ||
159 GC_MARK(b) == GC_MARK_RECLAIMABLE) &&
159 !atomic_read(&b->pin) && 160 !atomic_read(&b->pin) &&
160 can_inc_bucket_gen(b); 161 can_inc_bucket_gen(b);
161} 162}
@@ -475,7 +476,7 @@ void bch_bucket_free(struct cache_set *c, struct bkey *k)
475 for (i = 0; i < KEY_PTRS(k); i++) { 476 for (i = 0; i < KEY_PTRS(k); i++) {
476 struct bucket *b = PTR_BUCKET(c, k, i); 477 struct bucket *b = PTR_BUCKET(c, k, i);
477 478
478 SET_GC_MARK(b, GC_MARK_RECLAIMABLE); 479 SET_GC_MARK(b, 0);
479 SET_GC_SECTORS_USED(b, 0); 480 SET_GC_SECTORS_USED(b, 0);
480 bch_bucket_add_unused(PTR_CACHE(c, k, i), b); 481 bch_bucket_add_unused(PTR_CACHE(c, k, i), b);
481 } 482 }
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 6d814f463d9e..014236e411d8 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -207,9 +207,9 @@ struct bucket {
207 */ 207 */
208 208
209BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2); 209BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2);
210#define GC_MARK_RECLAIMABLE 0 210#define GC_MARK_RECLAIMABLE 1
211#define GC_MARK_DIRTY 1 211#define GC_MARK_DIRTY 2
212#define GC_MARK_METADATA 2 212#define GC_MARK_METADATA 3
213#define GC_SECTORS_USED_SIZE 13 213#define GC_SECTORS_USED_SIZE 13
214#define MAX_GC_SECTORS_USED (~(~0ULL << GC_SECTORS_USED_SIZE)) 214#define MAX_GC_SECTORS_USED (~(~0ULL << GC_SECTORS_USED_SIZE))
215BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE); 215BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE);
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index ea5a59e2d740..1672db348c8b 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -1160,6 +1160,8 @@ static uint8_t __bch_btree_mark_key(struct cache_set *c, int level,
1160 SET_GC_MARK(g, GC_MARK_METADATA); 1160 SET_GC_MARK(g, GC_MARK_METADATA);
1161 else if (KEY_DIRTY(k)) 1161 else if (KEY_DIRTY(k))
1162 SET_GC_MARK(g, GC_MARK_DIRTY); 1162 SET_GC_MARK(g, GC_MARK_DIRTY);
1163 else if (!GC_MARK(g))
1164 SET_GC_MARK(g, GC_MARK_RECLAIMABLE);
1163 1165
1164 /* guard against overflow */ 1166 /* guard against overflow */
1165 SET_GC_SECTORS_USED(g, min_t(unsigned, 1167 SET_GC_SECTORS_USED(g, min_t(unsigned,
@@ -1559,7 +1561,7 @@ static void btree_gc_start(struct cache_set *c)
1559 for_each_bucket(b, ca) { 1561 for_each_bucket(b, ca) {
1560 b->gc_gen = b->gen; 1562 b->gc_gen = b->gen;
1561 if (!atomic_read(&b->pin)) { 1563 if (!atomic_read(&b->pin)) {
1562 SET_GC_MARK(b, GC_MARK_RECLAIMABLE); 1564 SET_GC_MARK(b, 0);
1563 SET_GC_SECTORS_USED(b, 0); 1565 SET_GC_SECTORS_USED(b, 0);
1564 } 1566 }
1565 } 1567 }
@@ -1622,12 +1624,16 @@ size_t bch_btree_gc_finish(struct cache_set *c)
1622 b->last_gc = b->gc_gen; 1624 b->last_gc = b->gc_gen;
1623 c->need_gc = max(c->need_gc, bucket_gc_gen(b)); 1625 c->need_gc = max(c->need_gc, bucket_gc_gen(b));
1624 1626
1625 if (!atomic_read(&b->pin) && 1627 if (atomic_read(&b->pin))
1626 GC_MARK(b) == GC_MARK_RECLAIMABLE) { 1628 continue;
1629
1630 BUG_ON(!GC_MARK(b) && GC_SECTORS_USED(b));
1631
1632 if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE)
1627 available++; 1633 available++;
1628 if (!GC_SECTORS_USED(b)) 1634
1629 bch_bucket_add_unused(ca, b); 1635 if (!GC_MARK(b))
1630 } 1636 bch_bucket_add_unused(ca, b);
1631 } 1637 }
1632 } 1638 }
1633 1639
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c
index 416d1a3e028e..82d5e3288a6c 100644
--- a/drivers/md/bcache/extents.c
+++ b/drivers/md/bcache/extents.c
@@ -499,9 +499,9 @@ static bool bch_extent_bad_expensive(struct btree *b, const struct bkey *k,
499 499
500 if (mutex_trylock(&b->c->bucket_lock)) { 500 if (mutex_trylock(&b->c->bucket_lock)) {
501 if (b->c->gc_mark_valid && 501 if (b->c->gc_mark_valid &&
502 ((GC_MARK(g) != GC_MARK_DIRTY && 502 (!GC_MARK(g) ||
503 KEY_DIRTY(k)) || 503 GC_MARK(g) == GC_MARK_METADATA ||
504 GC_MARK(g) == GC_MARK_METADATA)) 504 (GC_MARK(g) != GC_MARK_DIRTY && KEY_DIRTY(k))))
505 goto err; 505 goto err;
506 506
507 if (g->prio == BTREE_PRIO) 507 if (g->prio == BTREE_PRIO)