diff options
-rw-r--r-- | drivers/md/bcache/alloc.c | 5 | ||||
-rw-r--r-- | drivers/md/bcache/bcache.h | 6 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 18 | ||||
-rw-r--r-- | drivers/md/bcache/extents.c | 6 |
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 | ||
156 | static bool can_invalidate_bucket(struct cache *ca, struct bucket *b) | 156 | static 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 | ||
209 | BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2); | 209 | BITMASK(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)) |
215 | BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE); | 215 | BITMASK(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) |