bcache: remove for_each_cache()

Since now each cache_set explicitly has single cache, for_each_cache()
is unnecessary. This patch removes this macro, and update all locations
where it is used, and makes sure all code logic still being consistent.

Signed-off-by: Coly Li <colyli@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Coly Li 2020-10-01 14:50:47 +08:00 committed by Jens Axboe
parent 697e23495c
commit 08fdb2cddb
6 changed files with 251 additions and 308 deletions

View File

@ -88,7 +88,6 @@ void bch_rescale_priorities(struct cache_set *c, int sectors)
struct cache *ca;
struct bucket *b;
unsigned long next = c->nbuckets * c->sb.bucket_size / 1024;
unsigned int i;
int r;
atomic_sub(sectors, &c->rescale);
@ -104,7 +103,7 @@ void bch_rescale_priorities(struct cache_set *c, int sectors)
c->min_prio = USHRT_MAX;
for_each_cache(ca, c, i)
ca = c->cache;
for_each_bucket(b, ca)
if (b->prio &&
b->prio != BTREE_PRIO &&

View File

@ -887,9 +887,6 @@ do { \
/* Looping macros */
#define for_each_cache(ca, cs, iter) \
for (iter = 0; ca = cs->cache, iter < 1; iter++)
#define for_each_bucket(b, ca) \
for (b = (ca)->buckets + (ca)->sb.first_bucket; \
b < (ca)->buckets + (ca)->sb.nbuckets; b++)
@ -931,10 +928,8 @@ static inline uint8_t bucket_gc_gen(struct bucket *b)
static inline void wake_up_allocators(struct cache_set *c)
{
struct cache *ca;
unsigned int i;
struct cache *ca = c->cache;
for_each_cache(ca, c, i)
wake_up_process(ca->alloc_thread);
}

View File

@ -1167,12 +1167,11 @@ static void make_btree_freeing_key(struct btree *b, struct bkey *k)
static int btree_check_reserve(struct btree *b, struct btree_op *op)
{
struct cache_set *c = b->c;
struct cache *ca;
unsigned int i, reserve = (c->root->level - b->level) * 2 + 1;
struct cache *ca = c->cache;
unsigned int reserve = (c->root->level - b->level) * 2 + 1;
mutex_lock(&c->bucket_lock);
for_each_cache(ca, c, i)
if (fifo_used(&ca->free[RESERVE_BTREE]) < reserve) {
if (op)
prepare_to_wait(&c->btree_cache_wait, &op->wait,
@ -1695,7 +1694,6 @@ static void btree_gc_start(struct cache_set *c)
{
struct cache *ca;
struct bucket *b;
unsigned int i;
if (!c->gc_mark_valid)
return;
@ -1705,7 +1703,7 @@ static void btree_gc_start(struct cache_set *c)
c->gc_mark_valid = 0;
c->gc_done = ZERO_KEY;
for_each_cache(ca, c, i)
ca = c->cache;
for_each_bucket(b, ca) {
b->last_gc = b->gen;
if (!atomic_read(&b->pin)) {
@ -1721,7 +1719,8 @@ static void bch_btree_gc_finish(struct cache_set *c)
{
struct bucket *b;
struct cache *ca;
unsigned int i;
unsigned int i, j;
uint64_t *k;
mutex_lock(&c->bucket_lock);
@ -1739,7 +1738,6 @@ static void bch_btree_gc_finish(struct cache_set *c)
struct bcache_device *d = c->devices[i];
struct cached_dev *dc;
struct keybuf_key *w, *n;
unsigned int j;
if (!d || UUID_FLASH_ONLY(&c->uuids[i]))
continue;
@ -1756,17 +1754,16 @@ static void bch_btree_gc_finish(struct cache_set *c)
rcu_read_unlock();
c->avail_nbuckets = 0;
for_each_cache(ca, c, i) {
uint64_t *i;
ca = c->cache;
ca->invalidate_needs_gc = 0;
for (i = ca->sb.d; i < ca->sb.d + ca->sb.keys; i++)
SET_GC_MARK(ca->buckets + *i, GC_MARK_METADATA);
for (k = ca->sb.d; k < ca->sb.d + ca->sb.keys; k++)
SET_GC_MARK(ca->buckets + *k, GC_MARK_METADATA);
for (i = ca->prio_buckets;
i < ca->prio_buckets + prio_buckets(ca) * 2; i++)
SET_GC_MARK(ca->buckets + *i, GC_MARK_METADATA);
for (k = ca->prio_buckets;
k < ca->prio_buckets + prio_buckets(ca) * 2; k++)
SET_GC_MARK(ca->buckets + *k, GC_MARK_METADATA);
for_each_bucket(b, ca) {
c->need_gc = max(c->need_gc, bucket_gc_gen(b));
@ -1779,7 +1776,6 @@ static void bch_btree_gc_finish(struct cache_set *c)
if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE)
c->avail_nbuckets++;
}
}
mutex_unlock(&c->bucket_lock);
}
@ -1830,10 +1826,8 @@ static void bch_btree_gc(struct cache_set *c)
static bool gc_should_run(struct cache_set *c)
{
struct cache *ca;
unsigned int i;
struct cache *ca = c->cache;
for_each_cache(ca, c, i)
if (ca->invalidate_needs_gc)
return true;
@ -2081,9 +2075,8 @@ int bch_btree_check(struct cache_set *c)
void bch_initial_gc_finish(struct cache_set *c)
{
struct cache *ca;
struct cache *ca = c->cache;
struct bucket *b;
unsigned int i;
bch_btree_gc_finish(c);
@ -2098,7 +2091,6 @@ void bch_initial_gc_finish(struct cache_set *c)
* This is only safe for buckets that have no live data in them, which
* there should always be some of.
*/
for_each_cache(ca, c, i) {
for_each_bucket(b, ca) {
if (fifo_full(&ca->free[RESERVE_PRIO]) &&
fifo_full(&ca->free[RESERVE_BTREE]))
@ -2113,7 +2105,6 @@ void bch_initial_gc_finish(struct cache_set *c)
b - ca->buckets);
}
}
}
mutex_unlock(&c->bucket_lock);
}

View File

@ -179,11 +179,8 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
ret; \
})
struct cache *ca;
unsigned int iter;
struct cache *ca = c->cache;
int ret = 0;
for_each_cache(ca, c, iter) {
struct journal_device *ja = &ca->journal;
DECLARE_BITMAP(bitmap, SB_JOURNAL_BUCKETS);
unsigned int i, l, r, m;
@ -223,7 +220,7 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
/* no journal entries on this device? */
if (l == ca->sb.njournal_buckets)
continue;
goto out;
bsearch:
BUG_ON(list_empty(list));
@ -283,8 +280,8 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
ca->sb.njournal_buckets;
}
}
out:
if (!list_empty(list))
c->journal.seq = list_entry(list->prev,
struct journal_replay,
@ -342,10 +339,8 @@ void bch_journal_mark(struct cache_set *c, struct list_head *list)
static bool is_discard_enabled(struct cache_set *s)
{
struct cache *ca;
unsigned int i;
struct cache *ca = s->cache;
for_each_cache(ca, s, i)
if (ca->discard)
return true;
@ -633,9 +628,10 @@ static void do_journal_discard(struct cache *ca)
static void journal_reclaim(struct cache_set *c)
{
struct bkey *k = &c->journal.key;
struct cache *ca;
struct cache *ca = c->cache;
uint64_t last_seq;
unsigned int iter, n = 0;
unsigned int next;
struct journal_device *ja = &ca->journal;
atomic_t p __maybe_unused;
atomic_long_inc(&c->reclaim);
@ -647,46 +643,31 @@ static void journal_reclaim(struct cache_set *c)
/* Update last_idx */
for_each_cache(ca, c, iter) {
struct journal_device *ja = &ca->journal;
while (ja->last_idx != ja->cur_idx &&
ja->seq[ja->last_idx] < last_seq)
ja->last_idx = (ja->last_idx + 1) %
ca->sb.njournal_buckets;
}
for_each_cache(ca, c, iter)
do_journal_discard(ca);
if (c->journal.blocks_free)
goto out;
/*
* Allocate:
* XXX: Sort by free journal space
*/
for_each_cache(ca, c, iter) {
struct journal_device *ja = &ca->journal;
unsigned int next = (ja->cur_idx + 1) % ca->sb.njournal_buckets;
next = (ja->cur_idx + 1) % ca->sb.njournal_buckets;
/* No space available on this device */
if (next == ja->discard_idx)
continue;
goto out;
ja->cur_idx = next;
k->ptr[n++] = MAKE_PTR(0,
k->ptr[0] = MAKE_PTR(0,
bucket_to_sector(c, ca->sb.d[ja->cur_idx]),
ca->sb.nr_this_dev);
atomic_long_inc(&c->reclaimed_journal_buckets);
}
if (n) {
bkey_init(k);
SET_KEY_PTRS(k, n);
SET_KEY_PTRS(k, 1);
c->journal.blocks_free = c->sb.bucket_size >> c->block_bits;
}
out:
if (!journal_full(&c->journal))
__closure_wake_up(&c->journal.wait);
@ -750,7 +731,7 @@ static void journal_write_unlocked(struct closure *cl)
__releases(c->journal.lock)
{
struct cache_set *c = container_of(cl, struct cache_set, journal.io);
struct cache *ca;
struct cache *ca = c->cache;
struct journal_write *w = c->journal.cur;
struct bkey *k = &c->journal.key;
unsigned int i, sectors = set_blocks(w->data, block_bytes(c)) *
@ -780,9 +761,7 @@ static void journal_write_unlocked(struct closure *cl)
bkey_copy(&w->data->btree_root, &c->root->key);
bkey_copy(&w->data->uuid_bucket, &c->uuid_bucket);
for_each_cache(ca, c, i)
w->data->prio_bucket[ca->sb.nr_this_dev] = ca->prio_buckets[0];
w->data->magic = jset_magic(&c->sb);
w->data->version = BCACHE_JSET_VERSION;
w->data->last_seq = last_seq(&c->journal);

View File

@ -196,18 +196,17 @@ static unsigned int bucket_heap_top(struct cache *ca)
void bch_moving_gc(struct cache_set *c)
{
struct cache *ca;
struct cache *ca = c->cache;
struct bucket *b;
unsigned int i;
unsigned long sectors_to_move, reserve_sectors;
if (!c->copy_gc_enabled)
return;
mutex_lock(&c->bucket_lock);
for_each_cache(ca, c, i) {
unsigned long sectors_to_move = 0;
unsigned long reserve_sectors = ca->sb.bucket_size *
sectors_to_move = 0;
reserve_sectors = ca->sb.bucket_size *
fifo_used(&ca->free[RESERVE_MOVINGGC]);
ca->heap.used = 0;
@ -238,7 +237,6 @@ void bch_moving_gc(struct cache_set *c)
while (heap_pop(&ca->heap, b, bucket_cmp))
SET_GC_MOVE(b, 1);
}
mutex_unlock(&c->bucket_lock);

View File

@ -343,8 +343,9 @@ static void bcache_write_super_unlock(struct closure *cl)
void bcache_write_super(struct cache_set *c)
{
struct closure *cl = &c->sb_write;
struct cache *ca;
unsigned int i, version = BCACHE_SB_VERSION_CDEV_WITH_UUID;
struct cache *ca = c->cache;
struct bio *bio = &ca->sb_bio;
unsigned int version = BCACHE_SB_VERSION_CDEV_WITH_UUID;
down(&c->sb_write_mutex);
closure_init(cl, &c->cl);
@ -354,9 +355,6 @@ void bcache_write_super(struct cache_set *c)
if (c->sb.version > version)
version = c->sb.version;
for_each_cache(ca, c, i) {
struct bio *bio = &ca->sb_bio;
ca->sb.version = version;
ca->sb.seq = c->sb.seq;
ca->sb.last_mount = c->sb.last_mount;
@ -370,7 +368,6 @@ void bcache_write_super(struct cache_set *c)
closure_get(cl);
__write_super(&ca->sb, ca->sb_disk, bio);
}
closure_return_with_destructor(cl, bcache_write_super_unlock);
}
@ -772,13 +769,11 @@ static void bcache_device_unlink(struct bcache_device *d)
lockdep_assert_held(&bch_register_lock);
if (d->c && !test_and_set_bit(BCACHE_DEV_UNLINK_DONE, &d->flags)) {
unsigned int i;
struct cache *ca;
struct cache *ca = d->c->cache;
sysfs_remove_link(&d->c->kobj, d->name);
sysfs_remove_link(&d->kobj, "cache");
for_each_cache(ca, d->c, i)
bd_unlink_disk_holder(ca->bdev, d->disk);
}
}
@ -786,11 +781,9 @@ static void bcache_device_unlink(struct bcache_device *d)
static void bcache_device_link(struct bcache_device *d, struct cache_set *c,
const char *name)
{
unsigned int i;
struct cache *ca;
struct cache *ca = c->cache;
int ret;
for_each_cache(ca, d->c, i)
bd_link_disk_holder(ca->bdev, d->disk);
snprintf(d->name, BCACHEDEVNAME_SIZE,
@ -1662,7 +1655,6 @@ static void cache_set_free(struct closure *cl)
{
struct cache_set *c = container_of(cl, struct cache_set, cl);
struct cache *ca;
unsigned int i;
debugfs_remove(c->debug);
@ -1671,7 +1663,7 @@ static void cache_set_free(struct closure *cl)
bch_journal_free(c);
mutex_lock(&bch_register_lock);
for_each_cache(ca, c, i)
ca = c->cache;
if (ca) {
ca->set = NULL;
c->cache = NULL;
@ -1702,9 +1694,8 @@ static void cache_set_free(struct closure *cl)
static void cache_set_flush(struct closure *cl)
{
struct cache_set *c = container_of(cl, struct cache_set, caching);
struct cache *ca;
struct cache *ca = c->cache;
struct btree *b;
unsigned int i;
bch_cache_accounting_destroy(&c->accounting);
@ -1729,7 +1720,6 @@ static void cache_set_flush(struct closure *cl)
mutex_unlock(&b->write_lock);
}
for_each_cache(ca, c, i)
if (ca->alloc_thread)
kthread_stop(ca->alloc_thread);
@ -1972,16 +1962,14 @@ static int run_cache_set(struct cache_set *c)
{
const char *err = "cannot allocate memory";
struct cached_dev *dc, *t;
struct cache *ca;
struct cache *ca = c->cache;
struct closure cl;
unsigned int i;
LIST_HEAD(journal);
struct journal_replay *l;
closure_init_stack(&cl);
for_each_cache(ca, c, i)
c->nbuckets += ca->sb.nbuckets;
c->nbuckets = ca->sb.nbuckets;
set_gc_sectors(c);
if (CACHE_SYNC(&c->sb)) {
@ -2001,10 +1989,8 @@ static int run_cache_set(struct cache_set *c)
j = &list_entry(journal.prev, struct journal_replay, list)->j;
err = "IO error reading priorities";
for_each_cache(ca, c, i) {
if (prio_read(ca, j->prio_bucket[ca->sb.nr_this_dev]))
goto err;
}
/*
* If prio_read() fails it'll call cache_set_error and we'll
@ -2048,7 +2034,6 @@ static int run_cache_set(struct cache_set *c)
bch_journal_next(&c->journal);
err = "error starting allocator thread";
for_each_cache(ca, c, i)
if (bch_cache_allocator_start(ca))
goto err;
@ -2069,27 +2054,22 @@ static int run_cache_set(struct cache_set *c)
if (bch_journal_replay(c, &journal))
goto err;
} else {
pr_notice("invalidating existing data\n");
for_each_cache(ca, c, i) {
unsigned int j;
pr_notice("invalidating existing data\n");
ca->sb.keys = clamp_t(int, ca->sb.nbuckets >> 7,
2, SB_JOURNAL_BUCKETS);
for (j = 0; j < ca->sb.keys; j++)
ca->sb.d[j] = ca->sb.first_bucket + j;
}
bch_initial_gc_finish(c);
err = "error starting allocator thread";
for_each_cache(ca, c, i)
if (bch_cache_allocator_start(ca))
goto err;
mutex_lock(&c->bucket_lock);
for_each_cache(ca, c, i)
bch_prio_write(ca, true);
mutex_unlock(&c->bucket_lock);
@ -2465,13 +2445,14 @@ static bool bch_is_open_backing(struct block_device *bdev)
static bool bch_is_open_cache(struct block_device *bdev)
{
struct cache_set *c, *tc;
struct cache *ca;
unsigned int i;
list_for_each_entry_safe(c, tc, &bch_cache_sets, list)
for_each_cache(ca, c, i)
list_for_each_entry_safe(c, tc, &bch_cache_sets, list) {
struct cache *ca = c->cache;
if (ca->bdev == bdev)
return true;
}
return false;
}