diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-09-01 16:37:23 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:37:01 -0800 |
commit | 46bdb04a8911a9e48832710a8d010771986f840c (patch) | |
tree | cf9ada249fcb03724167ab94281f8163b9c57a33 | |
parent | dc161349a05ea80768a29662fcfafd6d06b4877b (diff) |
bcache: plumb nr_replicas through disk_reservations
-rw-r--r-- | drivers/md/bcache/btree_update.c | 8 | ||||
-rw-r--r-- | drivers/md/bcache/buckets.c | 7 | ||||
-rw-r--r-- | drivers/md/bcache/buckets.h | 1 | ||||
-rw-r--r-- | drivers/md/bcache/buckets_types.h | 3 | ||||
-rw-r--r-- | drivers/md/bcache/fs-io.c | 12 | ||||
-rw-r--r-- | drivers/md/bcache/io.c | 85 | ||||
-rw-r--r-- | drivers/md/bcache/io.h | 4 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 67 |
8 files changed, 94 insertions, 93 deletions
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index 32a3915fd118..48e062b7acbc 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -238,6 +238,7 @@ void btree_open_bucket_put(struct cache_set *c, struct btree *b) } static struct btree *__bch_btree_node_alloc(struct cache_set *c, + struct disk_reservation *res, struct closure *cl) { BKEY_PADDED(k) tmp; @@ -263,7 +264,7 @@ retry: ob = bch_alloc_sectors(c, &c->btree_write_point, bkey_i_to_extent(&tmp.k), - c->opts.metadata_replicas, cl); + res->nr_replicas, cl); if (IS_ERR(ob)) return ERR_CAST(ob); @@ -518,7 +519,8 @@ static struct btree_reserve *__bch_btree_reserve_get(struct cache_set *c, struct btree *b; struct disk_reservation disk_res = { 0, 0 }; unsigned sectors = nr_nodes * c->sb.btree_node_size; - int ret, flags = BCH_DISK_RESERVATION_GC_LOCK_HELD; + int ret, flags = BCH_DISK_RESERVATION_GC_LOCK_HELD| + BCH_DISK_RESERVATION_METADATA; if (!check_enospc) flags |= BCH_DISK_RESERVATION_NOFAIL; @@ -544,7 +546,7 @@ static struct btree_reserve *__bch_btree_reserve_get(struct cache_set *c, reserve->nr = 0; while (reserve->nr < nr_nodes) { - b = __bch_btree_node_alloc(c, cl); + b = __bch_btree_node_alloc(c, &disk_res, cl); if (IS_ERR(b)) { ret = PTR_ERR(b); goto err_free; diff --git a/drivers/md/bcache/buckets.c b/drivers/md/bcache/buckets.c index e45f128d1635..3fa40106c783 100644 --- a/drivers/md/bcache/buckets.c +++ b/drivers/md/bcache/buckets.c @@ -192,7 +192,7 @@ void bch_cache_set_stats_apply(struct cache_set *c, * Not allowed to reduce sectors_available except by getting a * reservation: */ - BUG_ON(added > (disk_res ? disk_res->sectors : 0)); + BUG_ON(added > (s64) (disk_res ? disk_res->sectors : 0)); if (added > 0) { disk_res->sectors -= added; @@ -639,6 +639,8 @@ int bch_disk_reservation_add(struct cache_set *c, s64 sectors_available; int ret; + sectors *= res->nr_replicas; + lg_local_lock(&c->bucket_stats_lock); stats = this_cpu_ptr(c->bucket_stats_percpu); @@ -704,6 +706,9 @@ int bch_disk_reservation_get(struct cache_set *c, { res->sectors = 0; res->gen = c->capacity_gen; + res->nr_replicas = (flags & BCH_DISK_RESERVATION_METADATA) + ? c->opts.metadata_replicas + : c->opts.data_replicas; return bch_disk_reservation_add(c, res, sectors, flags); } diff --git a/drivers/md/bcache/buckets.h b/drivers/md/bcache/buckets.h index c96a398ca7bc..da077a3fe5a6 100644 --- a/drivers/md/bcache/buckets.h +++ b/drivers/md/bcache/buckets.h @@ -256,6 +256,7 @@ void bch_disk_reservation_put(struct cache_set *, #define BCH_DISK_RESERVATION_NOFAIL (1 << 0) #define BCH_DISK_RESERVATION_GC_LOCK_HELD (1 << 1) +#define BCH_DISK_RESERVATION_METADATA (1 << 2) int bch_disk_reservation_add(struct cache_set *, struct disk_reservation *, diff --git a/drivers/md/bcache/buckets_types.h b/drivers/md/bcache/buckets_types.h index 256f6fe7f272..7712ff2b6d1a 100644 --- a/drivers/md/bcache/buckets_types.h +++ b/drivers/md/bcache/buckets_types.h @@ -73,8 +73,9 @@ struct bucket_heap_entry { * A reservation for space on disk: */ struct disk_reservation { - u32 sectors; + u64 sectors; u32 gen; + unsigned nr_replicas; }; #endif /* _BUCKETS_TYPES_H */ diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c index d12d1c2e6e2e..6062da0a8622 100644 --- a/drivers/md/bcache/fs-io.c +++ b/drivers/md/bcache/fs-io.c @@ -856,7 +856,10 @@ alloc_io: w->io->op.sectors_added = 0; w->io->op.is_dio = false; bch_write_op_init(&w->io->op.op, w->c, &w->io->bio, - (struct disk_reservation) { 0 }, NULL, + (struct disk_reservation) { + .nr_replicas = w->c->opts.data_replicas, + }, + NULL, bkey_to_s_c(&KEY(w->inum, 0, 0)), NULL, &ei->journal_seq, 0); w->io->op.op.index_update_fn = bchfs_write_index_update; @@ -1305,10 +1308,8 @@ static void bch_do_direct_IO_write(struct dio_write *dio) dio->iop.is_dio = true; dio->iop.new_i_size = U64_MAX; bch_write_op_init(&dio->iop.op, dio->c, &dio->bio, - (struct disk_reservation) { - .sectors = bio_sectors(bio), - .gen = dio->res.gen - }, NULL, + dio->res, + NULL, bkey_to_s_c(&KEY(inode->i_ino, bio_end_sector(bio), bio_sectors(bio))), @@ -1316,6 +1317,7 @@ static void bch_do_direct_IO_write(struct dio_write *dio) dio->iop.op.index_update_fn = bchfs_write_index_update; dio->res.sectors -= bio_sectors(bio); + dio->iop.op.res.sectors = bio_sectors(bio); task_io_account_write(bio->bi_iter.bi_size); diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c index 9e4dae1c95d6..8b560c0ff5a7 100644 --- a/drivers/md/bcache/io.c +++ b/drivers/md/bcache/io.c @@ -1163,16 +1163,6 @@ void bch_write(struct closure *cl) closure_return(cl); } - if (version_stress_test(c)) - op->insert_key.k.version = bch_rand_range(UINT_MAX); - - /* - * This ought to be initialized in bch_write_op_init(), but struct - * cache_set isn't exported - */ - if (!op->io_wq) - op->io_wq = op->c->wq; - if (!(op->flags & BCH_WRITE_DISCARD)) bch_increment_clock(c, bio_sectors(bio), WRITE); @@ -1239,13 +1229,13 @@ void bch_write_op_init(struct bch_write_op *op, struct cache_set *c, } op->c = c; - op->io_wq = NULL; + op->io_wq = op->c->wq; op->bio = bio; op->written = 0; op->error = 0; op->flags = flags; op->compression_type = c->opts.compression; - op->nr_replicas = c->opts.data_replicas; + op->nr_replicas = res.nr_replicas; op->res = res; op->wp = wp; @@ -1275,6 +1265,9 @@ void bch_write_op_init(struct bch_write_op *op, struct cache_set *c, (op->flags & BCH_WRITE_CACHED) ? BCH_EXTENT_CACHED : BCH_EXTENT; } + + if (version_stress_test(c)) + op->insert_key.k.version = bch_rand_range(UINT_MAX); } void bch_replace_init(struct bch_replace_info *r, struct bkey_s_c old) @@ -1320,73 +1313,6 @@ struct cache_promote_op { struct bch_write_bio bio; /* must be last */ }; -/** - * __cache_promote -- insert result of read bio into cache - * - * Used for backing devices and flash-only volumes. - * - * @orig_bio must actually be a bbio with a valid key. - */ -void __cache_promote(struct cache_set *c, struct bbio *orig_bio, - struct bkey_s_c old, - struct bkey_s_c new, - unsigned write_flags) -{ -#if 0 - struct cache_promote_op *op; - struct bio *bio; - unsigned pages = DIV_ROUND_UP(orig_bio->bio.bi_iter.bi_size, PAGE_SIZE); - - /* XXX: readahead? */ - - op = kmalloc(sizeof(*op) + sizeof(struct bio_vec) * pages, GFP_NOIO); - if (!op) - goto out_submit; - - /* clone the bbio */ - memcpy(&op->bio, orig_bio, offsetof(struct bbio, bio)); - - bio = &op->bio.bio.bio; - bio_init(bio); - bio_get(bio); - bio->bi_bdev = orig_bio->bio.bi_bdev; - bio->bi_iter.bi_sector = orig_bio->bio.bi_iter.bi_sector; - bio->bi_iter.bi_size = orig_bio->bio.bi_iter.bi_size; - bio->bi_end_io = cache_promote_endio; - bio->bi_private = &op->cl; - bio->bi_io_vec = bio->bi_inline_vecs; - bch_bio_map(bio, NULL); - - if (bio_alloc_pages(bio, __GFP_NOWARN|GFP_NOIO)) - goto out_free; - - orig_bio->ca = NULL; - - closure_init(&op->cl, &c->cl); - op->orig_bio = &orig_bio->bio; - op->stale = 0; - - bch_write_op_init(&op->iop, c, &op->bio, &c->promote_write_point, - new, old, - BCH_WRITE_ALLOC_NOWAIT|write_flags); - op->iop.nr_replicas = 1; - - //bch_cut_front(bkey_start_pos(&orig_bio->key.k), &op->iop.insert_key); - //bch_cut_back(orig_bio->key.k.p, &op->iop.insert_key.k); - - trace_bcache_promote(&orig_bio->bio); - - op->bio.bio.submit_time_us = local_clock_us(); - closure_bio_submit(bio, &op->cl); - - continue_at(&op->cl, cache_promote_write, c->wq); -out_free: - kfree(op); -out_submit: - generic_make_request(&orig_bio->bio); -#endif -} - /* Read */ static int bio_checksum_uncompress(struct cache_set *c, @@ -1715,6 +1641,7 @@ void bch_read_extent_iter(struct cache_set *c, struct bch_read_bio *orig, &c->promote_write_point, k, &promote_op->replace.hook, NULL, BCH_WRITE_ALLOC_NOWAIT); + promote_op->iop.nr_replicas = 1; if (rbio->crc.compression_type) { promote_op->iop.flags |= BCH_WRITE_DATA_COMPRESSED; diff --git a/drivers/md/bcache/io.h b/drivers/md/bcache/io.h index b37d9845b17e..50172477fcb8 100644 --- a/drivers/md/bcache/io.h +++ b/drivers/md/bcache/io.h @@ -89,10 +89,6 @@ int bch_discard(struct cache_set *, struct bpos, struct bpos, u64, struct disk_reservation *, struct extent_insert_hook *, u64 *); -void __cache_promote(struct cache_set *, struct bbio *, - struct bkey_s_c, struct bkey_s_c, unsigned); -bool cache_promote(struct cache_set *, struct bbio *, struct bkey_s_c); - void bch_read_retry_work(struct work_struct *); void bch_wake_delayed_writes(unsigned long data); diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index dc3fa5477d6c..fc760de6d997 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -325,6 +325,73 @@ static void cached_dev_read_done_bh(struct closure *cl) } /** + * __cache_promote -- insert result of read bio into cache + * + * Used for backing devices and flash-only volumes. + * + * @orig_bio must actually be a bbio with a valid key. + */ +void __cache_promote(struct cache_set *c, struct bbio *orig_bio, + struct bkey_s_c old, + struct bkey_s_c new, + unsigned write_flags) +{ +#if 0 + struct cache_promote_op *op; + struct bio *bio; + unsigned pages = DIV_ROUND_UP(orig_bio->bio.bi_iter.bi_size, PAGE_SIZE); + + /* XXX: readahead? */ + + op = kmalloc(sizeof(*op) + sizeof(struct bio_vec) * pages, GFP_NOIO); + if (!op) + goto out_submit; + + /* clone the bbio */ + memcpy(&op->bio, orig_bio, offsetof(struct bbio, bio)); + + bio = &op->bio.bio.bio; + bio_init(bio); + bio_get(bio); + bio->bi_bdev = orig_bio->bio.bi_bdev; + bio->bi_iter.bi_sector = orig_bio->bio.bi_iter.bi_sector; + bio->bi_iter.bi_size = orig_bio->bio.bi_iter.bi_size; + bio->bi_end_io = cache_promote_endio; + bio->bi_private = &op->cl; + bio->bi_io_vec = bio->bi_inline_vecs; + bch_bio_map(bio, NULL); + + if (bio_alloc_pages(bio, __GFP_NOWARN|GFP_NOIO)) + goto out_free; + + orig_bio->ca = NULL; + + closure_init(&op->cl, &c->cl); + op->orig_bio = &orig_bio->bio; + op->stale = 0; + + bch_write_op_init(&op->iop, c, &op->bio, &c->promote_write_point, + new, old, + BCH_WRITE_ALLOC_NOWAIT|write_flags); + op->iop.nr_replicas = 1; + + //bch_cut_front(bkey_start_pos(&orig_bio->key.k), &op->iop.insert_key); + //bch_cut_back(orig_bio->key.k.p, &op->iop.insert_key.k); + + trace_bcache_promote(&orig_bio->bio); + + op->bio.bio.submit_time_us = local_clock_us(); + closure_bio_submit(bio, &op->cl); + + continue_at(&op->cl, cache_promote_write, c->wq); +out_free: + kfree(op); +out_submit: + generic_make_request(&orig_bio->bio); +#endif +} + +/** * cached_dev_cache_miss - populate cache with data from backing device * * We don't write to the cache if s->bypass is set. |