* [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
@ 2025-10-07 18:08 Daeho Jeong
2025-10-11 3:39 ` kernel test robot
2025-10-11 4:00 ` kernel test robot
0 siblings, 2 replies; 6+ messages in thread
From: Daeho Jeong @ 2025-10-07 18:08 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
The recent increase in the number of Segment Summary Area (SSA) entries
from 512 to 2048 was an unintentional change in logic of 16kb block
support. This commit corrects the issue.
To better utilize the space available from the erroneous 2048-entry
calculation, we are implementing a solution to share the currently
unused SSA space with neighboring segments. This enhances overall
SSA utilization without impacting the established 8MB segment size.
Fixes: d7e9a9037de2 ("f2fs: Support Block Size == Page Size")
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
fs/f2fs/gc.c | 117 +++++++++++++++++++++++-----------------
fs/f2fs/recovery.c | 2 +-
fs/f2fs/segment.c | 21 ++++----
fs/f2fs/segment.h | 8 ++-
include/linux/f2fs_fs.h | 5 +-
5 files changed, 91 insertions(+), 62 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 88bbcf291034..9ce070cc5af1 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1732,7 +1732,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
SUM_TYPE_DATA : SUM_TYPE_NODE;
unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
- int submitted = 0;
+ int submitted = 0, sum_blk_cnt;
if (__is_large_section(sbi)) {
sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
@@ -1766,22 +1766,28 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
+ segno = rounddown(segno, SUMS_PER_BLOCK);
+ sum_blk_cnt = (end_segno - segno + SUMS_PER_BLOCK - 1) / SUMS_PER_BLOCK;
/* readahead multi ssa blocks those have contiguous address */
if (__is_large_section(sbi))
f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
- end_segno - segno, META_SSA, true);
+ sum_blk_cnt, META_SSA, true);
/* reference all summary page */
while (segno < end_segno) {
- struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno++);
+ struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno);
+
+ segno += SUMS_PER_BLOCK;
if (IS_ERR(sum_folio)) {
int err = PTR_ERR(sum_folio);
- end_segno = segno - 1;
- for (segno = start_segno; segno < end_segno; segno++) {
+ end_segno = segno - SUMS_PER_BLOCK;
+ segno = rounddown(start_segno, SUMS_PER_BLOCK);
+ while (segno < end_segno) {
sum_folio = filemap_get_folio(META_MAPPING(sbi),
GET_SUM_BLOCK(sbi, segno));
folio_put_refs(sum_folio, 2);
+ segno += SUMS_PER_BLOCK;
}
return err;
}
@@ -1790,61 +1796,76 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
blk_start_plug(&plug);
- for (segno = start_segno; segno < end_segno; segno++) {
- struct f2fs_summary_block *sum;
-
+ segno = start_segno;
+ while (segno < end_segno) {
+ unsigned int cur_segno;
/* find segment summary of victim */
struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi),
GET_SUM_BLOCK(sbi, segno));
+ unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK)
+ + SUMS_PER_BLOCK;
+
+ if (block_end_segno > end_segno)
+ block_end_segno = end_segno;
- if (get_valid_blocks(sbi, segno, false) == 0)
- goto freed;
- if (gc_type == BG_GC && __is_large_section(sbi) &&
- migrated >= sbi->migration_granularity)
- goto skip;
if (!folio_test_uptodate(sum_folio) ||
unlikely(f2fs_cp_error(sbi)))
- goto skip;
-
- sum = folio_address(sum_folio);
- if (type != GET_SUM_TYPE((&sum->footer))) {
- f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
- segno, type, GET_SUM_TYPE((&sum->footer)));
- f2fs_stop_checkpoint(sbi, false,
- STOP_CP_REASON_CORRUPTED_SUMMARY);
- goto skip;
- }
+ goto next_block;
+
+ for (cur_segno = segno; cur_segno < block_end_segno;
+ cur_segno++) {
+ struct f2fs_summary_block *sum;
+
+ if (get_valid_blocks(sbi, cur_segno, false) == 0)
+ goto freed;
+ if (gc_type == BG_GC && __is_large_section(sbi) &&
+ migrated >= sbi->migration_granularity)
+ goto skip;
+
+ sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno);
+ if (type != GET_SUM_TYPE((&sum->footer))) {
+ f2fs_err(sbi, "Inconsistent segment (%u) type "
+ "[%d, %d] in SSA and SIT",
+ cur_segno, type,
+ GET_SUM_TYPE((&sum->footer)));
+ f2fs_stop_checkpoint(sbi, false,
+ STOP_CP_REASON_CORRUPTED_SUMMARY);
+ goto skip;
+ }
- /*
- * this is to avoid deadlock:
- * - lock_page(sum_page) - f2fs_replace_block
- * - check_valid_map() - down_write(sentry_lock)
- * - down_read(sentry_lock) - change_curseg()
- * - lock_page(sum_page)
- */
- if (type == SUM_TYPE_NODE)
- submitted += gc_node_segment(sbi, sum->entries, segno,
- gc_type);
- else
- submitted += gc_data_segment(sbi, sum->entries, gc_list,
- segno, gc_type,
- force_migrate);
+ /*
+ * this is to avoid deadlock:
+ * - lock_page(sum_page) - f2fs_replace_block
+ * - check_valid_map() - down_write(sentry_lock)
+ * - down_read(sentry_lock) - change_curseg()
+ * - lock_page(sum_page)
+ */
+ if (type == SUM_TYPE_NODE)
+ submitted += gc_node_segment(sbi, sum->entries,
+ cur_segno, gc_type);
+ else
+ submitted += gc_data_segment(sbi, sum->entries,
+ gc_list, cur_segno,
+ gc_type, force_migrate);
- stat_inc_gc_seg_count(sbi, data_type, gc_type);
- sbi->gc_reclaimed_segs[sbi->gc_mode]++;
- migrated++;
+ stat_inc_gc_seg_count(sbi, data_type, gc_type);
+ sbi->gc_reclaimed_segs[sbi->gc_mode]++;
+ migrated++;
freed:
- if (gc_type == FG_GC &&
- get_valid_blocks(sbi, segno, false) == 0)
- seg_freed++;
-
- if (__is_large_section(sbi))
- sbi->next_victim_seg[gc_type] =
- (segno + 1 < sec_end_segno) ?
- segno + 1 : NULL_SEGNO;
+ if (gc_type == FG_GC &&
+ get_valid_blocks(sbi, cur_segno, false) == 0)
+ seg_freed++;
+
+ if (__is_large_section(sbi))
+ sbi->next_victim_seg[gc_type] =
+ (cur_segno + 1 < sec_end_segno) ?
+ cur_segno + 1 : NULL_SEGNO;
skip:
+ }
+next_block:
folio_put_refs(sum_folio, 2);
+ segno = block_end_segno;
}
if (submitted)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 4cb3a91801b4..4fda8d2afdc8 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -519,7 +519,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
sum_folio = f2fs_get_sum_folio(sbi, segno);
if (IS_ERR(sum_folio))
return PTR_ERR(sum_folio);
- sum_node = folio_address(sum_folio);
+ sum_node = SUM_BLK_PAGE_ADDR(sum_folio, segno);
sum = sum_node->entries[blkoff];
f2fs_folio_put(sum_folio, true);
got_it:
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index cc82d42ef14c..2d2fd874fbb4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2720,9 +2720,14 @@ void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
}
static void write_sum_page(struct f2fs_sb_info *sbi,
- struct f2fs_summary_block *sum_blk, block_t blk_addr)
+ struct f2fs_summary_block *sum_blk, unsigned int segno)
{
- f2fs_update_meta_page(sbi, (void *)sum_blk, blk_addr);
+ struct folio *folio;
+
+ folio = f2fs_get_sum_folio(sbi, segno);
+ memcpy(SUM_BLK_PAGE_ADDR(folio, segno), sum_blk, sizeof(*sum_blk));
+ folio_mark_dirty(folio);
+ f2fs_folio_put(folio, true);
}
static void write_current_sum_page(struct f2fs_sb_info *sbi,
@@ -2970,7 +2975,7 @@ static int new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
int ret;
if (curseg->inited)
- write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, segno));
+ write_sum_page(sbi, curseg->sum_blk, segno);
segno = __get_next_segno(sbi, type);
ret = get_new_segment(sbi, &segno, new_sec, pinning);
@@ -3029,7 +3034,7 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type)
struct folio *sum_folio;
if (curseg->inited)
- write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
+ write_sum_page(sbi, curseg->sum_blk, curseg->segno);
__set_test_and_inuse(sbi, new_segno);
@@ -3048,7 +3053,7 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type)
memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE);
return PTR_ERR(sum_folio);
}
- sum_node = folio_address(sum_folio);
+ sum_node = SUM_BLK_PAGE_ADDR(sum_folio, new_segno);
memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
f2fs_folio_put(sum_folio, true);
return 0;
@@ -3137,8 +3142,7 @@ static void __f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi, int type)
goto out;
if (get_valid_blocks(sbi, curseg->segno, false)) {
- write_sum_page(sbi, curseg->sum_blk,
- GET_SUM_BLOCK(sbi, curseg->segno));
+ write_sum_page(sbi, curseg->sum_blk, curseg->segno);
} else {
mutex_lock(&DIRTY_I(sbi)->seglist_lock);
__set_test_and_free(sbi, curseg->segno, true);
@@ -3815,8 +3819,7 @@ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct folio *folio,
if (segment_full) {
if (type == CURSEG_COLD_DATA_PINNED &&
!((curseg->segno + 1) % sbi->segs_per_sec)) {
- write_sum_page(sbi, curseg->sum_blk,
- GET_SUM_BLOCK(sbi, curseg->segno));
+ write_sum_page(sbi, curseg->sum_blk, curseg->segno);
reset_curseg_fields(curseg);
goto skip_new_segment;
}
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 5e2ee5c686b1..510487669610 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -85,8 +85,12 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi,
#define GET_ZONE_FROM_SEG(sbi, segno) \
GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno))
-#define GET_SUM_BLOCK(sbi, segno) \
- ((sbi)->sm_info->ssa_blkaddr + (segno))
+#define SUMS_PER_BLOCK (F2FS_BLKSIZE / F2FS_SUM_BLKSIZE)
+#define GET_SUM_BLOCK(sbi, segno) \
+ (SM_I(sbi)->ssa_blkaddr + (segno / SUMS_PER_BLOCK))
+#define GET_SUM_BLKOFF(segno) (segno % SUMS_PER_BLOCK)
+#define SUM_BLK_PAGE_ADDR(folio, segno) \
+ (folio_address(folio) + GET_SUM_BLKOFF(segno) * F2FS_SUM_BLKSIZE)
#define GET_SUM_TYPE(footer) ((footer)->entry_type)
#define SET_SUM_TYPE(footer, type) ((footer)->entry_type = (type))
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 2f8b8bfc0e73..f6b2149d5e81 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -17,6 +17,7 @@
#define F2FS_LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) /* log number for sector/blk */
#define F2FS_BLKSIZE PAGE_SIZE /* support only block == page */
#define F2FS_BLKSIZE_BITS PAGE_SHIFT /* bits for F2FS_BLKSIZE */
+#define F2FS_SUM_BLKSIZE 4096 /* only support 4096 byte sum block */
#define F2FS_MAX_EXTENSION 64 /* # of extension entries */
#define F2FS_EXTENSION_LEN 8 /* max size of extension */
@@ -440,7 +441,7 @@ struct f2fs_sit_block {
* from node's page's beginning to get a data block address.
* ex) data_blkaddr = (block_t)(nodepage_start_address + ofs_in_node)
*/
-#define ENTRIES_IN_SUM (F2FS_BLKSIZE / 8)
+#define ENTRIES_IN_SUM (F2FS_SUM_BLKSIZE / 8)
#define SUMMARY_SIZE (7) /* sizeof(struct f2fs_summary) */
#define SUM_FOOTER_SIZE (5) /* sizeof(struct summary_footer) */
#define SUM_ENTRY_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM)
@@ -466,7 +467,7 @@ struct summary_footer {
__le32 check_sum; /* summary checksum */
} __packed;
-#define SUM_JOURNAL_SIZE (F2FS_BLKSIZE - SUM_FOOTER_SIZE -\
+#define SUM_JOURNAL_SIZE (F2FS_SUM_BLKSIZE - SUM_FOOTER_SIZE -\
SUM_ENTRY_SIZE)
#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) /\
sizeof(struct nat_journal_entry))
--
2.51.0.740.g6adb054d12-goog
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
2025-10-07 18:08 Daeho Jeong
@ 2025-10-11 3:39 ` kernel test robot
2025-10-11 4:00 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2025-10-11 3:39 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team
Cc: llvm, Daeho Jeong, oe-kbuild-all
Hi Daeho,
kernel test robot noticed the following build warnings:
[auto build test WARNING on v6.17]
[cannot apply to jaegeuk-f2fs/dev-test jaegeuk-f2fs/dev linus/master next-20251010]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Daeho-Jeong/f2fs-revert-summary-entry-count-from-2048-to-512-in-16kb-block-support/20251010-093707
base: v6.17
patch link: https://lore.kernel.org/r/20251007180819.3858285-1-daeho43%40gmail.com
patch subject: [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
config: riscv-randconfig-002-20251011 (https://download.01.org/0day-ci/archive/20251011/202510111112.Z3YnKrkU-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 39f292ffa13d7ca0d1edff27ac8fd55024bb4d19)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251011/202510111112.Z3YnKrkU-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510111112.Z3YnKrkU-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> fs/f2fs/gc.c:1862:3: warning: label at end of compound statement is a C23 extension [-Wc23-extensions]
1862 | }
| ^
1 warning generated.
vim +1862 fs/f2fs/gc.c
1718
1719 static int do_garbage_collect(struct f2fs_sb_info *sbi,
1720 unsigned int start_segno,
1721 struct gc_inode_list *gc_list, int gc_type,
1722 bool force_migrate, bool one_time)
1723 {
1724 struct blk_plug plug;
1725 unsigned int segno = start_segno;
1726 unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
1727 unsigned int sec_end_segno;
1728 int seg_freed = 0, migrated = 0;
1729 unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
1730 SUM_TYPE_DATA : SUM_TYPE_NODE;
1731 unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
1732 int submitted = 0, sum_blk_cnt;
1733
1734 if (__is_large_section(sbi)) {
1735 sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
1736
1737 /*
1738 * zone-capacity can be less than zone-size in zoned devices,
1739 * resulting in less than expected usable segments in the zone,
1740 * calculate the end segno in the zone which can be garbage
1741 * collected
1742 */
1743 if (f2fs_sb_has_blkzoned(sbi))
1744 sec_end_segno -= SEGS_PER_SEC(sbi) -
1745 f2fs_usable_segs_in_sec(sbi);
1746
1747 if (gc_type == BG_GC || one_time) {
1748 unsigned int window_granularity =
1749 sbi->migration_window_granularity;
1750
1751 if (f2fs_sb_has_blkzoned(sbi) &&
1752 !has_enough_free_blocks(sbi,
1753 sbi->gc_thread->boost_zoned_gc_percent))
1754 window_granularity *=
1755 sbi->gc_thread->boost_gc_multiple;
1756
1757 end_segno = start_segno + window_granularity;
1758 }
1759
1760 if (end_segno > sec_end_segno)
1761 end_segno = sec_end_segno;
1762 }
1763
1764 sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
1765
1766 segno = rounddown(segno, SUMS_PER_BLOCK);
1767 sum_blk_cnt = (end_segno - segno + SUMS_PER_BLOCK - 1) / SUMS_PER_BLOCK;
1768 /* readahead multi ssa blocks those have contiguous address */
1769 if (__is_large_section(sbi))
1770 f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
1771 sum_blk_cnt, META_SSA, true);
1772
1773 /* reference all summary page */
1774 while (segno < end_segno) {
1775 struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno);
1776
1777 segno += SUMS_PER_BLOCK;
1778 if (IS_ERR(sum_folio)) {
1779 int err = PTR_ERR(sum_folio);
1780
1781 end_segno = segno - SUMS_PER_BLOCK;
1782 segno = rounddown(start_segno, SUMS_PER_BLOCK);
1783 while (segno < end_segno) {
1784 sum_folio = filemap_get_folio(META_MAPPING(sbi),
1785 GET_SUM_BLOCK(sbi, segno));
1786 folio_put_refs(sum_folio, 2);
1787 segno += SUMS_PER_BLOCK;
1788 }
1789 return err;
1790 }
1791 folio_unlock(sum_folio);
1792 }
1793
1794 blk_start_plug(&plug);
1795
1796 segno = start_segno;
1797 while (segno < end_segno) {
1798 unsigned int cur_segno;
1799 /* find segment summary of victim */
1800 struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi),
1801 GET_SUM_BLOCK(sbi, segno));
1802 unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK)
1803 + SUMS_PER_BLOCK;
1804
1805 if (block_end_segno > end_segno)
1806 block_end_segno = end_segno;
1807
1808 if (!folio_test_uptodate(sum_folio) ||
1809 unlikely(f2fs_cp_error(sbi)))
1810 goto next_block;
1811
1812 for (cur_segno = segno; cur_segno < block_end_segno;
1813 cur_segno++) {
1814 struct f2fs_summary_block *sum;
1815
1816 if (get_valid_blocks(sbi, cur_segno, false) == 0)
1817 goto freed;
1818 if (gc_type == BG_GC && __is_large_section(sbi) &&
1819 migrated >= sbi->migration_granularity)
1820 goto skip;
1821
1822 sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno);
1823 if (type != GET_SUM_TYPE((&sum->footer))) {
1824 f2fs_err(sbi, "Inconsistent segment (%u) type "
1825 "[%d, %d] in SSA and SIT",
1826 cur_segno, type,
1827 GET_SUM_TYPE((&sum->footer)));
1828 f2fs_stop_checkpoint(sbi, false,
1829 STOP_CP_REASON_CORRUPTED_SUMMARY);
1830 goto skip;
1831 }
1832
1833 /*
1834 * this is to avoid deadlock:
1835 * - lock_page(sum_page) - f2fs_replace_block
1836 * - check_valid_map() - down_write(sentry_lock)
1837 * - down_read(sentry_lock) - change_curseg()
1838 * - lock_page(sum_page)
1839 */
1840 if (type == SUM_TYPE_NODE)
1841 submitted += gc_node_segment(sbi, sum->entries,
1842 cur_segno, gc_type);
1843 else
1844 submitted += gc_data_segment(sbi, sum->entries,
1845 gc_list, cur_segno,
1846 gc_type, force_migrate);
1847
1848 stat_inc_gc_seg_count(sbi, data_type, gc_type);
1849 sbi->gc_reclaimed_segs[sbi->gc_mode]++;
1850 migrated++;
1851
1852 freed:
1853 if (gc_type == FG_GC &&
1854 get_valid_blocks(sbi, cur_segno, false) == 0)
1855 seg_freed++;
1856
1857 if (__is_large_section(sbi))
1858 sbi->next_victim_seg[gc_type] =
1859 (cur_segno + 1 < sec_end_segno) ?
1860 cur_segno + 1 : NULL_SEGNO;
1861 skip:
> 1862 }
1863 next_block:
1864 folio_put_refs(sum_folio, 2);
1865 segno = block_end_segno;
1866 }
1867
1868 if (submitted)
1869 f2fs_submit_merged_write(sbi, data_type);
1870
1871 blk_finish_plug(&plug);
1872
1873 if (migrated)
1874 stat_inc_gc_sec_count(sbi, data_type, gc_type);
1875
1876 return seg_freed;
1877 }
1878
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
2025-10-07 18:08 Daeho Jeong
2025-10-11 3:39 ` kernel test robot
@ 2025-10-11 4:00 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2025-10-11 4:00 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team
Cc: Daeho Jeong, oe-kbuild-all
Hi Daeho,
kernel test robot noticed the following build errors:
[auto build test ERROR on v6.17]
[cannot apply to jaegeuk-f2fs/dev-test jaegeuk-f2fs/dev linus/master next-20251010]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Daeho-Jeong/f2fs-revert-summary-entry-count-from-2048-to-512-in-16kb-block-support/20251010-093707
base: v6.17
patch link: https://lore.kernel.org/r/20251007180819.3858285-1-daeho43%40gmail.com
patch subject: [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
config: arc-randconfig-002-20251011 (https://download.01.org/0day-ci/archive/20251011/202510111151.zDEs4Y0k-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 9.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251011/202510111151.zDEs4Y0k-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510111151.zDEs4Y0k-lkp@intel.com/
All errors (new ones prefixed by >>):
fs/f2fs/gc.c: In function 'do_garbage_collect':
>> fs/f2fs/gc.c:1861:1: error: label at end of compound statement
1861 | skip:
| ^~~~
vim +1861 fs/f2fs/gc.c
7bc0900347e069 Jaegeuk Kim 2012-11-02 1718
718e53fa633f84 Chao Yu 2016-01-23 1719 static int do_garbage_collect(struct f2fs_sb_info *sbi,
718e53fa633f84 Chao Yu 2016-01-23 1720 unsigned int start_segno,
7dede88659df38 Chao Yu 2021-02-20 1721 struct gc_inode_list *gc_list, int gc_type,
9748c2ddea4a3f Daeho Jeong 2024-09-09 1722 bool force_migrate, bool one_time)
7bc0900347e069 Jaegeuk Kim 2012-11-02 1723 {
c718379b6b0954 Jaegeuk Kim 2013-04-24 1724 struct blk_plug plug;
718e53fa633f84 Chao Yu 2016-01-23 1725 unsigned int segno = start_segno;
a60108f7dfb586 Jaegeuk Kim 2024-02-06 1726 unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
8c890c4c603427 Daeho Jeong 2024-09-09 1727 unsigned int sec_end_segno;
e3080b0120a15e Chao Yu 2018-10-24 1728 int seg_freed = 0, migrated = 0;
718e53fa633f84 Chao Yu 2016-01-23 1729 unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
718e53fa633f84 Chao Yu 2016-01-23 1730 SUM_TYPE_DATA : SUM_TYPE_NODE;
9bf1dcbdfdc889 Chao Yu 2023-08-08 1731 unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
2e154d8454d8bc Daeho Jeong 2025-10-07 1732 int submitted = 0, sum_blk_cnt;
7bc0900347e069 Jaegeuk Kim 2012-11-02 1733
8c890c4c603427 Daeho Jeong 2024-09-09 1734 if (__is_large_section(sbi)) {
8c890c4c603427 Daeho Jeong 2024-09-09 1735 sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
e3080b0120a15e Chao Yu 2018-10-24 1736
de881df97768d0 Aravind Ramesh 2020-07-16 1737 /*
de881df97768d0 Aravind Ramesh 2020-07-16 1738 * zone-capacity can be less than zone-size in zoned devices,
de881df97768d0 Aravind Ramesh 2020-07-16 1739 * resulting in less than expected usable segments in the zone,
8c890c4c603427 Daeho Jeong 2024-09-09 1740 * calculate the end segno in the zone which can be garbage
8c890c4c603427 Daeho Jeong 2024-09-09 1741 * collected
de881df97768d0 Aravind Ramesh 2020-07-16 1742 */
de881df97768d0 Aravind Ramesh 2020-07-16 1743 if (f2fs_sb_has_blkzoned(sbi))
8c890c4c603427 Daeho Jeong 2024-09-09 1744 sec_end_segno -= SEGS_PER_SEC(sbi) -
2af583afcf9d54 liuderong 2024-09-11 1745 f2fs_usable_segs_in_sec(sbi);
de881df97768d0 Aravind Ramesh 2020-07-16 1746
9748c2ddea4a3f Daeho Jeong 2024-09-09 1747 if (gc_type == BG_GC || one_time) {
2223fe652f7596 Daeho Jeong 2024-09-09 1748 unsigned int window_granularity =
8c890c4c603427 Daeho Jeong 2024-09-09 1749 sbi->migration_window_granularity;
8c890c4c603427 Daeho Jeong 2024-09-09 1750
2223fe652f7596 Daeho Jeong 2024-09-09 1751 if (f2fs_sb_has_blkzoned(sbi) &&
2223fe652f7596 Daeho Jeong 2024-09-09 1752 !has_enough_free_blocks(sbi,
9a481a1c16f465 Daeho Jeong 2024-09-09 1753 sbi->gc_thread->boost_zoned_gc_percent))
9a481a1c16f465 Daeho Jeong 2024-09-09 1754 window_granularity *=
1d4c5dbba1a53a Daeho Jeong 2025-07-28 1755 sbi->gc_thread->boost_gc_multiple;
2223fe652f7596 Daeho Jeong 2024-09-09 1756
2223fe652f7596 Daeho Jeong 2024-09-09 1757 end_segno = start_segno + window_granularity;
2223fe652f7596 Daeho Jeong 2024-09-09 1758 }
2223fe652f7596 Daeho Jeong 2024-09-09 1759
8c890c4c603427 Daeho Jeong 2024-09-09 1760 if (end_segno > sec_end_segno)
8c890c4c603427 Daeho Jeong 2024-09-09 1761 end_segno = sec_end_segno;
8c890c4c603427 Daeho Jeong 2024-09-09 1762 }
8c890c4c603427 Daeho Jeong 2024-09-09 1763
093749e296e29a Chao Yu 2020-08-04 1764 sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
093749e296e29a Chao Yu 2020-08-04 1765
2e154d8454d8bc Daeho Jeong 2025-10-07 1766 segno = rounddown(segno, SUMS_PER_BLOCK);
2e154d8454d8bc Daeho Jeong 2025-10-07 1767 sum_blk_cnt = (end_segno - segno + SUMS_PER_BLOCK - 1) / SUMS_PER_BLOCK;
718e53fa633f84 Chao Yu 2016-01-23 1768 /* readahead multi ssa blocks those have contiguous address */
2c70c5e3874e8c Chao Yu 2018-10-24 1769 if (__is_large_section(sbi))
4d57b86dd86404 Chao Yu 2018-05-30 1770 f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
2e154d8454d8bc Daeho Jeong 2025-10-07 1771 sum_blk_cnt, META_SSA, true);
718e53fa633f84 Chao Yu 2016-01-23 1772
718e53fa633f84 Chao Yu 2016-01-23 1773 /* reference all summary page */
718e53fa633f84 Chao Yu 2016-01-23 1774 while (segno < end_segno) {
2e154d8454d8bc Daeho Jeong 2025-10-07 1775 struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno);
2e154d8454d8bc Daeho Jeong 2025-10-07 1776
2e154d8454d8bc Daeho Jeong 2025-10-07 1777 segno += SUMS_PER_BLOCK;
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1778) if (IS_ERR(sum_folio)) {
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1779) int err = PTR_ERR(sum_folio);
edc55aaf0d1712 Jaegeuk Kim 2018-09-17 1780
2e154d8454d8bc Daeho Jeong 2025-10-07 1781 end_segno = segno - SUMS_PER_BLOCK;
2e154d8454d8bc Daeho Jeong 2025-10-07 1782 segno = rounddown(start_segno, SUMS_PER_BLOCK);
2e154d8454d8bc Daeho Jeong 2025-10-07 1783 while (segno < end_segno) {
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1784) sum_folio = filemap_get_folio(META_MAPPING(sbi),
edc55aaf0d1712 Jaegeuk Kim 2018-09-17 1785 GET_SUM_BLOCK(sbi, segno));
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1786) folio_put_refs(sum_folio, 2);
2e154d8454d8bc Daeho Jeong 2025-10-07 1787 segno += SUMS_PER_BLOCK;
edc55aaf0d1712 Jaegeuk Kim 2018-09-17 1788 }
edc55aaf0d1712 Jaegeuk Kim 2018-09-17 1789 return err;
edc55aaf0d1712 Jaegeuk Kim 2018-09-17 1790 }
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1791) folio_unlock(sum_folio);
718e53fa633f84 Chao Yu 2016-01-23 1792 }
7bc0900347e069 Jaegeuk Kim 2012-11-02 1793
c718379b6b0954 Jaegeuk Kim 2013-04-24 1794 blk_start_plug(&plug);
c718379b6b0954 Jaegeuk Kim 2013-04-24 1795
2e154d8454d8bc Daeho Jeong 2025-10-07 1796 segno = start_segno;
2e154d8454d8bc Daeho Jeong 2025-10-07 1797 while (segno < end_segno) {
2e154d8454d8bc Daeho Jeong 2025-10-07 1798 unsigned int cur_segno;
718e53fa633f84 Chao Yu 2016-01-23 1799 /* find segment summary of victim */
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1800) struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi),
718e53fa633f84 Chao Yu 2016-01-23 1801 GET_SUM_BLOCK(sbi, segno));
2e154d8454d8bc Daeho Jeong 2025-10-07 1802 unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK)
2e154d8454d8bc Daeho Jeong 2025-10-07 1803 + SUMS_PER_BLOCK;
2e154d8454d8bc Daeho Jeong 2025-10-07 1804
2e154d8454d8bc Daeho Jeong 2025-10-07 1805 if (block_end_segno > end_segno)
2e154d8454d8bc Daeho Jeong 2025-10-07 1806 block_end_segno = end_segno;
2e154d8454d8bc Daeho Jeong 2025-10-07 1807
2e154d8454d8bc Daeho Jeong 2025-10-07 1808 if (!folio_test_uptodate(sum_folio) ||
2e154d8454d8bc Daeho Jeong 2025-10-07 1809 unlikely(f2fs_cp_error(sbi)))
2e154d8454d8bc Daeho Jeong 2025-10-07 1810 goto next_block;
2e154d8454d8bc Daeho Jeong 2025-10-07 1811
2e154d8454d8bc Daeho Jeong 2025-10-07 1812 for (cur_segno = segno; cur_segno < block_end_segno;
2e154d8454d8bc Daeho Jeong 2025-10-07 1813 cur_segno++) {
2e154d8454d8bc Daeho Jeong 2025-10-07 1814 struct f2fs_summary_block *sum;
718e53fa633f84 Chao Yu 2016-01-23 1815
2e154d8454d8bc Daeho Jeong 2025-10-07 1816 if (get_valid_blocks(sbi, cur_segno, false) == 0)
d6c66cd19ef322 Yunlong Song 2018-10-24 1817 goto freed;
dabfbbc8f91450 Jaegeuk Kim 2020-02-09 1818 if (gc_type == BG_GC && __is_large_section(sbi) &&
e3080b0120a15e Chao Yu 2018-10-24 1819 migrated >= sbi->migration_granularity)
e3080b0120a15e Chao Yu 2018-10-24 1820 goto skip;
de0dcc40f6e24d Jaegeuk Kim 2016-10-12 1821
2e154d8454d8bc Daeho Jeong 2025-10-07 1822 sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno);
10d255c3540239 Chao Yu 2018-07-04 1823 if (type != GET_SUM_TYPE((&sum->footer))) {
2e154d8454d8bc Daeho Jeong 2025-10-07 1824 f2fs_err(sbi, "Inconsistent segment (%u) type "
2e154d8454d8bc Daeho Jeong 2025-10-07 1825 "[%d, %d] in SSA and SIT",
2e154d8454d8bc Daeho Jeong 2025-10-07 1826 cur_segno, type,
2e154d8454d8bc Daeho Jeong 2025-10-07 1827 GET_SUM_TYPE((&sum->footer)));
a9cfee0ef98e99 Chao Yu 2022-09-28 1828 f2fs_stop_checkpoint(sbi, false,
a9cfee0ef98e99 Chao Yu 2022-09-28 1829 STOP_CP_REASON_CORRUPTED_SUMMARY);
e3080b0120a15e Chao Yu 2018-10-24 1830 goto skip;
10d255c3540239 Chao Yu 2018-07-04 1831 }
7bc0900347e069 Jaegeuk Kim 2012-11-02 1832
9236cac5666ea8 Jaegeuk Kim 2015-05-28 1833 /*
9236cac5666ea8 Jaegeuk Kim 2015-05-28 1834 * this is to avoid deadlock:
9236cac5666ea8 Jaegeuk Kim 2015-05-28 1835 * - lock_page(sum_page) - f2fs_replace_block
3d26fa6be3c487 Chao Yu 2017-10-30 1836 * - check_valid_map() - down_write(sentry_lock)
3d26fa6be3c487 Chao Yu 2017-10-30 1837 * - down_read(sentry_lock) - change_curseg()
9236cac5666ea8 Jaegeuk Kim 2015-05-28 1838 * - lock_page(sum_page)
9236cac5666ea8 Jaegeuk Kim 2015-05-28 1839 */
718e53fa633f84 Chao Yu 2016-01-23 1840 if (type == SUM_TYPE_NODE)
2e154d8454d8bc Daeho Jeong 2025-10-07 1841 submitted += gc_node_segment(sbi, sum->entries,
2e154d8454d8bc Daeho Jeong 2025-10-07 1842 cur_segno, gc_type);
48018b4cfd07dd Chao Yu 2018-09-13 1843 else
2e154d8454d8bc Daeho Jeong 2025-10-07 1844 submitted += gc_data_segment(sbi, sum->entries,
2e154d8454d8bc Daeho Jeong 2025-10-07 1845 gc_list, cur_segno,
2e154d8454d8bc Daeho Jeong 2025-10-07 1846 gc_type, force_migrate);
c718379b6b0954 Jaegeuk Kim 2013-04-24 1847
9bf1dcbdfdc889 Chao Yu 2023-08-08 1848 stat_inc_gc_seg_count(sbi, data_type, gc_type);
07c6b5933ebf58 Daeho Jeong 2021-07-09 1849 sbi->gc_reclaimed_segs[sbi->gc_mode]++;
8c7b9ac129d096 Jaegeuk Kim 2020-02-09 1850 migrated++;
c56f16dab0dfc8 Chao Yu 2017-08-11 1851
d6c66cd19ef322 Yunlong Song 2018-10-24 1852 freed:
c56f16dab0dfc8 Chao Yu 2017-08-11 1853 if (gc_type == FG_GC &&
2e154d8454d8bc Daeho Jeong 2025-10-07 1854 get_valid_blocks(sbi, cur_segno, false) == 0)
c56f16dab0dfc8 Chao Yu 2017-08-11 1855 seg_freed++;
e3080b0120a15e Chao Yu 2018-10-24 1856
e219aecfd4b766 Yonggil Song 2022-11-22 1857 if (__is_large_section(sbi))
e219aecfd4b766 Yonggil Song 2022-11-22 1858 sbi->next_victim_seg[gc_type] =
2e154d8454d8bc Daeho Jeong 2025-10-07 1859 (cur_segno + 1 < sec_end_segno) ?
2e154d8454d8bc Daeho Jeong 2025-10-07 1860 cur_segno + 1 : NULL_SEGNO;
e3080b0120a15e Chao Yu 2018-10-24 @1861 skip:
2e154d8454d8bc Daeho Jeong 2025-10-07 1862 }
2e154d8454d8bc Daeho Jeong 2025-10-07 1863 next_block:
5d895f7beae94f Matthew Wilcox (Oracle 2025-03-31 1864) folio_put_refs(sum_folio, 2);
2e154d8454d8bc Daeho Jeong 2025-10-07 1865 segno = block_end_segno;
718e53fa633f84 Chao Yu 2016-01-23 1866 }
718e53fa633f84 Chao Yu 2016-01-23 1867
48018b4cfd07dd Chao Yu 2018-09-13 1868 if (submitted)
9bf1dcbdfdc889 Chao Yu 2023-08-08 1869 f2fs_submit_merged_write(sbi, data_type);
718e53fa633f84 Chao Yu 2016-01-23 1870
718e53fa633f84 Chao Yu 2016-01-23 1871 blk_finish_plug(&plug);
718e53fa633f84 Chao Yu 2016-01-23 1872
9bf1dcbdfdc889 Chao Yu 2023-08-08 1873 if (migrated)
9bf1dcbdfdc889 Chao Yu 2023-08-08 1874 stat_inc_gc_sec_count(sbi, data_type, gc_type);
17d899df4678a1 Chao Yu 2016-02-22 1875
c56f16dab0dfc8 Chao Yu 2017-08-11 1876 return seg_freed;
7bc0900347e069 Jaegeuk Kim 2012-11-02 1877 }
7bc0900347e069 Jaegeuk Kim 2012-11-02 1878
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
@ 2025-11-04 16:24 Daeho Jeong
2025-11-05 8:20 ` Chao Yu via Linux-f2fs-devel
2025-11-10 9:22 ` Chao Yu via Linux-f2fs-devel
0 siblings, 2 replies; 6+ messages in thread
From: Daeho Jeong @ 2025-11-04 16:24 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
The recent increase in the number of Segment Summary Area (SSA) entries
from 512 to 2048 was an unintentional change in logic of 16kb block
support. This commit corrects the issue.
To better utilize the space available from the erroneous 2048-entry
calculation, we are implementing a solution to share the currently
unused SSA space with neighboring segments. This enhances overall
SSA utilization without impacting the established 8MB segment size.
Fixes: d7e9a9037de2 ("f2fs: Support Block Size == Page Size")
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
v5: add the feature to sysfs feature and feature_list
v4: add a feature to prevent from mounting deprecated format
v3: error handling for a failure of f2fs_get_meta_folio().
v2: detect legacy layout and prevent mount.
---
fs/f2fs/f2fs.h | 2 +
fs/f2fs/gc.c | 117 +++++++++++++++++++++++-----------------
fs/f2fs/recovery.c | 2 +-
fs/f2fs/segment.c | 29 ++++++----
fs/f2fs/segment.h | 8 ++-
fs/f2fs/super.c | 14 +++++
fs/f2fs/sysfs.c | 7 +++
include/linux/f2fs_fs.h | 5 +-
8 files changed, 121 insertions(+), 63 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index b6e35fdd5fd3..c851364de529 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -245,6 +245,7 @@ struct f2fs_mount_info {
#define F2FS_FEATURE_COMPRESSION 0x00002000
#define F2FS_FEATURE_RO 0x00004000
#define F2FS_FEATURE_DEVICE_ALIAS 0x00008000
+#define F2FS_FEATURE_PACKED_SSA 0x00010000
#define __F2FS_HAS_FEATURE(raw_super, mask) \
((raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -4710,6 +4711,7 @@ F2FS_FEATURE_FUNCS(casefold, CASEFOLD);
F2FS_FEATURE_FUNCS(compression, COMPRESSION);
F2FS_FEATURE_FUNCS(readonly, RO);
F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
+F2FS_FEATURE_FUNCS(packed_ssa, PACKED_SSA);
#ifdef CONFIG_BLK_DEV_ZONED
static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 8abf521530ff..af2f4d28462c 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1732,7 +1732,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
SUM_TYPE_DATA : SUM_TYPE_NODE;
unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
- int submitted = 0;
+ int submitted = 0, sum_blk_cnt;
if (__is_large_section(sbi)) {
sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
@@ -1766,22 +1766,28 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
+ segno = rounddown(segno, SUMS_PER_BLOCK);
+ sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, SUMS_PER_BLOCK);
/* readahead multi ssa blocks those have contiguous address */
if (__is_large_section(sbi))
f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
- end_segno - segno, META_SSA, true);
+ sum_blk_cnt, META_SSA, true);
/* reference all summary page */
while (segno < end_segno) {
- struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno++);
+ struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno);
+
+ segno += SUMS_PER_BLOCK;
if (IS_ERR(sum_folio)) {
int err = PTR_ERR(sum_folio);
- end_segno = segno - 1;
- for (segno = start_segno; segno < end_segno; segno++) {
+ end_segno = segno - SUMS_PER_BLOCK;
+ segno = rounddown(start_segno, SUMS_PER_BLOCK);
+ while (segno < end_segno) {
sum_folio = filemap_get_folio(META_MAPPING(sbi),
GET_SUM_BLOCK(sbi, segno));
folio_put_refs(sum_folio, 2);
+ segno += SUMS_PER_BLOCK;
}
return err;
}
@@ -1790,68 +1796,83 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
blk_start_plug(&plug);
- for (segno = start_segno; segno < end_segno; segno++) {
- struct f2fs_summary_block *sum;
+ segno = start_segno;
+ while (segno < end_segno) {
+ unsigned int cur_segno;
/* find segment summary of victim */
struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi),
GET_SUM_BLOCK(sbi, segno));
+ unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK)
+ + SUMS_PER_BLOCK;
+
+ if (block_end_segno > end_segno)
+ block_end_segno = end_segno;
if (is_cursec(sbi, GET_SEC_FROM_SEG(sbi, segno))) {
f2fs_err(sbi, "%s: segment %u is used by log",
__func__, segno);
f2fs_bug_on(sbi, 1);
- goto skip;
+ goto next_block;
}
- if (get_valid_blocks(sbi, segno, false) == 0)
- goto freed;
- if (gc_type == BG_GC && __is_large_section(sbi) &&
- migrated >= sbi->migration_granularity)
- goto skip;
if (!folio_test_uptodate(sum_folio) ||
unlikely(f2fs_cp_error(sbi)))
- goto skip;
+ goto next_block;
- sum = folio_address(sum_folio);
- if (type != GET_SUM_TYPE((&sum->footer))) {
- f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SIT and SSA",
- segno, type, GET_SUM_TYPE((&sum->footer)));
- f2fs_stop_checkpoint(sbi, false,
- STOP_CP_REASON_CORRUPTED_SUMMARY);
- goto skip;
- }
+ for (cur_segno = segno; cur_segno < block_end_segno;
+ cur_segno++) {
+ struct f2fs_summary_block *sum;
- /*
- * this is to avoid deadlock:
- * - lock_page(sum_page) - f2fs_replace_block
- * - check_valid_map() - down_write(sentry_lock)
- * - down_read(sentry_lock) - change_curseg()
- * - lock_page(sum_page)
- */
- if (type == SUM_TYPE_NODE)
- submitted += gc_node_segment(sbi, sum->entries, segno,
- gc_type);
- else
- submitted += gc_data_segment(sbi, sum->entries, gc_list,
- segno, gc_type,
- force_migrate);
+ if (get_valid_blocks(sbi, cur_segno, false) == 0)
+ goto freed;
+ if (gc_type == BG_GC && __is_large_section(sbi) &&
+ migrated >= sbi->migration_granularity)
+ continue;
- stat_inc_gc_seg_count(sbi, data_type, gc_type);
- sbi->gc_reclaimed_segs[sbi->gc_mode]++;
- migrated++;
+ sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno);
+ if (type != GET_SUM_TYPE((&sum->footer))) {
+ f2fs_err(sbi, "Inconsistent segment (%u) type "
+ "[%d, %d] in SSA and SIT",
+ cur_segno, type,
+ GET_SUM_TYPE((&sum->footer)));
+ f2fs_stop_checkpoint(sbi, false,
+ STOP_CP_REASON_CORRUPTED_SUMMARY);
+ continue;
+ }
-freed:
- if (gc_type == FG_GC &&
- get_valid_blocks(sbi, segno, false) == 0)
- seg_freed++;
+ /*
+ * this is to avoid deadlock:
+ * - lock_page(sum_page) - f2fs_replace_block
+ * - check_valid_map() - down_write(sentry_lock)
+ * - down_read(sentry_lock) - change_curseg()
+ * - lock_page(sum_page)
+ */
+ if (type == SUM_TYPE_NODE)
+ submitted += gc_node_segment(sbi, sum->entries,
+ cur_segno, gc_type);
+ else
+ submitted += gc_data_segment(sbi, sum->entries,
+ gc_list, cur_segno,
+ gc_type, force_migrate);
- if (__is_large_section(sbi))
- sbi->next_victim_seg[gc_type] =
- (segno + 1 < sec_end_segno) ?
- segno + 1 : NULL_SEGNO;
-skip:
+ stat_inc_gc_seg_count(sbi, data_type, gc_type);
+ sbi->gc_reclaimed_segs[sbi->gc_mode]++;
+ migrated++;
+
+freed:
+ if (gc_type == FG_GC &&
+ get_valid_blocks(sbi, cur_segno, false) == 0)
+ seg_freed++;
+
+ if (__is_large_section(sbi))
+ sbi->next_victim_seg[gc_type] =
+ (cur_segno + 1 < sec_end_segno) ?
+ cur_segno + 1 : NULL_SEGNO;
+ }
+next_block:
folio_put_refs(sum_folio, 2);
+ segno = block_end_segno;
}
if (submitted)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 215e442db72c..af72309b9bfc 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -519,7 +519,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
sum_folio = f2fs_get_sum_folio(sbi, segno);
if (IS_ERR(sum_folio))
return PTR_ERR(sum_folio);
- sum_node = folio_address(sum_folio);
+ sum_node = SUM_BLK_PAGE_ADDR(sum_folio, segno);
sum = sum_node->entries[blkoff];
f2fs_folio_put(sum_folio, true);
got_it:
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b45eace879d7..77aa2125b8ca 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2712,7 +2712,10 @@ struct folio *f2fs_get_sum_folio(struct f2fs_sb_info *sbi, unsigned int segno)
void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
void *src, block_t blk_addr)
{
- struct folio *folio = f2fs_grab_meta_folio(sbi, blk_addr);
+ struct folio *folio = f2fs_get_meta_folio_retry(sbi, blk_addr);
+
+ if (IS_ERR(folio))
+ return;
memcpy(folio_address(folio), src, PAGE_SIZE);
folio_mark_dirty(folio);
@@ -2720,9 +2723,17 @@ void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
}
static void write_sum_page(struct f2fs_sb_info *sbi,
- struct f2fs_summary_block *sum_blk, block_t blk_addr)
+ struct f2fs_summary_block *sum_blk, unsigned int segno)
{
- f2fs_update_meta_page(sbi, (void *)sum_blk, blk_addr);
+ struct folio *folio;
+
+ folio = f2fs_get_sum_folio(sbi, segno);
+ if (IS_ERR(folio))
+ return;
+
+ memcpy(SUM_BLK_PAGE_ADDR(folio, segno), sum_blk, sizeof(*sum_blk));
+ folio_mark_dirty(folio);
+ f2fs_folio_put(folio, true);
}
static void write_current_sum_page(struct f2fs_sb_info *sbi,
@@ -2987,7 +2998,7 @@ static int new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
int ret;
if (curseg->inited)
- write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, segno));
+ write_sum_page(sbi, curseg->sum_blk, segno);
segno = __get_next_segno(sbi, type);
ret = get_new_segment(sbi, &segno, new_sec, pinning);
@@ -3046,7 +3057,7 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type)
struct folio *sum_folio;
if (curseg->inited)
- write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
+ write_sum_page(sbi, curseg->sum_blk, curseg->segno);
__set_test_and_inuse(sbi, new_segno);
@@ -3065,7 +3076,7 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type)
memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE);
return PTR_ERR(sum_folio);
}
- sum_node = folio_address(sum_folio);
+ sum_node = SUM_BLK_PAGE_ADDR(sum_folio, new_segno);
memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
f2fs_folio_put(sum_folio, true);
return 0;
@@ -3154,8 +3165,7 @@ static void __f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi, int type)
goto out;
if (get_valid_blocks(sbi, curseg->segno, false)) {
- write_sum_page(sbi, curseg->sum_blk,
- GET_SUM_BLOCK(sbi, curseg->segno));
+ write_sum_page(sbi, curseg->sum_blk, curseg->segno);
} else {
mutex_lock(&DIRTY_I(sbi)->seglist_lock);
__set_test_and_free(sbi, curseg->segno, true);
@@ -3833,8 +3843,7 @@ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct folio *folio,
if (segment_full) {
if (type == CURSEG_COLD_DATA_PINNED &&
!((curseg->segno + 1) % sbi->segs_per_sec)) {
- write_sum_page(sbi, curseg->sum_blk,
- GET_SUM_BLOCK(sbi, curseg->segno));
+ write_sum_page(sbi, curseg->sum_blk, curseg->segno);
reset_curseg_fields(curseg);
goto skip_new_segment;
}
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 1ce2c8abaf48..e883f14c228f 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -85,8 +85,12 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi,
#define GET_ZONE_FROM_SEG(sbi, segno) \
GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno))
-#define GET_SUM_BLOCK(sbi, segno) \
- ((sbi)->sm_info->ssa_blkaddr + (segno))
+#define SUMS_PER_BLOCK (F2FS_BLKSIZE / F2FS_SUM_BLKSIZE)
+#define GET_SUM_BLOCK(sbi, segno) \
+ (SM_I(sbi)->ssa_blkaddr + (segno / SUMS_PER_BLOCK))
+#define GET_SUM_BLKOFF(segno) (segno % SUMS_PER_BLOCK)
+#define SUM_BLK_PAGE_ADDR(folio, segno) \
+ (folio_address(folio) + GET_SUM_BLKOFF(segno) * F2FS_SUM_BLKSIZE)
#define GET_SUM_TYPE(footer) ((footer)->entry_type)
#define SET_SUM_TYPE(footer, type) ((footer)->entry_type = (type))
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 6e52e36c1f1a..707e24551fdd 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4052,6 +4052,20 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
if (sanity_check_area_boundary(sbi, folio, index))
return -EFSCORRUPTED;
+ /*
+ * Check for legacy summary layout on 16KB+ block devices.
+ * Modern f2fs-tools packs multiple 4KB summary areas into one block,
+ * whereas legacy versions used one block per summary, leading
+ * to a much larger SSA.
+ */
+ if (SUMS_PER_BLOCK > 1 &&
+ !(__F2FS_HAS_FEATURE(raw_super, F2FS_FEATURE_PACKED_SSA))) {
+ f2fs_info(sbi, "Error: Device formatted with a legacy version. "
+ "Please reformat with a tool supporting the packed ssa "
+ "feature for block sizes larger than 4kb.");
+ return -EOPNOTSUPP;
+ }
+
return 0;
}
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 6d2a4fba68a2..5685b454bfd1 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -235,6 +235,9 @@ static ssize_t features_show(struct f2fs_attr *a,
if (f2fs_sb_has_compression(sbi))
len += sysfs_emit_at(buf, len, "%s%s",
len ? ", " : "", "compression");
+ if (f2fs_sb_has_packed_ssa(sbi))
+ len += sysfs_emit_at(buf, len, "%s%s",
+ len ? ", " : "", "packed_ssa");
len += sysfs_emit_at(buf, len, "%s%s",
len ? ", " : "", "pin_file");
len += sysfs_emit_at(buf, len, "\n");
@@ -1296,6 +1299,7 @@ F2FS_FEATURE_RO_ATTR(pin_file);
#ifdef CONFIG_UNICODE
F2FS_FEATURE_RO_ATTR(linear_lookup);
#endif
+F2FS_FEATURE_RO_ATTR(packed_ssa);
#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
static struct attribute *f2fs_attrs[] = {
@@ -1455,6 +1459,7 @@ static struct attribute *f2fs_feat_attrs[] = {
#ifdef CONFIG_UNICODE
BASE_ATTR_LIST(linear_lookup),
#endif
+ BASE_ATTR_LIST(packed_ssa),
NULL,
};
ATTRIBUTE_GROUPS(f2fs_feat);
@@ -1490,6 +1495,7 @@ F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD);
F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION);
F2FS_SB_FEATURE_RO_ATTR(readonly, RO);
F2FS_SB_FEATURE_RO_ATTR(device_alias, DEVICE_ALIAS);
+F2FS_SB_FEATURE_RO_ATTR(packed_ssa, PACKED_SSA);
static struct attribute *f2fs_sb_feat_attrs[] = {
ATTR_LIST(sb_encryption),
@@ -1507,6 +1513,7 @@ static struct attribute *f2fs_sb_feat_attrs[] = {
ATTR_LIST(sb_compression),
ATTR_LIST(sb_readonly),
ATTR_LIST(sb_device_alias),
+ ATTR_LIST(sb_packed_ssa),
NULL,
};
ATTRIBUTE_GROUPS(f2fs_sb_feat);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 6afb4a13b81d..a7880787cad3 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -17,6 +17,7 @@
#define F2FS_LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) /* log number for sector/blk */
#define F2FS_BLKSIZE PAGE_SIZE /* support only block == page */
#define F2FS_BLKSIZE_BITS PAGE_SHIFT /* bits for F2FS_BLKSIZE */
+#define F2FS_SUM_BLKSIZE 4096 /* only support 4096 byte sum block */
#define F2FS_MAX_EXTENSION 64 /* # of extension entries */
#define F2FS_EXTENSION_LEN 8 /* max size of extension */
@@ -441,7 +442,7 @@ struct f2fs_sit_block {
* from node's page's beginning to get a data block address.
* ex) data_blkaddr = (block_t)(nodepage_start_address + ofs_in_node)
*/
-#define ENTRIES_IN_SUM (F2FS_BLKSIZE / 8)
+#define ENTRIES_IN_SUM (F2FS_SUM_BLKSIZE / 8)
#define SUMMARY_SIZE (7) /* sizeof(struct f2fs_summary) */
#define SUM_FOOTER_SIZE (5) /* sizeof(struct summary_footer) */
#define SUM_ENTRY_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM)
@@ -467,7 +468,7 @@ struct summary_footer {
__le32 check_sum; /* summary checksum */
} __packed;
-#define SUM_JOURNAL_SIZE (F2FS_BLKSIZE - SUM_FOOTER_SIZE -\
+#define SUM_JOURNAL_SIZE (F2FS_SUM_BLKSIZE - SUM_FOOTER_SIZE -\
SUM_ENTRY_SIZE)
#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) /\
sizeof(struct nat_journal_entry))
--
2.51.2.1026.g39e6a42477-goog
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
2025-11-04 16:24 [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support Daeho Jeong
@ 2025-11-05 8:20 ` Chao Yu via Linux-f2fs-devel
2025-11-10 9:22 ` Chao Yu via Linux-f2fs-devel
1 sibling, 0 replies; 6+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-11-05 8:20 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 11/5/25 00:24, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> The recent increase in the number of Segment Summary Area (SSA) entries
> from 512 to 2048 was an unintentional change in logic of 16kb block
> support. This commit corrects the issue.
>
> To better utilize the space available from the erroneous 2048-entry
> calculation, we are implementing a solution to share the currently
> unused SSA space with neighboring segments. This enhances overall
> SSA utilization without impacting the established 8MB segment size.
>
> Fixes: d7e9a9037de2 ("f2fs: Support Block Size == Page Size")
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Thanks,
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support
2025-11-04 16:24 [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support Daeho Jeong
2025-11-05 8:20 ` Chao Yu via Linux-f2fs-devel
@ 2025-11-10 9:22 ` Chao Yu via Linux-f2fs-devel
1 sibling, 0 replies; 6+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-11-10 9:22 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 11/5/25 00:24, Daeho Jeong wrote:
> static void write_sum_page(struct f2fs_sb_info *sbi,
> - struct f2fs_summary_block *sum_blk, block_t blk_addr)
> + struct f2fs_summary_block *sum_blk, unsigned int segno)
> {
> - f2fs_update_meta_page(sbi, (void *)sum_blk, blk_addr);
> + struct folio *folio;
w/ 4k-sized block config, I suffered performance regression issue while testing
fallocate() on pinfile.
Seems we need to add below code:
if (SUMS_PER_BLOCK == 1)
return f2fs_update_meta_page(sbi, (void *)sum_blk,
GET_SUM_BLOCK(sbi, segno));
Otherwise, we will load summary block whenever we change segment for curseg.
Thanks,
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-11-10 9:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-04 16:24 [f2fs-dev] [PATCH] f2fs: revert summary entry count from 2048 to 512 in 16kb block support Daeho Jeong
2025-11-05 8:20 ` Chao Yu via Linux-f2fs-devel
2025-11-10 9:22 ` Chao Yu via Linux-f2fs-devel
-- strict thread matches above, loose matches on Subject: below --
2025-10-07 18:08 Daeho Jeong
2025-10-11 3:39 ` kernel test robot
2025-10-11 4:00 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).