@@ -2628,23 +2628,22 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
2628
2628
}
2629
2629
2630
2630
/**
2631
- * nilfs_segctor_thread - main loop of the segment constructor thread.
2631
+ * nilfs_segctor_thread - main loop of the log writer thread
2632
2632
* @arg: pointer to a struct nilfs_sc_info.
2633
2633
*
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.
2636
2640
*/
2637
2641
static int nilfs_segctor_thread (void * arg )
2638
2642
{
2639
2643
struct nilfs_sc_info * sci = (struct nilfs_sc_info * )arg ;
2640
2644
struct the_nilfs * nilfs = sci -> sc_super -> s_fs_info ;
2641
2645
int timeout = 0 ;
2642
2646
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() */
2648
2647
nilfs_info (sci -> sc_super ,
2649
2648
"segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds" ,
2650
2649
sci -> sc_interval / HZ , sci -> sc_mjcp_freq / HZ );
@@ -2655,7 +2654,7 @@ static int nilfs_segctor_thread(void *arg)
2655
2654
for (;;) {
2656
2655
int mode ;
2657
2656
2658
- if (sci -> sc_state & NILFS_SEGCTOR_QUIT )
2657
+ if (kthread_should_stop () )
2659
2658
goto end_thread ;
2660
2659
2661
2660
if (timeout || sci -> sc_seq_request != sci -> sc_seq_done )
@@ -2709,41 +2708,10 @@ static int nilfs_segctor_thread(void *arg)
2709
2708
/* end sync. */
2710
2709
sci -> sc_task = NULL ;
2711
2710
timer_shutdown_sync (& sci -> sc_timer );
2712
- wake_up (& sci -> sc_wait_task ); /* for nilfs_segctor_kill_thread() */
2713
2711
spin_unlock (& sci -> sc_state_lock );
2714
2712
return 0 ;
2715
2713
}
2716
2714
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
-
2747
2715
/*
2748
2716
* Setup & clean-up functions
2749
2717
*/
@@ -2764,7 +2732,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
2764
2732
2765
2733
init_waitqueue_head (& sci -> sc_wait_request );
2766
2734
init_waitqueue_head (& sci -> sc_wait_daemon );
2767
- init_waitqueue_head (& sci -> sc_wait_task );
2768
2735
spin_lock_init (& sci -> sc_state_lock );
2769
2736
INIT_LIST_HEAD (& sci -> sc_dirty_files );
2770
2737
INIT_LIST_HEAD (& sci -> sc_segbufs );
@@ -2819,8 +2786,12 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
2819
2786
2820
2787
up_write (& nilfs -> ns_segctor_sem );
2821
2788
2789
+ if (sci -> sc_task ) {
2790
+ wake_up (& sci -> sc_wait_daemon );
2791
+ kthread_stop (sci -> sc_task );
2792
+ }
2793
+
2822
2794
spin_lock (& sci -> sc_state_lock );
2823
- nilfs_segctor_kill_thread (sci );
2824
2795
flag = ((sci -> sc_state & NILFS_SEGCTOR_COMMIT ) || sci -> sc_flush_request
2825
2796
|| sci -> sc_seq_request != sci -> sc_seq_done );
2826
2797
spin_unlock (& sci -> sc_state_lock );
@@ -2868,14 +2839,15 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
2868
2839
* This allocates a log writer object, initializes it, and starts the
2869
2840
* log writer.
2870
2841
*
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.
2875
2845
*/
2876
2846
int nilfs_attach_log_writer (struct super_block * sb , struct nilfs_root * root )
2877
2847
{
2878
2848
struct the_nilfs * nilfs = sb -> s_fs_info ;
2849
+ struct nilfs_sc_info * sci ;
2850
+ struct task_struct * t ;
2879
2851
int err ;
2880
2852
2881
2853
if (nilfs -> ns_writer ) {
@@ -2888,15 +2860,23 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
2888
2860
return 0 ;
2889
2861
}
2890
2862
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 ) )
2893
2865
return - ENOMEM ;
2894
2866
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 );
2897
2872
nilfs_detach_log_writer (sb );
2873
+ return err ;
2874
+ }
2875
+ sci -> sc_task = t ;
2876
+ timer_setup (& sci -> sc_timer , nilfs_construction_timeout , 0 );
2898
2877
2899
- return err ;
2878
+ wake_up_process (sci -> sc_task );
2879
+ return 0 ;
2900
2880
}
2901
2881
2902
2882
/**
0 commit comments