Commit 4fe6a816707aace9e8e297b708411c5930537793

Authored by Kent Overstreet
1 parent c13f3af924

bcache: Add a real GC_MARK_RECLAIMABLE

This means the garbage collection code can better check for data and metadata
pointers to the same buckets.

Signed-off-by: Kent Overstreet <kmo@daterainc.com>

Showing 4 changed files with 21 additions and 14 deletions Side-by-side Diff

drivers/md/bcache/alloc.c
... ... @@ -155,7 +155,8 @@
155 155  
156 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 160 !atomic_read(&b->pin) &&
160 161 can_inc_bucket_gen(b);
161 162 }
... ... @@ -475,7 +476,7 @@
475 476 for (i = 0; i < KEY_PTRS(k); i++) {
476 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 480 SET_GC_SECTORS_USED(b, 0);
480 481 bch_bucket_add_unused(PTR_CACHE(c, k, i), b);
481 482 }
drivers/md/bcache/bcache.h
... ... @@ -207,9 +207,9 @@
207 207 */
208 208  
209 209 BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2);
210   -#define GC_MARK_RECLAIMABLE 0
211   -#define GC_MARK_DIRTY 1
212   -#define GC_MARK_METADATA 2
  210 +#define GC_MARK_RECLAIMABLE 1
  211 +#define GC_MARK_DIRTY 2
  212 +#define GC_MARK_METADATA 3
213 213 #define GC_SECTORS_USED_SIZE 13
214 214 #define MAX_GC_SECTORS_USED (~(~0ULL << GC_SECTORS_USED_SIZE))
215 215 BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE);
drivers/md/bcache/btree.c
... ... @@ -1160,6 +1160,8 @@
1160 1160 SET_GC_MARK(g, GC_MARK_METADATA);
1161 1161 else if (KEY_DIRTY(k))
1162 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 1166 /* guard against overflow */
1165 1167 SET_GC_SECTORS_USED(g, min_t(unsigned,
... ... @@ -1559,7 +1561,7 @@
1559 1561 for_each_bucket(b, ca) {
1560 1562 b->gc_gen = b->gen;
1561 1563 if (!atomic_read(&b->pin)) {
1562   - SET_GC_MARK(b, GC_MARK_RECLAIMABLE);
  1564 + SET_GC_MARK(b, 0);
1563 1565 SET_GC_SECTORS_USED(b, 0);
1564 1566 }
1565 1567 }
1566 1568  
... ... @@ -1622,12 +1624,16 @@
1622 1624 b->last_gc = b->gc_gen;
1623 1625 c->need_gc = max(c->need_gc, bucket_gc_gen(b));
1624 1626  
1625   - if (!atomic_read(&b->pin) &&
1626   - GC_MARK(b) == GC_MARK_RECLAIMABLE) {
  1627 + if (atomic_read(&b->pin))
  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 1633 available++;
1628   - if (!GC_SECTORS_USED(b))
1629   - bch_bucket_add_unused(ca, b);
1630   - }
  1634 +
  1635 + if (!GC_MARK(b))
  1636 + bch_bucket_add_unused(ca, b);
1631 1637 }
1632 1638 }
1633 1639  
drivers/md/bcache/extents.c
... ... @@ -499,9 +499,9 @@
499 499  
500 500 if (mutex_trylock(&b->c->bucket_lock)) {
501 501 if (b->c->gc_mark_valid &&
502   - ((GC_MARK(g) != GC_MARK_DIRTY &&
503   - KEY_DIRTY(k)) ||
504   - GC_MARK(g) == GC_MARK_METADATA))
  502 + (!GC_MARK(g) ||
  503 + GC_MARK(g) == GC_MARK_METADATA ||
  504 + (GC_MARK(g) != GC_MARK_DIRTY && KEY_DIRTY(k))))
505 505 goto err;
506 506  
507 507 if (g->prio == BTREE_PRIO)