@@ -2628,23 +2628,22 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
26282628}
26292629
26302630/**
2631- * nilfs_segctor_thread - main loop of the segment constructor thread.
2631+ * nilfs_segctor_thread - main loop of the log writer thread
26322632 * @arg: pointer to a struct nilfs_sc_info.
26332633 *
2634- * nilfs_segctor_thread() initializes a timer and serves as a daemon
2635- * to execute segment constructions.
2634+ * nilfs_segctor_thread() is the main loop function of the log writer kernel
2635+ * thread, which determines whether log writing is necessary, and if so,
2636+ * performs the log write in the background, or waits if not. It is also
2637+ * used to decide the background writeback of the superblock.
2638+ *
2639+ * Return: Always 0.
26362640 */
26372641static int nilfs_segctor_thread (void * arg )
26382642{
26392643 struct nilfs_sc_info * sci = (struct nilfs_sc_info * )arg ;
26402644 struct the_nilfs * nilfs = sci -> sc_super -> s_fs_info ;
26412645 int timeout = 0 ;
26422646
2643- timer_setup (& sci -> sc_timer , nilfs_construction_timeout , 0 );
2644-
2645- /* start sync. */
2646- sci -> sc_task = current ;
2647- wake_up (& sci -> sc_wait_task ); /* for nilfs_segctor_start_thread() */
26482647 nilfs_info (sci -> sc_super ,
26492648 "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds" ,
26502649 sci -> sc_interval / HZ , sci -> sc_mjcp_freq / HZ );
@@ -2655,7 +2654,7 @@ static int nilfs_segctor_thread(void *arg)
26552654 for (;;) {
26562655 int mode ;
26572656
2658- if (sci -> sc_state & NILFS_SEGCTOR_QUIT )
2657+ if (kthread_should_stop () )
26592658 goto end_thread ;
26602659
26612660 if (timeout || sci -> sc_seq_request != sci -> sc_seq_done )
@@ -2709,41 +2708,10 @@ static int nilfs_segctor_thread(void *arg)
27092708 /* end sync. */
27102709 sci -> sc_task = NULL ;
27112710 timer_shutdown_sync (& sci -> sc_timer );
2712- wake_up (& sci -> sc_wait_task ); /* for nilfs_segctor_kill_thread() */
27132711 spin_unlock (& sci -> sc_state_lock );
27142712 return 0 ;
27152713}
27162714
2717- static int nilfs_segctor_start_thread (struct nilfs_sc_info * sci )
2718- {
2719- struct task_struct * t ;
2720-
2721- t = kthread_run (nilfs_segctor_thread , sci , "segctord" );
2722- if (IS_ERR (t )) {
2723- int err = PTR_ERR (t );
2724-
2725- nilfs_err (sci -> sc_super , "error %d creating segctord thread" ,
2726- err );
2727- return err ;
2728- }
2729- wait_event (sci -> sc_wait_task , sci -> sc_task != NULL );
2730- return 0 ;
2731- }
2732-
2733- static void nilfs_segctor_kill_thread (struct nilfs_sc_info * sci )
2734- __acquires (& sci - > sc_state_lock )
2735- __releases (& sci - > sc_state_lock )
2736- {
2737- sci -> sc_state |= NILFS_SEGCTOR_QUIT ;
2738-
2739- while (sci -> sc_task ) {
2740- wake_up (& sci -> sc_wait_daemon );
2741- spin_unlock (& sci -> sc_state_lock );
2742- wait_event (sci -> sc_wait_task , sci -> sc_task == NULL );
2743- spin_lock (& sci -> sc_state_lock );
2744- }
2745- }
2746-
27472715/*
27482716 * Setup & clean-up functions
27492717 */
@@ -2764,7 +2732,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
27642732
27652733 init_waitqueue_head (& sci -> sc_wait_request );
27662734 init_waitqueue_head (& sci -> sc_wait_daemon );
2767- init_waitqueue_head (& sci -> sc_wait_task );
27682735 spin_lock_init (& sci -> sc_state_lock );
27692736 INIT_LIST_HEAD (& sci -> sc_dirty_files );
27702737 INIT_LIST_HEAD (& sci -> sc_segbufs );
@@ -2819,8 +2786,12 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
28192786
28202787 up_write (& nilfs -> ns_segctor_sem );
28212788
2789+ if (sci -> sc_task ) {
2790+ wake_up (& sci -> sc_wait_daemon );
2791+ kthread_stop (sci -> sc_task );
2792+ }
2793+
28222794 spin_lock (& sci -> sc_state_lock );
2823- nilfs_segctor_kill_thread (sci );
28242795 flag = ((sci -> sc_state & NILFS_SEGCTOR_COMMIT ) || sci -> sc_flush_request
28252796 || sci -> sc_seq_request != sci -> sc_seq_done );
28262797 spin_unlock (& sci -> sc_state_lock );
@@ -2868,14 +2839,15 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
28682839 * This allocates a log writer object, initializes it, and starts the
28692840 * log writer.
28702841 *
2871- * Return Value: On success, 0 is returned. On error, one of the following
2872- * negative error code is returned.
2873- *
2874- * %-ENOMEM - Insufficient memory available.
2842+ * Return: 0 on success, or the following negative error code on failure.
2843+ * * %-EINTR - Log writer thread creation failed due to interruption.
2844+ * * %-ENOMEM - Insufficient memory available.
28752845 */
28762846int nilfs_attach_log_writer (struct super_block * sb , struct nilfs_root * root )
28772847{
28782848 struct the_nilfs * nilfs = sb -> s_fs_info ;
2849+ struct nilfs_sc_info * sci ;
2850+ struct task_struct * t ;
28792851 int err ;
28802852
28812853 if (nilfs -> ns_writer ) {
@@ -2888,15 +2860,23 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
28882860 return 0 ;
28892861 }
28902862
2891- nilfs -> ns_writer = nilfs_segctor_new (sb , root );
2892- if (! nilfs -> ns_writer )
2863+ sci = nilfs_segctor_new (sb , root );
2864+ if (unlikely (! sci ) )
28932865 return - ENOMEM ;
28942866
2895- err = nilfs_segctor_start_thread (nilfs -> ns_writer );
2896- if (unlikely (err ))
2867+ nilfs -> ns_writer = sci ;
2868+ t = kthread_create (nilfs_segctor_thread , sci , "segctord" );
2869+ if (IS_ERR (t )) {
2870+ err = PTR_ERR (t );
2871+ nilfs_err (sb , "error %d creating segctord thread" , err );
28972872 nilfs_detach_log_writer (sb );
2873+ return err ;
2874+ }
2875+ sci -> sc_task = t ;
2876+ timer_setup (& sci -> sc_timer , nilfs_construction_timeout , 0 );
28982877
2899- return err ;
2878+ wake_up_process (sci -> sc_task );
2879+ return 0 ;
29002880}
29012881
29022882/**
0 commit comments