Commit 2ce867df authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet
Browse files

bcachefs: Make sure to initialize j->last_flushed



If the journal reclaim thread makes it to the timeout without ever
initializing j->last_flushed, we could end up sleeping for a very long
time.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 050197b1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1189,6 +1189,8 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
	       "nr noflush writes:\t%llu\n"
	       "nr direct reclaim:\t%llu\n"
	       "nr background reclaim:\t%llu\n"
	       "reclaim kicked:\t\t%u\n"
	       "reclaim runs in:\t%u ms\n"
	       "current entry sectors:\t%u\n"
	       "current entry error:\t%u\n"
	       "current entry:\t\t",
@@ -1204,6 +1206,8 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
	       j->nr_noflush_writes,
	       j->nr_direct_reclaim,
	       j->nr_background_reclaim,
	       j->reclaim_kicked,
	       jiffies_to_msecs(j->next_reclaim - jiffies),
	       j->cur_entry_sectors,
	       j->cur_entry_error);

+12 −6
Original line number Diff line number Diff line
@@ -677,13 +677,15 @@ int bch2_journal_reclaim(struct journal *j)
static int bch2_journal_reclaim_thread(void *arg)
{
	struct journal *j = arg;
	unsigned long next;
	unsigned long delay, now;
	int ret = 0;

	set_freezable();

	kthread_wait_freezable(test_bit(JOURNAL_RECLAIM_STARTED, &j->flags));

	j->last_flushed = jiffies;

	while (!ret && !kthread_should_stop()) {
		j->reclaim_kicked = false;

@@ -691,18 +693,22 @@ static int bch2_journal_reclaim_thread(void *arg)
		ret = __bch2_journal_reclaim(j, false);
		mutex_unlock(&j->reclaim_lock);

		next = j->last_flushed + msecs_to_jiffies(j->reclaim_delay_ms);
		now = jiffies;
		delay = msecs_to_jiffies(j->reclaim_delay_ms);
		j->next_reclaim = j->last_flushed + delay;

		if (!time_in_range(j->next_reclaim, now, now + delay))
			j->next_reclaim = now + delay;

		while (1) {
			set_current_state(TASK_INTERRUPTIBLE);
			set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE);
			if (kthread_should_stop())
				break;
			if (j->reclaim_kicked)
				break;
			if (time_after_eq(jiffies, next))
			if (time_after_eq(jiffies, j->next_reclaim))
				break;
			schedule_timeout(next - jiffies);
			try_to_freeze();
			schedule_timeout(j->next_reclaim - jiffies);

		}
		__set_current_state(TASK_RUNNING);
+3 −5
Original line number Diff line number Diff line
@@ -8,12 +8,10 @@ static inline void journal_reclaim_kick(struct journal *j)
{
	struct task_struct *p = READ_ONCE(j->reclaim_thread);

	if (p && !j->reclaim_kicked) {
	j->reclaim_kicked = true;
	if (p)
		wake_up_process(p);
}
}

unsigned bch2_journal_dev_buckets_available(struct journal *,
					    struct journal_device *,
+1 −0
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ struct journal {
	wait_queue_head_t	reclaim_wait;
	struct task_struct	*reclaim_thread;
	bool			reclaim_kicked;
	unsigned long		next_reclaim;
	u64			nr_direct_reclaim;
	u64			nr_background_reclaim;