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: Ryusuke Konishi <konishi.ryusuke@gmail.com> Cc: Huang Xiaojia <huangxiaojia2@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
3f66cc261c
commit
74b0099340
+41
-46
@@ -2627,6 +2627,32 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
|
|||||||
return SC_LSEG_SR;
|
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
|
* nilfs_segctor_thread - main loop of the log writer thread
|
||||||
* @arg: pointer to a struct nilfs_sc_info.
|
* @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 nilfs_sc_info *sci = (struct nilfs_sc_info *)arg;
|
||||||
struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
|
struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
|
||||||
int timeout = 0;
|
|
||||||
|
|
||||||
nilfs_info(sci->sc_super,
|
nilfs_info(sci->sc_super,
|
||||||
"segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
|
"segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
|
||||||
sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
|
sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
|
||||||
|
|
||||||
set_freezable();
|
set_freezable();
|
||||||
spin_lock(&sci->sc_state_lock);
|
|
||||||
loop:
|
while (!kthread_should_stop()) {
|
||||||
for (;;) {
|
DEFINE_WAIT(wait);
|
||||||
|
bool should_write;
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
if (kthread_should_stop())
|
if (freezing(current)) {
|
||||||
goto end_thread;
|
try_to_freeze();
|
||||||
|
continue;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
prepare_to_wait(&sci->sc_wait_daemon, &wait,
|
prepare_to_wait(&sci->sc_wait_daemon, &wait,
|
||||||
TASK_INTERRUPTIBLE);
|
TASK_INTERRUPTIBLE);
|
||||||
|
should_write = nilfs_log_write_required(sci, &mode);
|
||||||
if (sci->sc_seq_request != sci->sc_seq_done)
|
if (!should_write)
|
||||||
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);
|
|
||||||
schedule();
|
schedule();
|
||||||
spin_lock(&sci->sc_state_lock);
|
|
||||||
}
|
|
||||||
finish_wait(&sci->sc_wait_daemon, &wait);
|
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))
|
if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
|
||||||
set_nilfs_discontinued(nilfs);
|
set_nilfs_discontinued(nilfs);
|
||||||
}
|
|
||||||
goto loop;
|
|
||||||
|
|
||||||
end_thread:
|
if (should_write)
|
||||||
|
nilfs_segctor_thread_construct(sci, mode);
|
||||||
|
}
|
||||||
|
|
||||||
/* end sync. */
|
/* end sync. */
|
||||||
|
spin_lock(&sci->sc_state_lock);
|
||||||
sci->sc_task = NULL;
|
sci->sc_task = NULL;
|
||||||
timer_shutdown_sync(&sci->sc_timer);
|
timer_shutdown_sync(&sci->sc_timer);
|
||||||
spin_unlock(&sci->sc_state_lock);
|
spin_unlock(&sci->sc_state_lock);
|
||||||
|
|||||||
Reference in New Issue
Block a user