diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-03-17 19:17:57 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:35:53 -0800 |
commit | 3aeb8a3a2574f69568db40741646bf9a6075cb14 (patch) | |
tree | 171c1c88f4305c289c9ad992b27c76761c724ec7 | |
parent | 13358f10d7faee37c7eaffc54db6a4b699a8760e (diff) |
bcache: bch_journal_halt()
-rw-r--r-- | drivers/md/bcache/btree_io.c | 8 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 8 | ||||
-rw-r--r-- | drivers/md/bcache/journal.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 1 |
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; |