@@ -1735,7 +1735,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17351735 unsigned char type = IS_DATASEG (get_seg_entry (sbi , segno )-> type ) ?
17361736 SUM_TYPE_DATA : SUM_TYPE_NODE ;
17371737 unsigned char data_type = (type == SUM_TYPE_DATA ) ? DATA : NODE ;
1738- int submitted = 0 ;
1738+ int submitted = 0 , sum_blk_cnt ;
17391739
17401740 if (__is_large_section (sbi )) {
17411741 sec_end_segno = rounddown (end_segno , SEGS_PER_SEC (sbi ));
@@ -1769,22 +1769,28 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17691769
17701770 sanity_check_seg_type (sbi , get_seg_entry (sbi , segno )-> type );
17711771
1772+ segno = rounddown (segno , SUMS_PER_BLOCK );
1773+ sum_blk_cnt = DIV_ROUND_UP (end_segno - segno , SUMS_PER_BLOCK );
17721774 /* readahead multi ssa blocks those have contiguous address */
17731775 if (__is_large_section (sbi ))
17741776 f2fs_ra_meta_pages (sbi , GET_SUM_BLOCK (sbi , segno ),
1775- end_segno - segno , META_SSA , true);
1777+ sum_blk_cnt , META_SSA , true);
17761778
17771779 /* reference all summary page */
17781780 while (segno < end_segno ) {
1779- struct folio * sum_folio = f2fs_get_sum_folio (sbi , segno ++ );
1781+ struct folio * sum_folio = f2fs_get_sum_folio (sbi , segno );
1782+
1783+ segno += SUMS_PER_BLOCK ;
17801784 if (IS_ERR (sum_folio )) {
17811785 int err = PTR_ERR (sum_folio );
17821786
1783- end_segno = segno - 1 ;
1784- for (segno = start_segno ; segno < end_segno ; segno ++ ) {
1787+ end_segno = segno - SUMS_PER_BLOCK ;
1788+ segno = rounddown (start_segno , SUMS_PER_BLOCK );
1789+ while (segno < end_segno ) {
17851790 sum_folio = filemap_get_folio (META_MAPPING (sbi ),
17861791 GET_SUM_BLOCK (sbi , segno ));
17871792 folio_put_refs (sum_folio , 2 );
1793+ segno += SUMS_PER_BLOCK ;
17881794 }
17891795 return err ;
17901796 }
@@ -1793,68 +1799,83 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17931799
17941800 blk_start_plug (& plug );
17951801
1796- for (segno = start_segno ; segno < end_segno ; segno ++ ) {
1797- struct f2fs_summary_block * sum ;
1802+ segno = start_segno ;
1803+ while (segno < end_segno ) {
1804+ unsigned int cur_segno ;
17981805
17991806 /* find segment summary of victim */
18001807 struct folio * sum_folio = filemap_get_folio (META_MAPPING (sbi ),
18011808 GET_SUM_BLOCK (sbi , segno ));
1809+ unsigned int block_end_segno = rounddown (segno , SUMS_PER_BLOCK )
1810+ + SUMS_PER_BLOCK ;
1811+
1812+ if (block_end_segno > end_segno )
1813+ block_end_segno = end_segno ;
18021814
18031815 if (is_cursec (sbi , GET_SEC_FROM_SEG (sbi , segno ))) {
18041816 f2fs_err (sbi , "%s: segment %u is used by log" ,
18051817 __func__ , segno );
18061818 f2fs_bug_on (sbi , 1 );
1807- goto skip ;
1819+ goto next_block ;
18081820 }
18091821
1810- if (get_valid_blocks (sbi , segno , false) == 0 )
1811- goto freed ;
1812- if (gc_type == BG_GC && __is_large_section (sbi ) &&
1813- migrated >= sbi -> migration_granularity )
1814- goto skip ;
18151822 if (!folio_test_uptodate (sum_folio ) ||
18161823 unlikely (f2fs_cp_error (sbi )))
1817- goto skip ;
1824+ goto next_block ;
18181825
1819- sum = folio_address (sum_folio );
1820- if (type != GET_SUM_TYPE ((& sum -> footer ))) {
1821- f2fs_err (sbi , "Inconsistent segment (%u) type [%d, %d] in SIT and SSA" ,
1822- segno , type , GET_SUM_TYPE ((& sum -> footer )));
1823- f2fs_stop_checkpoint (sbi , false,
1824- STOP_CP_REASON_CORRUPTED_SUMMARY );
1825- goto skip ;
1826- }
1826+ for (cur_segno = segno ; cur_segno < block_end_segno ;
1827+ cur_segno ++ ) {
1828+ struct f2fs_summary_block * sum ;
18271829
1828- /*
1829- * this is to avoid deadlock:
1830- * - lock_page(sum_page) - f2fs_replace_block
1831- * - check_valid_map() - down_write(sentry_lock)
1832- * - down_read(sentry_lock) - change_curseg()
1833- * - lock_page(sum_page)
1834- */
1835- if (type == SUM_TYPE_NODE )
1836- submitted += gc_node_segment (sbi , sum -> entries , segno ,
1837- gc_type );
1838- else
1839- submitted += gc_data_segment (sbi , sum -> entries , gc_list ,
1840- segno , gc_type ,
1841- force_migrate );
1830+ if (get_valid_blocks (sbi , cur_segno , false) == 0 )
1831+ goto freed ;
1832+ if (gc_type == BG_GC && __is_large_section (sbi ) &&
1833+ migrated >= sbi -> migration_granularity )
1834+ continue ;
18421835
1843- stat_inc_gc_seg_count (sbi , data_type , gc_type );
1844- sbi -> gc_reclaimed_segs [sbi -> gc_mode ]++ ;
1845- migrated ++ ;
1836+ sum = SUM_BLK_PAGE_ADDR (sum_folio , cur_segno );
1837+ if (type != GET_SUM_TYPE ((& sum -> footer ))) {
1838+ f2fs_err (sbi , "Inconsistent segment (%u) type "
1839+ "[%d, %d] in SSA and SIT" ,
1840+ cur_segno , type ,
1841+ GET_SUM_TYPE ((& sum -> footer )));
1842+ f2fs_stop_checkpoint (sbi , false,
1843+ STOP_CP_REASON_CORRUPTED_SUMMARY );
1844+ continue ;
1845+ }
18461846
1847- freed :
1848- if (gc_type == FG_GC &&
1849- get_valid_blocks (sbi , segno , false) == 0 )
1850- seg_freed ++ ;
1847+ /*
1848+ * this is to avoid deadlock:
1849+ * - lock_page(sum_page) - f2fs_replace_block
1850+ * - check_valid_map() - down_write(sentry_lock)
1851+ * - down_read(sentry_lock) - change_curseg()
1852+ * - lock_page(sum_page)
1853+ */
1854+ if (type == SUM_TYPE_NODE )
1855+ submitted += gc_node_segment (sbi , sum -> entries ,
1856+ cur_segno , gc_type );
1857+ else
1858+ submitted += gc_data_segment (sbi , sum -> entries ,
1859+ gc_list , cur_segno ,
1860+ gc_type , force_migrate );
18511861
1852- if (__is_large_section (sbi ))
1853- sbi -> next_victim_seg [gc_type ] =
1854- (segno + 1 < sec_end_segno ) ?
1855- segno + 1 : NULL_SEGNO ;
1856- skip :
1862+ stat_inc_gc_seg_count (sbi , data_type , gc_type );
1863+ sbi -> gc_reclaimed_segs [sbi -> gc_mode ]++ ;
1864+ migrated ++ ;
1865+
1866+ freed :
1867+ if (gc_type == FG_GC &&
1868+ get_valid_blocks (sbi , cur_segno , false) == 0 )
1869+ seg_freed ++ ;
1870+
1871+ if (__is_large_section (sbi ))
1872+ sbi -> next_victim_seg [gc_type ] =
1873+ (cur_segno + 1 < sec_end_segno ) ?
1874+ cur_segno + 1 : NULL_SEGNO ;
1875+ }
1876+ next_block :
18571877 folio_put_refs (sum_folio , 2 );
1878+ segno = block_end_segno ;
18581879 }
18591880
18601881 if (submitted )
0 commit comments