summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-12-08 17:28:02 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-12-12 12:53:59 -0900
commit2d258c7a723ce2ec9893a1717158cfebe96285ce (patch)
tree0a6cc3d77bd8d729d1e6648522dd961bc3095ded
parent125312566ed797bc0c8b87ae9dbf694a68ddef33 (diff)
bcache: don't flush journal unnecessarily
-rw-r--r--drivers/md/bcache/btree_update.c4
-rw-r--r--drivers/md/bcache/journal.c30
-rw-r--r--drivers/md/bcache/journal.h1
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 *);