@@ -1962,7 +1962,7 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
19621962
19631963 mutex_lock (& dirty_i -> seglist_lock );
19641964 for_each_set_bit (segno , dirty_i -> dirty_segmap [PRE ], MAIN_SEGS (sbi ))
1965- __set_test_and_free (sbi , segno );
1965+ __set_test_and_free (sbi , segno , false );
19661966 mutex_unlock (& dirty_i -> seglist_lock );
19671967}
19681968
@@ -2500,31 +2500,39 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
25002500 struct curseg_info * curseg = CURSEG_I (sbi , type );
25012501 struct summary_footer * sum_footer ;
25022502
2503+ curseg -> inited = true;
25032504 curseg -> segno = curseg -> next_segno ;
25042505 curseg -> zone = GET_ZONE_FROM_SEG (sbi , curseg -> segno );
25052506 curseg -> next_blkoff = 0 ;
25062507 curseg -> next_segno = NULL_SEGNO ;
25072508
25082509 sum_footer = & (curseg -> sum_blk -> footer );
25092510 memset (sum_footer , 0 , sizeof (struct summary_footer ));
2510- if (IS_DATASEG (type ))
2511+ if (IS_DATASEG (curseg -> seg_type ))
25112512 SET_SUM_TYPE (sum_footer , SUM_TYPE_DATA );
2512- if (IS_NODESEG (type ))
2513+ if (IS_NODESEG (curseg -> seg_type ))
25132514 SET_SUM_TYPE (sum_footer , SUM_TYPE_NODE );
2514- __set_sit_entry_type (sbi , type , curseg -> segno , modified );
2515+ __set_sit_entry_type (sbi , curseg -> seg_type , curseg -> segno , modified );
25152516}
25162517
25172518static unsigned int __get_next_segno (struct f2fs_sb_info * sbi , int type )
25182519{
2520+ struct curseg_info * curseg = CURSEG_I (sbi , type );
2521+
25192522 /* if segs_per_sec is large than 1, we need to keep original policy. */
25202523 if (__is_large_section (sbi ))
2521- return CURSEG_I (sbi , type )-> segno ;
2524+ return curseg -> segno ;
2525+
2526+ /* inmem log may not locate on any segment after mount */
2527+ if (!curseg -> inited )
2528+ return 0 ;
25222529
25232530 if (unlikely (is_sbi_flag_set (sbi , SBI_CP_DISABLED )))
25242531 return 0 ;
25252532
25262533 if (test_opt (sbi , NOHEAP ) &&
2527- (type == CURSEG_HOT_DATA || IS_NODESEG (type )))
2534+ (curseg -> seg_type == CURSEG_HOT_DATA ||
2535+ IS_NODESEG (curseg -> seg_type )))
25282536 return 0 ;
25292537
25302538 if (SIT_I (sbi )-> last_victim [ALLOC_NEXT ])
@@ -2534,7 +2542,7 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
25342542 if (F2FS_OPTION (sbi ).alloc_mode == ALLOC_MODE_REUSE )
25352543 return 0 ;
25362544
2537- return CURSEG_I ( sbi , type ) -> segno ;
2545+ return curseg -> segno ;
25382546}
25392547
25402548/*
@@ -2544,12 +2552,14 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
25442552static void new_curseg (struct f2fs_sb_info * sbi , int type , bool new_sec )
25452553{
25462554 struct curseg_info * curseg = CURSEG_I (sbi , type );
2555+ unsigned short seg_type = curseg -> seg_type ;
25472556 unsigned int segno = curseg -> segno ;
25482557 int dir = ALLOC_LEFT ;
25492558
2550- write_sum_page (sbi , curseg -> sum_blk ,
2559+ if (curseg -> inited )
2560+ write_sum_page (sbi , curseg -> sum_blk ,
25512561 GET_SUM_BLOCK (sbi , segno ));
2552- if (type == CURSEG_WARM_DATA || type == CURSEG_COLD_DATA )
2562+ if (seg_type == CURSEG_WARM_DATA || seg_type == CURSEG_COLD_DATA )
25532563 dir = ALLOC_RIGHT ;
25542564
25552565 if (test_opt (sbi , NOHEAP ))
@@ -2626,6 +2636,43 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)
26262636 f2fs_put_page (sum_page , 1 );
26272637}
26282638
2639+ void f2fs_save_inmem_curseg (struct f2fs_sb_info * sbi , int type )
2640+ {
2641+ struct curseg_info * curseg = CURSEG_I (sbi , type );
2642+
2643+ mutex_lock (& curseg -> curseg_mutex );
2644+ if (!curseg -> inited )
2645+ goto out ;
2646+
2647+ if (get_valid_blocks (sbi , curseg -> segno , false)) {
2648+ write_sum_page (sbi , curseg -> sum_blk ,
2649+ GET_SUM_BLOCK (sbi , curseg -> segno ));
2650+ } else {
2651+ mutex_lock (& DIRTY_I (sbi )-> seglist_lock );
2652+ __set_test_and_free (sbi , curseg -> segno , true);
2653+ mutex_unlock (& DIRTY_I (sbi )-> seglist_lock );
2654+ }
2655+ out :
2656+ mutex_unlock (& curseg -> curseg_mutex );
2657+ }
2658+
2659+ void f2fs_restore_inmem_curseg (struct f2fs_sb_info * sbi , int type )
2660+ {
2661+ struct curseg_info * curseg = CURSEG_I (sbi , type );
2662+
2663+ mutex_lock (& curseg -> curseg_mutex );
2664+ if (!curseg -> inited )
2665+ goto out ;
2666+ if (get_valid_blocks (sbi , curseg -> segno , false))
2667+ goto out ;
2668+
2669+ mutex_lock (& DIRTY_I (sbi )-> seglist_lock );
2670+ __set_test_and_inuse (sbi , curseg -> segno );
2671+ mutex_unlock (& DIRTY_I (sbi )-> seglist_lock );
2672+ out :
2673+ mutex_unlock (& curseg -> curseg_mutex );
2674+ }
2675+
26292676static int get_ssr_segment (struct f2fs_sb_info * sbi , int type )
26302677{
26312678 struct curseg_info * curseg = CURSEG_I (sbi , type );
@@ -2742,11 +2789,15 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
27422789 struct curseg_info * curseg = CURSEG_I (sbi , type );
27432790 unsigned int old_segno ;
27442791
2792+ if (!curseg -> inited )
2793+ goto alloc ;
2794+
27452795 if (!curseg -> next_blkoff &&
27462796 !get_valid_blocks (sbi , curseg -> segno , false) &&
27472797 !get_ckpt_valid_blocks (sbi , curseg -> segno ))
27482798 return ;
27492799
2800+ alloc :
27502801 old_segno = curseg -> segno ;
27512802 SIT_I (sbi )-> s_ops -> allocate_segment (sbi , type , true);
27522803 locate_dirty_segment (sbi , old_segno );
@@ -3130,19 +3181,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
31303181{
31313182 struct sit_info * sit_i = SIT_I (sbi );
31323183 struct curseg_info * curseg = CURSEG_I (sbi , type );
3133- bool put_pin_sem = false;
3134-
3135- if (type == CURSEG_COLD_DATA ) {
3136- /* GC during CURSEG_COLD_DATA_PINNED allocation */
3137- if (down_read_trylock (& sbi -> pin_sem )) {
3138- put_pin_sem = true;
3139- } else {
3140- type = CURSEG_WARM_DATA ;
3141- curseg = CURSEG_I (sbi , type );
3142- }
3143- } else if (type == CURSEG_COLD_DATA_PINNED ) {
3144- type = CURSEG_COLD_DATA ;
3145- }
31463184
31473185 down_read (& SM_I (sbi )-> curseg_lock );
31483186
@@ -3208,9 +3246,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
32083246 mutex_unlock (& curseg -> curseg_mutex );
32093247
32103248 up_read (& SM_I (sbi )-> curseg_lock );
3211-
3212- if (put_pin_sem )
3213- up_read (& sbi -> pin_sem );
32143249}
32153250
32163251static void update_device_state (struct f2fs_io_info * fio )
@@ -3578,7 +3613,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
35783613 blk_off = le16_to_cpu (ckpt -> cur_data_blkoff [type -
35793614 CURSEG_HOT_DATA ]);
35803615 if (__exist_node_summaries (sbi ))
3581- blk_addr = sum_blk_addr (sbi , NR_CURSEG_TYPE , type );
3616+ blk_addr = sum_blk_addr (sbi , NR_CURSEG_PERSIST_TYPE , type );
35823617 else
35833618 blk_addr = sum_blk_addr (sbi , NR_CURSEG_DATA_TYPE , type );
35843619 } else {
@@ -3656,8 +3691,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
36563691 }
36573692
36583693 if (__exist_node_summaries (sbi ))
3659- f2fs_ra_meta_pages (sbi , sum_blk_addr (sbi , NR_CURSEG_TYPE , type ),
3660- NR_CURSEG_TYPE - type , META_CP , true);
3694+ f2fs_ra_meta_pages (sbi ,
3695+ sum_blk_addr (sbi , NR_CURSEG_PERSIST_TYPE , type ),
3696+ NR_CURSEG_PERSIST_TYPE - type , META_CP , true);
36613697
36623698 for (; type <= CURSEG_COLD_NODE ; type ++ ) {
36633699 err = read_normal_summaries (sbi , type );
@@ -4159,14 +4195,14 @@ static int build_curseg(struct f2fs_sb_info *sbi)
41594195 struct curseg_info * array ;
41604196 int i ;
41614197
4162- array = f2fs_kzalloc (sbi , array_size (NR_CURSEG_TYPE , sizeof ( * array )),
4163- GFP_KERNEL );
4198+ array = f2fs_kzalloc (sbi , array_size (NR_CURSEG_TYPE ,
4199+ sizeof ( * array )), GFP_KERNEL );
41644200 if (!array )
41654201 return - ENOMEM ;
41664202
41674203 SM_I (sbi )-> curseg_array = array ;
41684204
4169- for (i = 0 ; i < NR_CURSEG_TYPE ; i ++ ) {
4205+ for (i = 0 ; i < NO_CHECK_TYPE ; i ++ ) {
41704206 mutex_init (& array [i ].curseg_mutex );
41714207 array [i ].sum_blk = f2fs_kzalloc (sbi , PAGE_SIZE , GFP_KERNEL );
41724208 if (!array [i ].sum_blk )
@@ -4176,8 +4212,13 @@ static int build_curseg(struct f2fs_sb_info *sbi)
41764212 sizeof (struct f2fs_journal ), GFP_KERNEL );
41774213 if (!array [i ].journal )
41784214 return - ENOMEM ;
4215+ if (i < NR_PERSISTENT_LOG )
4216+ array [i ].seg_type = CURSEG_HOT_DATA + i ;
4217+ else if (i == CURSEG_COLD_DATA_PINNED )
4218+ array [i ].seg_type = CURSEG_COLD_DATA ;
41794219 array [i ].segno = NULL_SEGNO ;
41804220 array [i ].next_blkoff = 0 ;
4221+ array [i ].inited = false;
41814222 }
41824223 return restore_curseg_summaries (sbi );
41834224}
@@ -4416,7 +4457,7 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi)
44164457 * In LFS/SSR curseg, .next_blkoff should point to an unused blkaddr;
44174458 * In LFS curseg, all blkaddr after .next_blkoff should be unused.
44184459 */
4419- for (i = 0 ; i < NO_CHECK_TYPE ; i ++ ) {
4460+ for (i = 0 ; i < NR_PERSISTENT_LOG ; i ++ ) {
44204461 struct curseg_info * curseg = CURSEG_I (sbi , i );
44214462 struct seg_entry * se = get_seg_entry (sbi , curseg -> segno );
44224463 unsigned int blkofs = curseg -> next_blkoff ;
@@ -4645,7 +4686,7 @@ int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
46454686{
46464687 int i , ret ;
46474688
4648- for (i = 0 ; i < NO_CHECK_TYPE ; i ++ ) {
4689+ for (i = 0 ; i < NR_PERSISTENT_LOG ; i ++ ) {
46494690 ret = fix_curseg_write_pointer (sbi , i );
46504691 if (ret )
46514692 return ret ;
0 commit comments