summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-09-01 16:37:23 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-09-08 19:07:20 -0800
commitf5a6dac229214474b886c78392fc39c9533fc0db (patch)
tree3cc4458d7095cee70b72e71b63538c7f9c90edc2
parentfbd8713814bbfe2f97ea47ab6622dcc877f24c94 (diff)
bcache: plumb nr_replicas through disk_reservations
-rw-r--r--drivers/md/bcache/btree_update.c8
-rw-r--r--drivers/md/bcache/buckets.c7
-rw-r--r--drivers/md/bcache/buckets.h1
-rw-r--r--drivers/md/bcache/buckets_types.h3
-rw-r--r--drivers/md/bcache/fs-io.c12
-rw-r--r--drivers/md/bcache/io.c85
-rw-r--r--drivers/md/bcache/io.h4
-rw-r--r--drivers/md/bcache/request.c67
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 651f39dd9e96..a9173de44269 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 4193c36763c8..7ec4b627d7d4 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 67c8d3f3d145..cdfd74e3ced6 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.