diff options
Diffstat (limited to 'drivers/md/bcache/journal.c')
-rw-r--r-- | drivers/md/bcache/journal.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index ad687285c2df..9d32d5790822 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c | |||
@@ -564,6 +564,14 @@ static void journal_write_done(struct closure *cl) | |||
564 | continue_at_nobarrier(cl, journal_write, system_wq); | 564 | continue_at_nobarrier(cl, journal_write, system_wq); |
565 | } | 565 | } |
566 | 566 | ||
567 | static void journal_write_unlock(struct closure *cl) | ||
568 | { | ||
569 | struct cache_set *c = container_of(cl, struct cache_set, journal.io); | ||
570 | |||
571 | c->journal.io_in_flight = 0; | ||
572 | spin_unlock(&c->journal.lock); | ||
573 | } | ||
574 | |||
567 | static void journal_write_unlocked(struct closure *cl) | 575 | static void journal_write_unlocked(struct closure *cl) |
568 | __releases(c->journal.lock) | 576 | __releases(c->journal.lock) |
569 | { | 577 | { |
@@ -578,15 +586,7 @@ static void journal_write_unlocked(struct closure *cl) | |||
578 | bio_list_init(&list); | 586 | bio_list_init(&list); |
579 | 587 | ||
580 | if (!w->need_write) { | 588 | if (!w->need_write) { |
581 | /* | 589 | closure_return_with_destructor(cl, journal_write_unlock); |
582 | * XXX: have to unlock closure before we unlock journal lock, | ||
583 | * else we race with bch_journal(). But this way we race | ||
584 | * against cache set unregister. Doh. | ||
585 | */ | ||
586 | set_closure_fn(cl, NULL, NULL); | ||
587 | closure_sub(cl, CLOSURE_RUNNING + 1); | ||
588 | spin_unlock(&c->journal.lock); | ||
589 | return; | ||
590 | } else if (journal_full(&c->journal)) { | 590 | } else if (journal_full(&c->journal)) { |
591 | journal_reclaim(c); | 591 | journal_reclaim(c); |
592 | spin_unlock(&c->journal.lock); | 592 | spin_unlock(&c->journal.lock); |
@@ -662,10 +662,12 @@ static void journal_try_write(struct cache_set *c) | |||
662 | 662 | ||
663 | w->need_write = true; | 663 | w->need_write = true; |
664 | 664 | ||
665 | if (closure_trylock(cl, &c->cl)) | 665 | if (!c->journal.io_in_flight) { |
666 | journal_write_unlocked(cl); | 666 | c->journal.io_in_flight = 1; |
667 | else | 667 | closure_call(cl, journal_write_unlocked, NULL, &c->cl); |
668 | } else { | ||
668 | spin_unlock(&c->journal.lock); | 669 | spin_unlock(&c->journal.lock); |
670 | } | ||
669 | } | 671 | } |
670 | 672 | ||
671 | static struct journal_write *journal_wait_for_write(struct cache_set *c, | 673 | static struct journal_write *journal_wait_for_write(struct cache_set *c, |
@@ -793,7 +795,6 @@ int bch_journal_alloc(struct cache_set *c) | |||
793 | { | 795 | { |
794 | struct journal *j = &c->journal; | 796 | struct journal *j = &c->journal; |
795 | 797 | ||
796 | closure_init_unlocked(&j->io); | ||
797 | spin_lock_init(&j->lock); | 798 | spin_lock_init(&j->lock); |
798 | INIT_DELAYED_WORK(&j->work, journal_write_work); | 799 | INIT_DELAYED_WORK(&j->work, journal_write_work); |
799 | 800 | ||