diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-10-24 20:07:04 -0400 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2013-11-11 00:56:02 -0500 |
commit | a34a8bfd4e6358c646928320d37b0425c0762f8a (patch) | |
tree | 650dd57be0460f439551baca3514009b4287bb12 /drivers/md | |
parent | cdd972b164be8fc69f6ee8533c5a07b621da74c7 (diff) |
bcache: Refactor journalling flow control
Making things less asynchronous that don't need to be - bch_journal()
only has to block when the journal or journal entry is full, which is
emphatically not a fast path. So make it a normal function that just
returns when it finishes, to make the code and control flow easier to
follow.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bcache/btree.c | 3 | ||||
-rw-r--r-- | drivers/md/bcache/closure.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 213 | ||||
-rw-r--r-- | drivers/md/bcache/journal.h | 3 | ||||
-rw-r--r-- | drivers/md/bcache/movinggc.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 160 | ||||
-rw-r--r-- | drivers/md/bcache/request.h | 3 |
7 files changed, 207 insertions, 179 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index f960607f1f25..777c01d67ef0 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -2164,9 +2164,6 @@ int bch_btree_insert(struct btree_op *op, struct cache_set *c, | |||
2164 | } | 2164 | } |
2165 | } | 2165 | } |
2166 | 2166 | ||
2167 | if (op->journal) | ||
2168 | atomic_dec_bug(op->journal); | ||
2169 | op->journal = NULL; | ||
2170 | return ret; | 2167 | return ret; |
2171 | } | 2168 | } |
2172 | 2169 | ||
diff --git a/drivers/md/bcache/closure.h b/drivers/md/bcache/closure.h index 00039924ea9d..ab011f03801f 100644 --- a/drivers/md/bcache/closure.h +++ b/drivers/md/bcache/closure.h | |||
@@ -642,7 +642,7 @@ do { \ | |||
642 | #define continue_at_nobarrier(_cl, _fn, _wq) \ | 642 | #define continue_at_nobarrier(_cl, _fn, _wq) \ |
643 | do { \ | 643 | do { \ |
644 | set_closure_fn(_cl, _fn, _wq); \ | 644 | set_closure_fn(_cl, _fn, _wq); \ |
645 | closure_queue(cl); \ | 645 | closure_queue(_cl); \ |
646 | return; \ | 646 | return; \ |
647 | } while (0) | 647 | } while (0) |
648 | 648 | ||
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index 1bdefdb1fa71..940e89e0d706 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c | |||
@@ -318,7 +318,6 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list, | |||
318 | bch_keylist_push(&op->keys); | 318 | bch_keylist_push(&op->keys); |
319 | 319 | ||
320 | op->journal = i->pin; | 320 | op->journal = i->pin; |
321 | atomic_inc(op->journal); | ||
322 | 321 | ||
323 | ret = bch_btree_insert(op, s, &op->keys); | 322 | ret = bch_btree_insert(op, s, &op->keys); |
324 | if (ret) | 323 | if (ret) |
@@ -357,48 +356,35 @@ static void btree_flush_write(struct cache_set *c) | |||
357 | * Try to find the btree node with that references the oldest journal | 356 | * Try to find the btree node with that references the oldest journal |
358 | * entry, best is our current candidate and is locked if non NULL: | 357 | * entry, best is our current candidate and is locked if non NULL: |
359 | */ | 358 | */ |
360 | struct btree *b, *best = NULL; | 359 | struct btree *b, *best; |
361 | unsigned iter; | 360 | unsigned i; |
361 | retry: | ||
362 | best = NULL; | ||
363 | |||
364 | for_each_cached_btree(b, c, i) | ||
365 | if (btree_current_write(b)->journal) { | ||
366 | if (!best) | ||
367 | best = b; | ||
368 | else if (journal_pin_cmp(c, | ||
369 | btree_current_write(best), | ||
370 | btree_current_write(b))) { | ||
371 | best = b; | ||
372 | } | ||
373 | } | ||
362 | 374 | ||
363 | for_each_cached_btree(b, c, iter) { | 375 | b = best; |
364 | if (!down_write_trylock(&b->lock)) | 376 | if (b) { |
365 | continue; | 377 | rw_lock(true, b, b->level); |
366 | 378 | ||
367 | if (!btree_node_dirty(b) || | 379 | if (!btree_current_write(b)->journal) { |
368 | !btree_current_write(b)->journal) { | ||
369 | rw_unlock(true, b); | 380 | rw_unlock(true, b); |
370 | continue; | 381 | /* We raced */ |
382 | goto retry; | ||
371 | } | 383 | } |
372 | 384 | ||
373 | if (!best) | 385 | bch_btree_node_write(b, NULL); |
374 | best = b; | 386 | rw_unlock(true, b); |
375 | else if (journal_pin_cmp(c, | ||
376 | btree_current_write(best), | ||
377 | btree_current_write(b))) { | ||
378 | rw_unlock(true, best); | ||
379 | best = b; | ||
380 | } else | ||
381 | rw_unlock(true, b); | ||
382 | } | 387 | } |
383 | |||
384 | if (best) | ||
385 | goto out; | ||
386 | |||
387 | /* We can't find the best btree node, just pick the first */ | ||
388 | list_for_each_entry(b, &c->btree_cache, list) | ||
389 | if (!b->level && btree_node_dirty(b)) { | ||
390 | best = b; | ||
391 | rw_lock(true, best, best->level); | ||
392 | goto found; | ||
393 | } | ||
394 | |||
395 | out: | ||
396 | if (!best) | ||
397 | return; | ||
398 | found: | ||
399 | if (btree_node_dirty(best)) | ||
400 | bch_btree_node_write(best, NULL); | ||
401 | rw_unlock(true, best); | ||
402 | } | 388 | } |
403 | 389 | ||
404 | #define last_seq(j) ((j)->seq - fifo_used(&(j)->pin) + 1) | 390 | #define last_seq(j) ((j)->seq - fifo_used(&(j)->pin) + 1) |
@@ -494,7 +480,7 @@ static void journal_reclaim(struct cache_set *c) | |||
494 | do_journal_discard(ca); | 480 | do_journal_discard(ca); |
495 | 481 | ||
496 | if (c->journal.blocks_free) | 482 | if (c->journal.blocks_free) |
497 | return; | 483 | goto out; |
498 | 484 | ||
499 | /* | 485 | /* |
500 | * Allocate: | 486 | * Allocate: |
@@ -520,7 +506,7 @@ static void journal_reclaim(struct cache_set *c) | |||
520 | 506 | ||
521 | if (n) | 507 | if (n) |
522 | c->journal.blocks_free = c->sb.bucket_size >> c->block_bits; | 508 | c->journal.blocks_free = c->sb.bucket_size >> c->block_bits; |
523 | 509 | out: | |
524 | if (!journal_full(&c->journal)) | 510 | if (!journal_full(&c->journal)) |
525 | __closure_wake_up(&c->journal.wait); | 511 | __closure_wake_up(&c->journal.wait); |
526 | } | 512 | } |
@@ -659,7 +645,7 @@ static void journal_write(struct closure *cl) | |||
659 | journal_write_unlocked(cl); | 645 | journal_write_unlocked(cl); |
660 | } | 646 | } |
661 | 647 | ||
662 | static void __journal_try_write(struct cache_set *c, bool noflush) | 648 | static void journal_try_write(struct cache_set *c) |
663 | __releases(c->journal.lock) | 649 | __releases(c->journal.lock) |
664 | { | 650 | { |
665 | struct closure *cl = &c->journal.io; | 651 | struct closure *cl = &c->journal.io; |
@@ -667,29 +653,59 @@ static void __journal_try_write(struct cache_set *c, bool noflush) | |||
667 | 653 | ||
668 | w->need_write = true; | 654 | w->need_write = true; |
669 | 655 | ||
670 | if (!closure_trylock(cl, &c->cl)) | 656 | if (closure_trylock(cl, &c->cl)) |
671 | spin_unlock(&c->journal.lock); | ||
672 | else if (noflush && journal_full(&c->journal)) { | ||
673 | spin_unlock(&c->journal.lock); | ||
674 | continue_at(cl, journal_write, system_wq); | ||
675 | } else | ||
676 | journal_write_unlocked(cl); | 657 | journal_write_unlocked(cl); |
658 | else | ||
659 | spin_unlock(&c->journal.lock); | ||
677 | } | 660 | } |
678 | 661 | ||
679 | #define journal_try_write(c) __journal_try_write(c, false) | 662 | static struct journal_write *journal_wait_for_write(struct cache_set *c, |
680 | 663 | unsigned nkeys) | |
681 | void bch_journal_meta(struct cache_set *c, struct closure *cl) | ||
682 | { | 664 | { |
683 | struct journal_write *w; | 665 | size_t sectors; |
666 | struct closure cl; | ||
684 | 667 | ||
685 | if (CACHE_SYNC(&c->sb)) { | 668 | closure_init_stack(&cl); |
686 | spin_lock(&c->journal.lock); | 669 | |
687 | w = c->journal.cur; | 670 | spin_lock(&c->journal.lock); |
671 | |||
672 | while (1) { | ||
673 | struct journal_write *w = c->journal.cur; | ||
674 | |||
675 | sectors = __set_blocks(w->data, w->data->keys + nkeys, | ||
676 | c) * c->sb.block_size; | ||
677 | |||
678 | if (sectors <= min_t(size_t, | ||
679 | c->journal.blocks_free * c->sb.block_size, | ||
680 | PAGE_SECTORS << JSET_BITS)) | ||
681 | return w; | ||
682 | |||
683 | /* XXX: tracepoint */ | ||
684 | if (!journal_full(&c->journal)) { | ||
685 | trace_bcache_journal_entry_full(c); | ||
686 | |||
687 | /* | ||
688 | * XXX: If we were inserting so many keys that they | ||
689 | * won't fit in an _empty_ journal write, we'll | ||
690 | * deadlock. For now, handle this in | ||
691 | * bch_keylist_realloc() - but something to think about. | ||
692 | */ | ||
693 | BUG_ON(!w->data->keys); | ||
694 | |||
695 | closure_wait(&w->wait, &cl); | ||
696 | journal_try_write(c); /* unlocks */ | ||
697 | } else { | ||
698 | trace_bcache_journal_full(c); | ||
699 | |||
700 | closure_wait(&c->journal.wait, &cl); | ||
701 | journal_reclaim(c); | ||
702 | spin_unlock(&c->journal.lock); | ||
688 | 703 | ||
689 | if (cl) | 704 | btree_flush_write(c); |
690 | BUG_ON(!closure_wait(&w->wait, cl)); | 705 | } |
691 | 706 | ||
692 | __journal_try_write(c, true); | 707 | closure_sync(&cl); |
708 | spin_lock(&c->journal.lock); | ||
693 | } | 709 | } |
694 | } | 710 | } |
695 | 711 | ||
@@ -708,68 +724,26 @@ static void journal_write_work(struct work_struct *work) | |||
708 | * bch_journal() hands those same keys off to btree_insert_async() | 724 | * bch_journal() hands those same keys off to btree_insert_async() |
709 | */ | 725 | */ |
710 | 726 | ||
711 | void bch_journal(struct closure *cl) | 727 | atomic_t *bch_journal(struct cache_set *c, |
728 | struct keylist *keys, | ||
729 | struct closure *parent) | ||
712 | { | 730 | { |
713 | struct btree_op *op = container_of(cl, struct btree_op, cl); | ||
714 | struct cache_set *c = op->c; | ||
715 | struct journal_write *w; | 731 | struct journal_write *w; |
716 | size_t sectors, nkeys; | 732 | atomic_t *ret; |
717 | |||
718 | if (op->type != BTREE_INSERT || | ||
719 | !CACHE_SYNC(&c->sb)) | ||
720 | goto out; | ||
721 | |||
722 | /* | ||
723 | * If we're looping because we errored, might already be waiting on | ||
724 | * another journal write: | ||
725 | */ | ||
726 | while (atomic_read(&cl->parent->remaining) & CLOSURE_WAITING) | ||
727 | closure_sync(cl->parent); | ||
728 | |||
729 | spin_lock(&c->journal.lock); | ||
730 | |||
731 | if (journal_full(&c->journal)) { | ||
732 | trace_bcache_journal_full(c); | ||
733 | |||
734 | closure_wait(&c->journal.wait, cl); | ||
735 | |||
736 | journal_reclaim(c); | ||
737 | spin_unlock(&c->journal.lock); | ||
738 | |||
739 | btree_flush_write(c); | ||
740 | continue_at(cl, bch_journal, bcache_wq); | ||
741 | } | ||
742 | 733 | ||
743 | w = c->journal.cur; | 734 | if (!CACHE_SYNC(&c->sb)) |
744 | nkeys = w->data->keys + bch_keylist_nkeys(&op->keys); | 735 | return NULL; |
745 | sectors = __set_blocks(w->data, nkeys, c) * c->sb.block_size; | ||
746 | 736 | ||
747 | if (sectors > min_t(size_t, | 737 | w = journal_wait_for_write(c, bch_keylist_nkeys(keys)); |
748 | c->journal.blocks_free * c->sb.block_size, | ||
749 | PAGE_SECTORS << JSET_BITS)) { | ||
750 | trace_bcache_journal_entry_full(c); | ||
751 | 738 | ||
752 | /* | 739 | memcpy(end(w->data), keys->keys, bch_keylist_bytes(keys)); |
753 | * XXX: If we were inserting so many keys that they won't fit in | 740 | w->data->keys += bch_keylist_nkeys(keys); |
754 | * an _empty_ journal write, we'll deadlock. For now, handle | ||
755 | * this in bch_keylist_realloc() - but something to think about. | ||
756 | */ | ||
757 | BUG_ON(!w->data->keys); | ||
758 | 741 | ||
759 | BUG_ON(!closure_wait(&w->wait, cl)); | 742 | ret = &fifo_back(&c->journal.pin); |
743 | atomic_inc(ret); | ||
760 | 744 | ||
761 | journal_try_write(c); | 745 | if (parent) { |
762 | continue_at(cl, bch_journal, bcache_wq); | 746 | closure_wait(&w->wait, parent); |
763 | } | ||
764 | |||
765 | memcpy(end(w->data), op->keys.keys, bch_keylist_bytes(&op->keys)); | ||
766 | w->data->keys += bch_keylist_nkeys(&op->keys); | ||
767 | |||
768 | op->journal = &fifo_back(&c->journal.pin); | ||
769 | atomic_inc(op->journal); | ||
770 | |||
771 | if (op->flush_journal) { | ||
772 | closure_wait(&w->wait, cl->parent); | ||
773 | journal_try_write(c); | 747 | journal_try_write(c); |
774 | } else if (!w->need_write) { | 748 | } else if (!w->need_write) { |
775 | schedule_delayed_work(&c->journal.work, | 749 | schedule_delayed_work(&c->journal.work, |
@@ -778,8 +752,21 @@ void bch_journal(struct closure *cl) | |||
778 | } else { | 752 | } else { |
779 | spin_unlock(&c->journal.lock); | 753 | spin_unlock(&c->journal.lock); |
780 | } | 754 | } |
781 | out: | 755 | |
782 | bch_btree_insert_async(cl); | 756 | |
757 | return ret; | ||
758 | } | ||
759 | |||
760 | void bch_journal_meta(struct cache_set *c, struct closure *cl) | ||
761 | { | ||
762 | struct keylist keys; | ||
763 | atomic_t *ref; | ||
764 | |||
765 | bch_keylist_init(&keys); | ||
766 | |||
767 | ref = bch_journal(c, &keys, cl); | ||
768 | if (ref) | ||
769 | atomic_dec_bug(ref); | ||
783 | } | 770 | } |
784 | 771 | ||
785 | void bch_journal_free(struct cache_set *c) | 772 | void bch_journal_free(struct cache_set *c) |
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h index 3ca93d3d566c..7045e6fd2d5a 100644 --- a/drivers/md/bcache/journal.h +++ b/drivers/md/bcache/journal.h | |||
@@ -200,8 +200,9 @@ struct journal_device { | |||
200 | struct closure; | 200 | struct closure; |
201 | struct cache_set; | 201 | struct cache_set; |
202 | struct btree_op; | 202 | struct btree_op; |
203 | struct keylist; | ||
203 | 204 | ||
204 | void bch_journal(struct closure *); | 205 | atomic_t *bch_journal(struct cache_set *, struct keylist *, struct closure *); |
205 | void bch_journal_next(struct journal *); | 206 | void bch_journal_next(struct journal *); |
206 | void bch_journal_mark(struct cache_set *, struct list_head *); | 207 | void bch_journal_mark(struct cache_set *, struct list_head *); |
207 | void bch_journal_meta(struct cache_set *, struct closure *); | 208 | void bch_journal_meta(struct cache_set *, struct closure *); |
diff --git a/drivers/md/bcache/movinggc.c b/drivers/md/bcache/movinggc.c index dd8a035c5ae1..2c42377a65aa 100644 --- a/drivers/md/bcache/movinggc.c +++ b/drivers/md/bcache/movinggc.c | |||
@@ -110,7 +110,7 @@ static void write_moving(struct closure *cl) | |||
110 | bkey_copy(&s->op.replace, &io->w->key); | 110 | bkey_copy(&s->op.replace, &io->w->key); |
111 | 111 | ||
112 | closure_init(&s->op.cl, cl); | 112 | closure_init(&s->op.cl, cl); |
113 | bch_insert_data(&s->op.cl); | 113 | bch_data_insert(&s->op.cl); |
114 | } | 114 | } |
115 | 115 | ||
116 | continue_at(cl, write_moving_finish, bch_gc_wq); | 116 | continue_at(cl, write_moving_finish, bch_gc_wq); |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 3b85f33ae4c7..1c3af44b097b 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -25,6 +25,8 @@ | |||
25 | 25 | ||
26 | struct kmem_cache *bch_search_cache; | 26 | struct kmem_cache *bch_search_cache; |
27 | 27 | ||
28 | static void bch_data_insert_start(struct closure *); | ||
29 | |||
28 | /* Cgroup interface */ | 30 | /* Cgroup interface */ |
29 | 31 | ||
30 | #ifdef CONFIG_CGROUP_BCACHE | 32 | #ifdef CONFIG_CGROUP_BCACHE |
@@ -211,31 +213,42 @@ static void bio_csum(struct bio *bio, struct bkey *k) | |||
211 | 213 | ||
212 | /* Insert data into cache */ | 214 | /* Insert data into cache */ |
213 | 215 | ||
214 | static void bio_invalidate(struct closure *cl) | 216 | static void bch_data_insert_keys(struct closure *cl) |
215 | { | 217 | { |
216 | struct btree_op *op = container_of(cl, struct btree_op, cl); | 218 | struct btree_op *op = container_of(cl, struct btree_op, cl); |
217 | struct bio *bio = op->cache_bio; | 219 | struct search *s = container_of(op, struct search, op); |
218 | 220 | ||
219 | pr_debug("invalidating %i sectors from %llu", | 221 | /* |
220 | bio_sectors(bio), (uint64_t) bio->bi_sector); | 222 | * If we're looping, might already be waiting on |
223 | * another journal write - can't wait on more than one journal write at | ||
224 | * a time | ||
225 | * | ||
226 | * XXX: this looks wrong | ||
227 | */ | ||
228 | #if 0 | ||
229 | while (atomic_read(&s->cl.remaining) & CLOSURE_WAITING) | ||
230 | closure_sync(&s->cl); | ||
231 | #endif | ||
221 | 232 | ||
222 | while (bio_sectors(bio)) { | 233 | if (s->write) |
223 | unsigned len = min(bio_sectors(bio), 1U << 14); | 234 | op->journal = bch_journal(op->c, &op->keys, |
235 | op->flush_journal | ||
236 | ? &s->cl : NULL); | ||
224 | 237 | ||
225 | if (bch_keylist_realloc(&op->keys, 0, op->c)) | 238 | if (bch_btree_insert(op, op->c, &op->keys)) { |
226 | goto out; | 239 | s->error = -ENOMEM; |
240 | op->insert_data_done = true; | ||
241 | } | ||
227 | 242 | ||
228 | bio->bi_sector += len; | 243 | if (op->journal) |
229 | bio->bi_size -= len << 9; | 244 | atomic_dec_bug(op->journal); |
245 | op->journal = NULL; | ||
230 | 246 | ||
231 | bch_keylist_add(&op->keys, | 247 | if (!op->insert_data_done) |
232 | &KEY(op->inode, bio->bi_sector, len)); | 248 | continue_at(cl, bch_data_insert_start, bcache_wq); |
233 | } | ||
234 | 249 | ||
235 | op->insert_data_done = true; | 250 | bch_keylist_free(&op->keys); |
236 | bio_put(bio); | 251 | closure_return(cl); |
237 | out: | ||
238 | continue_at(cl, bch_journal, bcache_wq); | ||
239 | } | 252 | } |
240 | 253 | ||
241 | struct open_bucket { | 254 | struct open_bucket { |
@@ -423,7 +436,34 @@ static bool bch_alloc_sectors(struct bkey *k, unsigned sectors, | |||
423 | return true; | 436 | return true; |
424 | } | 437 | } |
425 | 438 | ||
426 | static void bch_insert_data_error(struct closure *cl) | 439 | static void bch_data_invalidate(struct closure *cl) |
440 | { | ||
441 | struct btree_op *op = container_of(cl, struct btree_op, cl); | ||
442 | struct bio *bio = op->cache_bio; | ||
443 | |||
444 | pr_debug("invalidating %i sectors from %llu", | ||
445 | bio_sectors(bio), (uint64_t) bio->bi_sector); | ||
446 | |||
447 | while (bio_sectors(bio)) { | ||
448 | unsigned len = min(bio_sectors(bio), 1U << 14); | ||
449 | |||
450 | if (bch_keylist_realloc(&op->keys, 0, op->c)) | ||
451 | goto out; | ||
452 | |||
453 | bio->bi_sector += len; | ||
454 | bio->bi_size -= len << 9; | ||
455 | |||
456 | bch_keylist_add(&op->keys, &KEY(op->inode, | ||
457 | bio->bi_sector, len)); | ||
458 | } | ||
459 | |||
460 | op->insert_data_done = true; | ||
461 | bio_put(bio); | ||
462 | out: | ||
463 | continue_at(cl, bch_data_insert_keys, bcache_wq); | ||
464 | } | ||
465 | |||
466 | static void bch_data_insert_error(struct closure *cl) | ||
427 | { | 467 | { |
428 | struct btree_op *op = container_of(cl, struct btree_op, cl); | 468 | struct btree_op *op = container_of(cl, struct btree_op, cl); |
429 | 469 | ||
@@ -450,10 +490,10 @@ static void bch_insert_data_error(struct closure *cl) | |||
450 | 490 | ||
451 | op->keys.top = dst; | 491 | op->keys.top = dst; |
452 | 492 | ||
453 | bch_journal(cl); | 493 | bch_data_insert_keys(cl); |
454 | } | 494 | } |
455 | 495 | ||
456 | static void bch_insert_data_endio(struct bio *bio, int error) | 496 | static void bch_data_insert_endio(struct bio *bio, int error) |
457 | { | 497 | { |
458 | struct closure *cl = bio->bi_private; | 498 | struct closure *cl = bio->bi_private; |
459 | struct btree_op *op = container_of(cl, struct btree_op, cl); | 499 | struct btree_op *op = container_of(cl, struct btree_op, cl); |
@@ -464,7 +504,7 @@ static void bch_insert_data_endio(struct bio *bio, int error) | |||
464 | if (s->writeback) | 504 | if (s->writeback) |
465 | s->error = error; | 505 | s->error = error; |
466 | else if (s->write) | 506 | else if (s->write) |
467 | set_closure_fn(cl, bch_insert_data_error, bcache_wq); | 507 | set_closure_fn(cl, bch_data_insert_error, bcache_wq); |
468 | else | 508 | else |
469 | set_closure_fn(cl, NULL, NULL); | 509 | set_closure_fn(cl, NULL, NULL); |
470 | } | 510 | } |
@@ -472,14 +512,14 @@ static void bch_insert_data_endio(struct bio *bio, int error) | |||
472 | bch_bbio_endio(op->c, bio, error, "writing data to cache"); | 512 | bch_bbio_endio(op->c, bio, error, "writing data to cache"); |
473 | } | 513 | } |
474 | 514 | ||
475 | static void bch_insert_data_loop(struct closure *cl) | 515 | static void bch_data_insert_start(struct closure *cl) |
476 | { | 516 | { |
477 | struct btree_op *op = container_of(cl, struct btree_op, cl); | 517 | struct btree_op *op = container_of(cl, struct btree_op, cl); |
478 | struct search *s = container_of(op, struct search, op); | 518 | struct search *s = container_of(op, struct search, op); |
479 | struct bio *bio = op->cache_bio, *n; | 519 | struct bio *bio = op->cache_bio, *n; |
480 | 520 | ||
481 | if (op->bypass) | 521 | if (op->bypass) |
482 | return bio_invalidate(cl); | 522 | return bch_data_invalidate(cl); |
483 | 523 | ||
484 | if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) { | 524 | if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) { |
485 | set_gc_sectors(op->c); | 525 | set_gc_sectors(op->c); |
@@ -502,7 +542,7 @@ static void bch_insert_data_loop(struct closure *cl) | |||
502 | if (bch_keylist_realloc(&op->keys, | 542 | if (bch_keylist_realloc(&op->keys, |
503 | 1 + (op->csum ? 1 : 0), | 543 | 1 + (op->csum ? 1 : 0), |
504 | op->c)) | 544 | op->c)) |
505 | continue_at(cl, bch_journal, bcache_wq); | 545 | continue_at(cl, bch_data_insert_keys, bcache_wq); |
506 | 546 | ||
507 | k = op->keys.top; | 547 | k = op->keys.top; |
508 | bkey_init(k); | 548 | bkey_init(k); |
@@ -514,7 +554,7 @@ static void bch_insert_data_loop(struct closure *cl) | |||
514 | 554 | ||
515 | n = bch_bio_split(bio, KEY_SIZE(k), GFP_NOIO, split); | 555 | n = bch_bio_split(bio, KEY_SIZE(k), GFP_NOIO, split); |
516 | 556 | ||
517 | n->bi_end_io = bch_insert_data_endio; | 557 | n->bi_end_io = bch_data_insert_endio; |
518 | n->bi_private = cl; | 558 | n->bi_private = cl; |
519 | 559 | ||
520 | if (s->writeback) { | 560 | if (s->writeback) { |
@@ -537,7 +577,7 @@ static void bch_insert_data_loop(struct closure *cl) | |||
537 | } while (n != bio); | 577 | } while (n != bio); |
538 | 578 | ||
539 | op->insert_data_done = true; | 579 | op->insert_data_done = true; |
540 | continue_at(cl, bch_journal, bcache_wq); | 580 | continue_at(cl, bch_data_insert_keys, bcache_wq); |
541 | err: | 581 | err: |
542 | /* bch_alloc_sectors() blocks if s->writeback = true */ | 582 | /* bch_alloc_sectors() blocks if s->writeback = true */ |
543 | BUG_ON(s->writeback); | 583 | BUG_ON(s->writeback); |
@@ -556,7 +596,7 @@ err: | |||
556 | * rest of the write. | 596 | * rest of the write. |
557 | */ | 597 | */ |
558 | op->bypass = true; | 598 | op->bypass = true; |
559 | return bio_invalidate(cl); | 599 | return bch_data_invalidate(cl); |
560 | } else { | 600 | } else { |
561 | /* | 601 | /* |
562 | * From a cache miss, we can just insert the keys for the data | 602 | * From a cache miss, we can just insert the keys for the data |
@@ -566,14 +606,14 @@ err: | |||
566 | bio_put(bio); | 606 | bio_put(bio); |
567 | 607 | ||
568 | if (!bch_keylist_empty(&op->keys)) | 608 | if (!bch_keylist_empty(&op->keys)) |
569 | continue_at(cl, bch_journal, bcache_wq); | 609 | continue_at(cl, bch_data_insert_keys, bcache_wq); |
570 | else | 610 | else |
571 | closure_return(cl); | 611 | closure_return(cl); |
572 | } | 612 | } |
573 | } | 613 | } |
574 | 614 | ||
575 | /** | 615 | /** |
576 | * bch_insert_data - stick some data in the cache | 616 | * bch_data_insert - stick some data in the cache |
577 | * | 617 | * |
578 | * This is the starting point for any data to end up in a cache device; it could | 618 | * This is the starting point for any data to end up in a cache device; it could |
579 | * be from a normal write, or a writeback write, or a write to a flash only | 619 | * be from a normal write, or a writeback write, or a write to a flash only |
@@ -591,30 +631,13 @@ err: | |||
591 | * If op->bypass is true, instead of inserting the data it invalidates the | 631 | * If op->bypass is true, instead of inserting the data it invalidates the |
592 | * region of the cache represented by op->cache_bio and op->inode. | 632 | * region of the cache represented by op->cache_bio and op->inode. |
593 | */ | 633 | */ |
594 | void bch_insert_data(struct closure *cl) | 634 | void bch_data_insert(struct closure *cl) |
595 | { | 635 | { |
596 | struct btree_op *op = container_of(cl, struct btree_op, cl); | 636 | struct btree_op *op = container_of(cl, struct btree_op, cl); |
597 | 637 | ||
598 | bch_keylist_init(&op->keys); | 638 | bch_keylist_init(&op->keys); |
599 | bio_get(op->cache_bio); | 639 | bio_get(op->cache_bio); |
600 | bch_insert_data_loop(cl); | 640 | bch_data_insert_start(cl); |
601 | } | ||
602 | |||
603 | void bch_btree_insert_async(struct closure *cl) | ||
604 | { | ||
605 | struct btree_op *op = container_of(cl, struct btree_op, cl); | ||
606 | struct search *s = container_of(op, struct search, op); | ||
607 | |||
608 | if (bch_btree_insert(op, op->c, &op->keys)) { | ||
609 | s->error = -ENOMEM; | ||
610 | op->insert_data_done = true; | ||
611 | } | ||
612 | |||
613 | if (op->insert_data_done) { | ||
614 | bch_keylist_free(&op->keys); | ||
615 | closure_return(cl); | ||
616 | } else | ||
617 | continue_at(cl, bch_insert_data_loop, bcache_wq); | ||
618 | } | 641 | } |
619 | 642 | ||
620 | /* Common code for the make_request functions */ | 643 | /* Common code for the make_request functions */ |
@@ -969,7 +992,7 @@ static void cached_dev_read_done(struct closure *cl) | |||
969 | if (s->op.cache_bio && | 992 | if (s->op.cache_bio && |
970 | !test_bit(CACHE_SET_STOPPING, &s->op.c->flags)) { | 993 | !test_bit(CACHE_SET_STOPPING, &s->op.c->flags)) { |
971 | s->op.type = BTREE_REPLACE; | 994 | s->op.type = BTREE_REPLACE; |
972 | closure_call(&s->op.cl, bch_insert_data, NULL, cl); | 995 | closure_call(&s->op.cl, bch_data_insert, NULL, cl); |
973 | } | 996 | } |
974 | 997 | ||
975 | continue_at(cl, cached_dev_cache_miss_done, NULL); | 998 | continue_at(cl, cached_dev_cache_miss_done, NULL); |
@@ -1147,13 +1170,13 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s) | |||
1147 | closure_bio_submit(bio, cl, s->d); | 1170 | closure_bio_submit(bio, cl, s->d); |
1148 | } | 1171 | } |
1149 | 1172 | ||
1150 | closure_call(&s->op.cl, bch_insert_data, NULL, cl); | 1173 | closure_call(&s->op.cl, bch_data_insert, NULL, cl); |
1151 | continue_at(cl, cached_dev_write_complete, NULL); | 1174 | continue_at(cl, cached_dev_write_complete, NULL); |
1152 | } | 1175 | } |
1153 | 1176 | ||
1154 | static void cached_dev_nodata(struct cached_dev *dc, struct search *s) | 1177 | static void cached_dev_nodata(struct closure *cl) |
1155 | { | 1178 | { |
1156 | struct closure *cl = &s->cl; | 1179 | struct search *s = container_of(cl, struct search, cl); |
1157 | struct bio *bio = &s->bio.bio; | 1180 | struct bio *bio = &s->bio.bio; |
1158 | 1181 | ||
1159 | if (s->op.flush_journal) | 1182 | if (s->op.flush_journal) |
@@ -1186,9 +1209,15 @@ static void cached_dev_make_request(struct request_queue *q, struct bio *bio) | |||
1186 | s = search_alloc(bio, d); | 1209 | s = search_alloc(bio, d); |
1187 | trace_bcache_request_start(s, bio); | 1210 | trace_bcache_request_start(s, bio); |
1188 | 1211 | ||
1189 | if (!bio->bi_size) | 1212 | if (!bio->bi_size) { |
1190 | cached_dev_nodata(dc, s); | 1213 | /* |
1191 | else { | 1214 | * can't call bch_journal_meta from under |
1215 | * generic_make_request | ||
1216 | */ | ||
1217 | continue_at_nobarrier(&s->cl, | ||
1218 | cached_dev_nodata, | ||
1219 | bcache_wq); | ||
1220 | } else { | ||
1192 | s->op.bypass = check_should_bypass(dc, s); | 1221 | s->op.bypass = check_should_bypass(dc, s); |
1193 | 1222 | ||
1194 | if (rw) | 1223 | if (rw) |
@@ -1275,6 +1304,16 @@ static int flash_dev_cache_miss(struct btree *b, struct search *s, | |||
1275 | return 0; | 1304 | return 0; |
1276 | } | 1305 | } |
1277 | 1306 | ||
1307 | static void flash_dev_nodata(struct closure *cl) | ||
1308 | { | ||
1309 | struct search *s = container_of(cl, struct search, cl); | ||
1310 | |||
1311 | if (s->op.flush_journal) | ||
1312 | bch_journal_meta(s->op.c, cl); | ||
1313 | |||
1314 | continue_at(cl, search_free, NULL); | ||
1315 | } | ||
1316 | |||
1278 | static void flash_dev_make_request(struct request_queue *q, struct bio *bio) | 1317 | static void flash_dev_make_request(struct request_queue *q, struct bio *bio) |
1279 | { | 1318 | { |
1280 | struct search *s; | 1319 | struct search *s; |
@@ -1294,8 +1333,13 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio) | |||
1294 | trace_bcache_request_start(s, bio); | 1333 | trace_bcache_request_start(s, bio); |
1295 | 1334 | ||
1296 | if (!bio->bi_size) { | 1335 | if (!bio->bi_size) { |
1297 | if (s->op.flush_journal) | 1336 | /* |
1298 | bch_journal_meta(s->op.c, cl); | 1337 | * can't call bch_journal_meta from under |
1338 | * generic_make_request | ||
1339 | */ | ||
1340 | continue_at_nobarrier(&s->cl, | ||
1341 | flash_dev_nodata, | ||
1342 | bcache_wq); | ||
1299 | } else if (rw) { | 1343 | } else if (rw) { |
1300 | bch_keybuf_check_overlapping(&s->op.c->moving_gc_keys, | 1344 | bch_keybuf_check_overlapping(&s->op.c->moving_gc_keys, |
1301 | &KEY(d->id, bio->bi_sector, 0), | 1345 | &KEY(d->id, bio->bi_sector, 0), |
@@ -1305,7 +1349,7 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio) | |||
1305 | s->writeback = true; | 1349 | s->writeback = true; |
1306 | s->op.cache_bio = bio; | 1350 | s->op.cache_bio = bio; |
1307 | 1351 | ||
1308 | closure_call(&s->op.cl, bch_insert_data, NULL, cl); | 1352 | closure_call(&s->op.cl, bch_data_insert, NULL, cl); |
1309 | } else { | 1353 | } else { |
1310 | closure_call(&s->op.cl, btree_read_async, NULL, cl); | 1354 | closure_call(&s->op.cl, btree_read_async, NULL, cl); |
1311 | } | 1355 | } |
diff --git a/drivers/md/bcache/request.h b/drivers/md/bcache/request.h index 57dc4784f4f4..1f1b59d38db5 100644 --- a/drivers/md/bcache/request.h +++ b/drivers/md/bcache/request.h | |||
@@ -31,8 +31,7 @@ struct search { | |||
31 | 31 | ||
32 | void bch_cache_read_endio(struct bio *, int); | 32 | void bch_cache_read_endio(struct bio *, int); |
33 | unsigned bch_get_congested(struct cache_set *); | 33 | unsigned bch_get_congested(struct cache_set *); |
34 | void bch_insert_data(struct closure *cl); | 34 | void bch_data_insert(struct closure *cl); |
35 | void bch_btree_insert_async(struct closure *); | ||
36 | void bch_cache_read_endio(struct bio *, int); | 35 | void bch_cache_read_endio(struct bio *, int); |
37 | 36 | ||
38 | void bch_open_buckets_free(struct cache_set *); | 37 | void bch_open_buckets_free(struct cache_set *); |