diff options
-rw-r--r-- | drivers/md/bcache/btree_update.c | 4 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 30 | ||||
-rw-r--r-- | drivers/md/bcache/journal.h | 1 |
3 files changed, 33 insertions, 2 deletions
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index 8b5c5b43d0f8..0b7bdff6129d 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -1033,7 +1033,7 @@ static void btree_interior_update_updated_btree(struct cache_set *c, mutex_unlock(&c->btree_interior_update_lock); - bch_journal_flush_seq_async(&c->journal, as->journal_seq, &as->cl); + bch_journal_wait_on_seq(&c->journal, as->journal_seq, &as->cl); continue_at(&as->cl, btree_interior_update_nodes_written, system_freezable_wq); @@ -1068,7 +1068,7 @@ static void btree_interior_update_updated_root(struct cache_set *c, mutex_unlock(&c->btree_interior_update_lock); - bch_journal_flush_seq_async(&c->journal, as->journal_seq, &as->cl); + bch_journal_wait_on_seq(&c->journal, as->journal_seq, &as->cl); continue_at(&as->cl, btree_interior_update_nodes_written, system_freezable_wq); diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index 3a30b102c093..3f26c36c9da5 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -2111,6 +2111,36 @@ int bch_journal_res_get_slowpath(struct journal *j, struct journal_res *res, return ret < 0 ? ret : 0; } +void bch_journal_wait_on_seq(struct journal *j, u64 seq, struct closure *parent) +{ + spin_lock(&j->lock); + + BUG_ON(seq > atomic64_read(&j->seq)); + + if (bch_journal_error(j)) { + spin_unlock(&j->lock); + return; + } + + if (seq == atomic64_read(&j->seq)) { + if (!closure_wait(&journal_cur_buf(j)->wait, parent)) + BUG(); + } else if (seq + 1 == atomic64_read(&j->seq) && + j->reservations.prev_buf_unwritten) { + if (!closure_wait(&journal_prev_buf(j)->wait, parent)) + BUG(); + + smp_mb(); + + /* check if raced with write completion (or failure) */ + if (!j->reservations.prev_buf_unwritten || + bch_journal_error(j)) + closure_wake_up(&journal_prev_buf(j)->wait); + } + + spin_unlock(&j->lock); +} + void bch_journal_flush_seq_async(struct journal *j, u64 seq, struct closure *parent) { spin_lock(&j->lock); diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h index 940e697d5d47..6fe7014ecd76 100644 --- a/drivers/md/bcache/journal.h +++ b/drivers/md/bcache/journal.h @@ -315,6 +315,7 @@ out: return 0; } +void bch_journal_wait_on_seq(struct journal *, u64, struct closure *); void bch_journal_flush_seq_async(struct journal *, u64, struct closure *); void bch_journal_flush_async(struct journal *, struct closure *); void bch_journal_meta_async(struct journal *, struct closure *); |