diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-12-08 17:28:02 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-18 21:41:27 -0900 |
commit | 2a5aabcfc0db52062dad95f4b522c74307add3d5 (patch) | |
tree | 596ecfdd93356d64bfaf392aa1d5be22c8e1a1a7 | |
parent | 019162ee32535849042f7482e7cd57c7263864bd (diff) |
bcache: don't flush journal unnecessarily
-rw-r--r-- | drivers/md/bcache/btree_update.c | 16 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 30 | ||||
-rw-r--r-- | drivers/md/bcache/journal.h | 1 |
3 files changed, 43 insertions, 4 deletions
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index 8b5c5b43d0f8..e5771185155d 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,12 +1068,20 @@ 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); } +static void interior_update_flush(struct journal *j, struct journal_entry_pin *pin) +{ + struct btree_interior_update *as = + container_of(pin, struct btree_interior_update, journal); + + bch_journal_flush_seq_async(j, as->journal_seq, NULL); +} + /* * @b is being split/rewritten: it may have pointers to not-yet-written btree * nodes and thus outstanding btree_interior_updates - redirect @b's @@ -1108,10 +1116,10 @@ void bch_btree_interior_update_will_free_node(struct cache_set *c, */ bch_journal_pin_add_if_older(&c->journal, &b->writes[0].journal, - &as->journal, NULL); + &as->journal, interior_update_flush); bch_journal_pin_add_if_older(&c->journal, &b->writes[1].journal, - &as->journal, NULL); + &as->journal, interior_update_flush); mutex_lock(&c->btree_interior_update_lock); 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 *); |