diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-01-07 17:09:26 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-22 00:44:18 -0400 |
commit | 0318b62d732011e2b241db25efd9feade5b9ad13 (patch) | |
tree | b6da539f63abe29ef57736dde01e5712b0b9de79 | |
parent | 068e3da3565aeb3b808ce66b92e01ab847635abf (diff) |
bcachefs: fix a deadlock in bch2_journal_flush_pins()
-rw-r--r-- | fs/bcachefs/journal.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index ed2753304aab..e8756cd8e01b 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -1223,6 +1223,8 @@ static enum { buf = &j->buf[old.idx]; buf->data->u64s = cpu_to_le32(old.cur_entry_offset); + + /* XXX: why set this here, and not in journal_write()? */ buf->data->last_seq = cpu_to_le64(last_seq(j)); j->prev_buf_sectors = @@ -1732,6 +1734,7 @@ static inline void __journal_pin_add(struct journal *j, list_add(&pin->list, &pin_list->list); else INIT_LIST_HEAD(&pin->list); + wake_up(&j->wait); } static void journal_pin_add_entry(struct journal *j, @@ -1878,10 +1881,16 @@ void bch2_journal_flush_pins(struct journal *j, u64 seq_to_flush) */ if (!test_bit(JOURNAL_REPLAY_DONE, &j->flags)) return; - +again: + /* flushing a journal pin might cause a new one to be added: */ wait_event(j->wait, + (pin = journal_get_next_pin(j, seq_to_flush, &pin_seq)) || journal_flush_done(j, seq_to_flush) || bch2_journal_error(j)); + if (pin) { + pin->flush(j, pin, pin_seq); + goto again; + } } int bch2_journal_flush_all_pins(struct journal *j) |