mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
bcachefs: Check for errors in bch2_journal_reclaim()
If the journal is halted, journal reclaim won't necessarily be able to make any forward progress, and won't accomplish anything anyways - we should bail out so that we don't get stuck looping in reclaim when the caches are too dirty and we should be shutting down. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
33c74e4119
commit
afa7cb0c36
@ -659,13 +659,13 @@ int bch2_trans_commit_error(struct btree_trans *trans,
|
|||||||
case BTREE_INSERT_NEED_JOURNAL_RECLAIM:
|
case BTREE_INSERT_NEED_JOURNAL_RECLAIM:
|
||||||
bch2_trans_unlock(trans);
|
bch2_trans_unlock(trans);
|
||||||
|
|
||||||
while (bch2_btree_key_cache_must_wait(c)) {
|
do {
|
||||||
mutex_lock(&c->journal.reclaim_lock);
|
mutex_lock(&c->journal.reclaim_lock);
|
||||||
bch2_journal_reclaim(&c->journal);
|
ret = bch2_journal_reclaim(&c->journal);
|
||||||
mutex_unlock(&c->journal.reclaim_lock);
|
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;
|
return 0;
|
||||||
|
|
||||||
trace_trans_restart_journal_reclaim(trans->ip);
|
trace_trans_restart_journal_reclaim(trans->ip);
|
||||||
|
@ -485,13 +485,14 @@ static u64 journal_seq_to_flush(struct journal *j)
|
|||||||
* 512 journal entries or 25% of all journal buckets, then
|
* 512 journal entries or 25% of all journal buckets, then
|
||||||
* journal_next_bucket() should not stall.
|
* 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);
|
struct bch_fs *c = container_of(j, struct bch_fs, journal);
|
||||||
bool kthread = (current->flags & PF_KTHREAD) != 0;
|
bool kthread = (current->flags & PF_KTHREAD) != 0;
|
||||||
u64 seq_to_flush, nr_flushed = 0;
|
u64 seq_to_flush, nr_flushed = 0;
|
||||||
size_t min_nr;
|
size_t min_nr;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can't invoke memory reclaim while holding the reclaim_lock -
|
* 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())
|
if (kthread && kthread_should_stop())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (bch2_journal_error(j)) {
|
||||||
|
ret = -EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bch2_journal_do_discards(j);
|
bch2_journal_do_discards(j);
|
||||||
|
|
||||||
seq_to_flush = journal_seq_to_flush(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);
|
} while (min_nr);
|
||||||
|
|
||||||
memalloc_noreclaim_restore(flags);
|
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)
|
static int bch2_journal_reclaim_thread(void *arg)
|
||||||
{
|
{
|
||||||
struct journal *j = arg;
|
struct journal *j = arg;
|
||||||
unsigned long next;
|
unsigned long next;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
set_freezable();
|
set_freezable();
|
||||||
|
|
||||||
kthread_wait_freezable(test_bit(JOURNAL_RECLAIM_STARTED, &j->flags));
|
kthread_wait_freezable(test_bit(JOURNAL_RECLAIM_STARTED, &j->flags));
|
||||||
|
|
||||||
while (!kthread_should_stop()) {
|
while (!ret && !kthread_should_stop()) {
|
||||||
j->reclaim_kicked = false;
|
j->reclaim_kicked = false;
|
||||||
|
|
||||||
mutex_lock(&j->reclaim_lock);
|
mutex_lock(&j->reclaim_lock);
|
||||||
__bch2_journal_reclaim(j, false);
|
ret = __bch2_journal_reclaim(j, false);
|
||||||
mutex_unlock(&j->reclaim_lock);
|
mutex_unlock(&j->reclaim_lock);
|
||||||
|
|
||||||
next = j->last_flushed + msecs_to_jiffies(j->reclaim_delay_ms);
|
next = j->last_flushed + msecs_to_jiffies(j->reclaim_delay_ms);
|
||||||
|
@ -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_pin_flush(struct journal *, struct journal_entry_pin *);
|
||||||
|
|
||||||
void bch2_journal_do_discards(struct journal *);
|
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 *);
|
void bch2_journal_reclaim_stop(struct journal *);
|
||||||
int bch2_journal_reclaim_start(struct journal *);
|
int bch2_journal_reclaim_start(struct journal *);
|
||||||
|
Loading…
Reference in New Issue
Block a user