summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-03-17 19:17:57 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:35:53 -0800
commit3aeb8a3a2574f69568db40741646bf9a6075cb14 (patch)
tree171c1c88f4305c289c9ad992b27c76761c724ec7
parent13358f10d7faee37c7eaffc54db6a4b699a8760e (diff)
bcache: bch_journal_halt()
-rw-r--r--drivers/md/bcache/btree_io.c8
-rw-r--r--drivers/md/bcache/journal.c8
-rw-r--r--drivers/md/bcache/journal.h2
-rw-r--r--drivers/md/bcache/super.c1
4 files changed, 18 insertions, 1 deletions
diff --git a/drivers/md/bcache/btree_io.c b/drivers/md/bcache/btree_io.c
index c593468dc195..f1e9c57e6e3e 100644
--- a/drivers/md/bcache/btree_io.c
+++ b/drivers/md/bcache/btree_io.c
@@ -491,6 +491,14 @@ static void btree_node_write_done(struct closure *cl)
struct btree_write *w = btree_prev_write(b);
struct cache_set *c = b->c;
+ /*
+ * Before calling bch_btree_complete_write() - if the write errored, we
+ * have to halt new journal writes before they see this btree node
+ * write as completed:
+ */
+ if (btree_node_write_error(b))
+ bch_journal_halt(&c->journal);
+
/* XXX: pin btree node in memory somehow */
if (!btree_node_write_error(b))
bch_btree_complete_write(c, b, w);
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 6b18f9db7f37..5a133c3f2a2f 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -850,6 +850,12 @@ static enum journal_entry_state journal_entry_close(struct journal *j)
return __journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
}
+void bch_journal_halt(struct journal *j)
+{
+ __journal_entry_close(j, JOURNAL_ENTRY_ERROR_VAL);
+ wake_up(&j->wait);
+}
+
/* Number of u64s we can write to the current journal bucket */
static void journal_entry_open(struct journal *j)
{
@@ -1381,7 +1387,7 @@ static void journal_write_endio(struct bio *bio)
if (cache_fatal_io_err_on(bio->bi_error, ca, "journal write") ||
bch_meta_write_fault("journal")) {
- __journal_entry_close(j, JOURNAL_ENTRY_ERROR_VAL);
+ bch_journal_halt(j);
wake_up(&j->wait);
}
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h
index 180019a571e0..e417d5b28b09 100644
--- a/drivers/md/bcache/journal.h
+++ b/drivers/md/bcache/journal.h
@@ -209,6 +209,8 @@ int bch_journal_flush_seq(struct journal *, u64);
int bch_journal_flush(struct journal *);
int bch_journal_meta(struct journal *);
+void bch_journal_halt(struct journal *);
+
static inline int bch_journal_error(struct journal *j)
{
return j->reservations.cur_entry_offset == JOURNAL_ENTRY_ERROR_VAL
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 88427a89c29f..5eae7eadf678 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -803,6 +803,7 @@ bool bch_cache_set_emergency_read_only(struct cache_set *c)
bool ret = !test_and_set_bit(CACHE_SET_EMERGENCY_RO, &c->flags);
bch_cache_set_read_only(c);
+ bch_journal_halt(&c->journal);
wake_up(&bch_read_only_wait);
return ret;