diff options
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.c | 19 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.h | 2 |
3 files changed, 19 insertions, 10 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 1c47d806fa9c..e27ec0fbee2c 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -659,13 +659,13 @@ int bch2_trans_commit_error(struct btree_trans *trans, case BTREE_INSERT_NEED_JOURNAL_RECLAIM: bch2_trans_unlock(trans); - while (bch2_btree_key_cache_must_wait(c)) { + do { mutex_lock(&c->journal.reclaim_lock); - bch2_journal_reclaim(&c->journal); + ret = bch2_journal_reclaim(&c->journal); mutex_unlock(&c->journal.reclaim_lock); - } + } while (!ret && bch2_btree_key_cache_must_wait(c)); - if (bch2_trans_relock(trans)) + if (!ret && bch2_trans_relock(trans)) return 0; trace_trans_restart_journal_reclaim(trans->ip); diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c index 1dabad618870..4fd2b272e04e 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -485,13 +485,14 @@ static u64 journal_seq_to_flush(struct journal *j) * 512 journal entries or 25% of all journal buckets, then * journal_next_bucket() should not stall. */ -static void __bch2_journal_reclaim(struct journal *j, bool direct) +static int __bch2_journal_reclaim(struct journal *j, bool direct) { struct bch_fs *c = container_of(j, struct bch_fs, journal); bool kthread = (current->flags & PF_KTHREAD) != 0; u64 seq_to_flush, nr_flushed = 0; size_t min_nr; unsigned flags; + int ret = 0; /* * We can't invoke memory reclaim while holding the reclaim_lock - @@ -506,6 +507,11 @@ static void __bch2_journal_reclaim(struct journal *j, bool direct) if (kthread && kthread_should_stop()) break; + if (bch2_journal_error(j)) { + ret = -EIO; + break; + } + bch2_journal_do_discards(j); seq_to_flush = journal_seq_to_flush(j); @@ -547,27 +553,30 @@ static void __bch2_journal_reclaim(struct journal *j, bool direct) } while (min_nr); memalloc_noreclaim_restore(flags); + + return ret; } -void bch2_journal_reclaim(struct journal *j) +int bch2_journal_reclaim(struct journal *j) { - __bch2_journal_reclaim(j, true); + return __bch2_journal_reclaim(j, true); } static int bch2_journal_reclaim_thread(void *arg) { struct journal *j = arg; unsigned long next; + int ret = 0; set_freezable(); kthread_wait_freezable(test_bit(JOURNAL_RECLAIM_STARTED, &j->flags)); - while (!kthread_should_stop()) { + while (!ret && !kthread_should_stop()) { j->reclaim_kicked = false; mutex_lock(&j->reclaim_lock); - __bch2_journal_reclaim(j, false); + ret = __bch2_journal_reclaim(j, false); mutex_unlock(&j->reclaim_lock); next = j->last_flushed + msecs_to_jiffies(j->reclaim_delay_ms); diff --git a/fs/bcachefs/journal_reclaim.h b/fs/bcachefs/journal_reclaim.h index e25355042e6e..3404fef241ea 100644 --- a/fs/bcachefs/journal_reclaim.h +++ b/fs/bcachefs/journal_reclaim.h @@ -73,7 +73,7 @@ static inline void bch2_journal_pin_update(struct journal *j, u64 seq, void bch2_journal_pin_flush(struct journal *, struct journal_entry_pin *); void bch2_journal_do_discards(struct journal *); -void bch2_journal_reclaim(struct journal *); +int bch2_journal_reclaim(struct journal *); void bch2_journal_reclaim_stop(struct journal *); int bch2_journal_reclaim_start(struct journal *); |