From 94035eed52f58a321fa28e938898535973bec847 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sat, 11 Apr 2020 12:29:32 -0400 Subject: [PATCH] bcachefs: Fix a locking bug in bch2_journal_pin_copy() There was a race where the src pin would be flushed - releasing the last pin on that sequence number - before adding the new journal pin. Oops. Signed-off-by: Kent Overstreet Signed-off-by: Kent Overstreet --- fs/bcachefs/journal_reclaim.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c index 5233cb82d422a..341106ab4a774 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -322,14 +322,12 @@ void bch2_journal_pin_drop(struct journal *j, spin_unlock(&j->lock); } -void __bch2_journal_pin_add(struct journal *j, u64 seq, +static void bch2_journal_pin_add_locked(struct journal *j, u64 seq, struct journal_entry_pin *pin, journal_pin_flush_fn flush_fn) { struct journal_entry_pin_list *pin_list = journal_seq_pin(j, seq); - spin_lock(&j->lock); - __journal_pin_drop(j, pin); BUG_ON(!atomic_read(&pin_list->count)); @@ -339,7 +337,14 @@ void __bch2_journal_pin_add(struct journal *j, u64 seq, pin->flush = flush_fn; list_add(&pin->list, flush_fn ? &pin_list->list : &pin_list->flushed); +} +void __bch2_journal_pin_add(struct journal *j, u64 seq, + struct journal_entry_pin *pin, + journal_pin_flush_fn flush_fn) +{ + spin_lock(&j->lock); + bch2_journal_pin_add_locked(j, seq, pin, flush_fn); spin_unlock(&j->lock); /* @@ -354,9 +359,13 @@ void bch2_journal_pin_copy(struct journal *j, struct journal_entry_pin *src, journal_pin_flush_fn flush_fn) { + spin_lock(&j->lock); + if (journal_pin_active(src) && (!journal_pin_active(dst) || src->seq < dst->seq)) - __bch2_journal_pin_add(j, src->seq, dst, flush_fn); + bch2_journal_pin_add_locked(j, src->seq, dst, flush_fn); + + spin_unlock(&j->lock); } /** -- 2.30.2