Commit 74b00993 authored by Ryusuke Konishi's avatar Ryusuke Konishi Committed by Andrew Morton
Browse files

nilfs2: refactor nilfs_segctor_thread()

Simplify nilfs_segctor_thread(), the main loop function of the log writer
thread, to make the basic structure easier to understand.

In particular, the acquisition and release of the sc_state_lock spinlock
was scattered throughout the function, so extract the determination of
whether log writing is required into a helper function and make the
spinlock lock sections clearer.

Link: https://lkml.kernel.org/r/20240826174116.5008-9-konishi.ryusuke@gmail.com


Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@gmail.com>
Cc: Huang Xiaojia <huangxiaojia2@huawei.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 3f66cc26
Loading
Loading
Loading
Loading
+40 −45
Original line number Diff line number Diff line
@@ -2627,6 +2627,32 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
	return SC_LSEG_SR;
}

/**
 * nilfs_log_write_required - determine whether log writing is required
 * @sci:   nilfs_sc_info struct
 * @modep: location for storing log writing mode
 *
 * Return: true if log writing is required, false otherwise.  If log writing
 * is required, the mode is stored in the location pointed to by @modep.
 */
static bool nilfs_log_write_required(struct nilfs_sc_info *sci, int *modep)
{
	bool timedout, ret = true;

	spin_lock(&sci->sc_state_lock);
	timedout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
		   time_after_eq(jiffies, sci->sc_timer.expires));
	if (timedout || sci->sc_seq_request != sci->sc_seq_done)
		*modep = SC_LSEG_SR;
	else if (sci->sc_flush_request)
		*modep = nilfs_segctor_flush_mode(sci);
	else
		ret = false;

	spin_unlock(&sci->sc_state_lock);
	return ret;
}

/**
 * nilfs_segctor_thread - main loop of the log writer thread
 * @arg: pointer to a struct nilfs_sc_info.
@@ -2642,70 +2668,39 @@ static int nilfs_segctor_thread(void *arg)
{
	struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg;
	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
	int timeout = 0;

	nilfs_info(sci->sc_super,
		   "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
		   sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);

	set_freezable();
	spin_lock(&sci->sc_state_lock);
 loop:
	for (;;) {
		int mode;

		if (kthread_should_stop())
			goto end_thread;

		if (timeout || sci->sc_seq_request != sci->sc_seq_done)
			mode = SC_LSEG_SR;
		else if (sci->sc_flush_request)
			mode = nilfs_segctor_flush_mode(sci);
		else
			break;

		spin_unlock(&sci->sc_state_lock);
		nilfs_segctor_thread_construct(sci, mode);
		spin_lock(&sci->sc_state_lock);
		timeout = 0;
	}

	while (!kthread_should_stop()) {
		DEFINE_WAIT(wait);
		bool should_write;
		int mode;

		if (freezing(current)) {
		spin_unlock(&sci->sc_state_lock);
			try_to_freeze();
		spin_lock(&sci->sc_state_lock);
	} else {
		DEFINE_WAIT(wait);
		int should_sleep = 1;
			continue;
		}

		prepare_to_wait(&sci->sc_wait_daemon, &wait,
				TASK_INTERRUPTIBLE);

		if (sci->sc_seq_request != sci->sc_seq_done)
			should_sleep = 0;
		else if (sci->sc_flush_request)
			should_sleep = 0;
		else if (sci->sc_state & NILFS_SEGCTOR_COMMIT)
			should_sleep = time_before(jiffies,
					sci->sc_timer.expires);

		if (should_sleep) {
			spin_unlock(&sci->sc_state_lock);
		should_write = nilfs_log_write_required(sci, &mode);
		if (!should_write)
			schedule();
			spin_lock(&sci->sc_state_lock);
		}
		finish_wait(&sci->sc_wait_daemon, &wait);
		timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
			   time_after_eq(jiffies, sci->sc_timer.expires));

		if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
			set_nilfs_discontinued(nilfs);

		if (should_write)
			nilfs_segctor_thread_construct(sci, mode);
	}
	goto loop;

 end_thread:
	/* end sync. */
	spin_lock(&sci->sc_state_lock);
	sci->sc_task = NULL;
	timer_shutdown_sync(&sci->sc_timer);
	spin_unlock(&sci->sc_state_lock);