nilfs2: refactor nilfs_segctor_thread()
authorRyusuke Konishi <konishi.ryusuke@gmail.com>
Mon, 26 Aug 2024 17:41:16 +0000 (02:41 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 2 Sep 2024 03:43:44 +0000 (20:43 -0700)
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>
fs/nilfs2/segment.c

index 4ff219f90f478912efffed34ba02fd3098375f43..7c99d71204f1deea459cfebbb4f9731fdf84eba5 100644 (file)
@@ -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;
-       }
 
-
-       if (freezing(current)) {
-               spin_unlock(&sci->sc_state_lock);
-               try_to_freeze();
-               spin_lock(&sci->sc_state_lock);
-       } else {
+       while (!kthread_should_stop()) {
                DEFINE_WAIT(wait);
-               int should_sleep = 1;
+               bool should_write;
+               int mode;
+
+               if (freezing(current)) {
+                       try_to_freeze();
+                       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);