summaryrefslogtreecommitdiff
path: root/drivers/md/bcache/io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-12-02 20:03:06 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-12-02 20:03:06 -0900
commit50706f36b51a721791124f4d7348252d4d6d3458 (patch)
treedaec72695a0e6c2387d3d88dc04a11940852367c /drivers/md/bcache/io.c
parent548f0f7b68212e51ab9f137313dfa58eb0bdbc64 (diff)
bcache: allow __bch_write() to fragment io more than twice without slowpath loop
Diffstat (limited to 'drivers/md/bcache/io.c')
-rw-r--r--drivers/md/bcache/io.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index 9f32f4817c09..ba2644166c31 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -233,6 +233,7 @@ static int bch_write_index_default(struct bch_write_op *op)
static void bch_write_index(struct closure *cl)
{
struct bch_write_op *op = container_of(cl, struct bch_write_op, cl);
+ struct cache_set *c = op->c;
struct keylist *keys = &op->insert_keys;
unsigned i;
@@ -247,25 +248,27 @@ static void bch_write_index(struct closure *cl)
op->written += sectors_start - keylist_sectors(keys);
if (ret) {
- __bcache_io_error(op->c, "btree IO error %i", ret);
+ __bcache_io_error(c, "btree IO error %i", ret);
op->error = ret;
}
}
for (i = 0; i < ARRAY_SIZE(op->open_buckets); i++)
if (op->open_buckets[i]) {
- bch_open_bucket_put(op->c, op->open_buckets[i]);
- op->open_buckets[i] = NULL;
+ bch_open_bucket_put(c,
+ c->open_buckets +
+ op->open_buckets[i]);
+ op->open_buckets[i] = 0;
}
if (!(op->flags & BCH_WRITE_DONE))
continue_at(cl, __bch_write, op->io_wq);
if (!op->error && (op->flags & BCH_WRITE_FLUSH)) {
- bch_journal_flush_seq_async(&op->c->journal,
+ bch_journal_flush_seq_async(&c->journal,
*op_journal_seq(op),
cl);
- continue_at(cl, bch_write_done, op->c->wq);
+ continue_at(cl, bch_write_done, c->wq);
} else {
continue_at_nobarrier(cl, bch_write_done, NULL);
}
@@ -520,6 +523,7 @@ static int bch_write_extent(struct bch_write_op *op,
static void __bch_write(struct closure *cl)
{
struct bch_write_op *op = container_of(cl, struct bch_write_op, cl);
+ struct cache_set *c = op->c;
struct bio *bio = &op->bio->bio;
unsigned open_bucket_nr = 0;
struct open_bucket *b;
@@ -531,7 +535,7 @@ static void __bch_write(struct closure *cl)
op->flags |= BCH_WRITE_DONE;
bch_write_discard(cl);
bio_put(bio);
- continue_at(cl, bch_write_done, op->c->wq);
+ continue_at(cl, bch_write_done, c->wq);
}
/*
@@ -547,14 +551,14 @@ static void __bch_write(struct closure *cl)
EBUG_ON(!bio_sectors(bio));
if (open_bucket_nr == ARRAY_SIZE(op->open_buckets))
- continue_at(cl, bch_write_index, op->c->wq);
+ continue_at(cl, bch_write_index, c->wq);
/* for the device pointers and 1 for the chksum */
if (bch_keylist_realloc(&op->insert_keys,
op->inline_keys,
ARRAY_SIZE(op->inline_keys),
BKEY_EXTENT_U64s_MAX))
- continue_at(cl, bch_write_index, op->c->wq);
+ continue_at(cl, bch_write_index, c->wq);
k = op->insert_keys.top;
bkey_extent_init(k);
@@ -564,7 +568,7 @@ static void __bch_write(struct closure *cl)
? op->size
: bio_sectors(bio));
- b = bch_alloc_sectors_start(op->c, op->wp,
+ b = bch_alloc_sectors_start(c, op->wp,
bkey_i_to_extent(k), op->nr_replicas,
op->alloc_reserve,
(op->flags & BCH_WRITE_ALLOC_NOWAIT) ? NULL : cl);
@@ -582,7 +586,7 @@ static void __bch_write(struct closure *cl)
* this case if open_bucket_nr > 1.
*/
if (!bch_keylist_empty(&op->insert_keys))
- continue_at(cl, bch_write_index, op->c->wq);
+ continue_at(cl, bch_write_index, c->wq);
/*
* If we've looped, we're running out of a workqueue -
@@ -604,7 +608,9 @@ static void __bch_write(struct closure *cl)
continue;
}
- op->open_buckets[open_bucket_nr++] = b;
+ BUG_ON(b - c->open_buckets == 0 ||
+ b - c->open_buckets > U8_MAX);
+ op->open_buckets[open_bucket_nr++] = b - c->open_buckets;
ret = bch_write_extent(op, b, bkey_i_to_extent(k), bio);
if (ret < 0)
@@ -615,7 +621,7 @@ static void __bch_write(struct closure *cl)
bkey_extent_set_cached(&k->k, (op->flags & BCH_WRITE_CACHED));
if (!(op->flags & BCH_WRITE_CACHED))
- bch_check_mark_super(op->c, k, false);
+ bch_check_mark_super(c, k, false);
bch_keylist_push(&op->insert_keys);
@@ -623,7 +629,7 @@ static void __bch_write(struct closure *cl)
} while (ret);
op->flags |= BCH_WRITE_DONE;
- continue_at(cl, bch_write_index, op->c->wq);
+ continue_at(cl, bch_write_index, c->wq);
err:
if (op->flags & BCH_WRITE_DISCARD_ON_ERROR) {
/*
@@ -655,7 +661,7 @@ err:
*/
continue_at(cl, !bch_keylist_empty(&op->insert_keys)
? bch_write_index
- : bch_write_done, op->c->wq);
+ : bch_write_done, c->wq);
}
void bch_wake_delayed_writes(unsigned long data)