Re: [f2fs-dev] [PATCH v7 03/11] f2fs: describe NAT block layout dynamically
From: Daeho Jeong
Date: Mon Aug 31 2026 - 20:41:52 EST
On Mon, Aug 31, 2026 at 3:09 PM Kelvin Zhang <zhangxp1998@xxxxxxxxx> wrote:
>
> A NAT block is a filesystem-block-sized array of struct f2fs_nat_entry
> elements. The compile-time NAT_ENTRY_PER_BLOCK definition hardcodes the
> NAT capacity to a 4KB block size.
>
> Replace the fixed array in struct f2fs_nat_block with a C flexible
> array member, and calculate sbi->nat_entries_per_block dynamically in
> init_sb_info().
>
> Parameterize NAT geometry helpers (NAT_ENTRY_PER_BLOCK,
> NAT_BLOCK_OFFSET, f2fs_start_nid, NAT_BLK_CNT, and
> f2fs_nat_bitmap_size) with sbi. Update call sites across node management,
> checkpointing, GC, and sysfs.
>
> This is a layout-only change without behavioral differences for 4KB
> blocks.
>
> Signed-off-by: Kelvin Zhang <zhangxp1998@xxxxxxxxx>
> ---
> fs/f2fs/checkpoint.c | 4 +--
> fs/f2fs/debug.c | 2 +-
> fs/f2fs/f2fs.h | 2 ++
> fs/f2fs/gc.c | 4 +--
> fs/f2fs/node.c | 77 +++++++++++++++++++++--------------------
> fs/f2fs/node.h | 22 ++++++++----
> fs/f2fs/segment.c | 4 +--
> fs/f2fs/shrinker.c | 2 +-
> fs/f2fs/super.c | 4 ++-
> include/linux/f2fs_fs.h | 5 ++-
> 10 files changed, 71 insertions(+), 55 deletions(-)
>
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index 47c4a5c83a70..3ecced9b4d57 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -476,11 +476,11 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
> switch (type) {
> case META_NAT:
> if (unlikely(blkno >=
> - NAT_BLOCK_OFFSET(NM_I(sbi)->max_nid)))
> + NAT_BLOCK_OFFSET(sbi, NM_I(sbi)->max_nid)))
> blkno = 0;
> /* get nat block addr */
> fio.new_blkaddr = current_nat_addr(sbi,
> - blkno * NAT_ENTRY_PER_BLOCK);
> + blkno * NAT_ENTRY_PER_BLOCK(sbi));
> break;
> case META_SIT:
> if (unlikely(blkno >= TOTAL_SEGS(sbi)))
> diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> index ff379aff4472..5980b9d79afb 100644
> --- a/fs/f2fs/debug.c
> +++ b/fs/f2fs/debug.c
> @@ -345,7 +345,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
> si->base_mem += __bitmap_size(sbi, NAT_BITMAP);
> si->base_mem += F2FS_BLK_TO_BYTES(NM_I(sbi)->nat_bits_blocks);
> si->base_mem += NM_I(sbi)->nat_blocks *
> - f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK);
> + f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK(sbi));
> si->base_mem += NM_I(sbi)->nat_blocks / 8;
> si->base_mem += NM_I(sbi)->nat_blocks * sizeof(unsigned short);
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 035863d513ab..8e6000e7d766 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1863,6 +1863,7 @@ struct f2fs_sb_info {
> unsigned int log_sectors_per_block; /* log2 sectors per block */
> unsigned int log_blocksize; /* log2 block size */
> unsigned int blocksize; /* block size */
> + unsigned int nat_entries_per_block; /* NAT entries in a block */
> unsigned int sit_entries_per_block; /* SIT entries in a block */
> unsigned int root_ino_num; /* root inode number*/
> unsigned int node_ino_num; /* node inode number*/
> @@ -2253,6 +2254,7 @@ static inline struct f2fs_sb_info *F2FS_F_SB(const struct folio *folio)
> }
>
> #define SIT_ENTRY_PER_BLOCK(sbi) ((sbi)->sit_entries_per_block)
> +#define NAT_ENTRY_PER_BLOCK(sbi) ((sbi)->nat_entries_per_block)
>
> static inline struct f2fs_super_block *F2FS_RAW_SUPER(struct f2fs_sb_info *sbi)
> {
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 0a00180c21dc..c15c6ba91597 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -1066,7 +1066,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi,
> continue;
>
> if (phase == 0) {
> - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
> + f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(sbi, nid), 1,
> META_NAT, true);
> continue;
> }
> @@ -1614,7 +1614,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
> continue;
>
> if (phase == 0) {
> - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
> + f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(sbi, nid), 1,
> META_NAT, true);
> continue;
> }
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index 86c2e67e43b6..960c6657d0d6 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -169,7 +169,7 @@ static struct folio *get_next_nat_folio(struct f2fs_sb_info *sbi, nid_t nid)
> folio_mark_dirty(dst_folio);
> f2fs_folio_put(src_folio, true);
>
> - set_to_next_nat(nm_i, nid);
> + set_to_next_nat(sbi, nm_i, nid);
>
> return dst_folio;
> }
> @@ -254,10 +254,11 @@ static void __del_from_nat_cache(struct f2fs_nm_info *nm_i, struct nat_entry *e)
> __free_nat_entry(e);
> }
>
> -static struct nat_entry_set *__grab_nat_entry_set(struct f2fs_nm_info *nm_i,
> +static struct nat_entry_set *__grab_nat_entry_set(struct f2fs_sb_info *sbi,
> + struct f2fs_nm_info *nm_i,
> struct nat_entry *ne)
> {
> - nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid);
> + nid_t set = NAT_BLOCK_OFFSET(sbi, ne->ni.nid);
> struct nat_entry_set *head;
>
> head = radix_tree_lookup(&nm_i->nat_set_root, set);
> @@ -274,14 +275,15 @@ static struct nat_entry_set *__grab_nat_entry_set(struct f2fs_nm_info *nm_i,
> return head;
> }
>
> -static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
> +static void __set_nat_cache_dirty(struct f2fs_sb_info *sbi,
> + struct f2fs_nm_info *nm_i,
> struct nat_entry *ne, bool init_dirty)
> {
> struct nat_entry_set *head;
> bool new_ne = nat_get_blkaddr(ne) == NEW_ADDR;
>
> if (!new_ne)
> - head = __grab_nat_entry_set(nm_i, ne);
> + head = __grab_nat_entry_set(sbi, nm_i, ne);
>
> /*
> * update entry_cnt in below condition:
> @@ -527,7 +529,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
> nat_set_blkaddr(e, new_blkaddr);
> if (!__is_valid_data_blkaddr(new_blkaddr))
> set_nat_flag(e, IS_CHECKPOINTED, false);
> - __set_nat_cache_dirty(nm_i, e, init_dirty);
> + __set_nat_cache_dirty(sbi, nm_i, e, init_dirty);
>
> /* update fsync_mark if its inode nat entry is still alive */
> if (ni->nid != ni->ino)
> @@ -578,7 +580,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
> struct f2fs_journal *journal = curseg->journal;
> - nid_t start_nid = START_NID(nid);
> + nid_t start_nid = f2fs_start_nid(sbi, nid);
> struct f2fs_nat_block *nat_blk;
> struct folio *folio = NULL;
> struct f2fs_nat_entry ne;
> @@ -2403,8 +2405,8 @@ static void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid,
> bool set, bool build)
> {
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> - unsigned int nat_ofs = NAT_BLOCK_OFFSET(nid);
> - unsigned int nid_ofs = nid - START_NID(nid);
> + unsigned int nat_ofs = NAT_BLOCK_OFFSET(sbi, nid);
> + unsigned int nid_ofs = nid - f2fs_start_nid(sbi, nid);
>
> if (!test_bit_le(nat_ofs, nm_i->nat_block_bitmap))
> return;
> @@ -2524,14 +2526,14 @@ static int scan_nat_page(struct f2fs_sb_info *sbi,
> {
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> block_t blk_addr;
> - unsigned int nat_ofs = NAT_BLOCK_OFFSET(start_nid);
> + unsigned int nat_ofs = NAT_BLOCK_OFFSET(sbi, start_nid);
> int i;
>
> __set_bit_le(nat_ofs, nm_i->nat_block_bitmap);
>
> - i = start_nid % NAT_ENTRY_PER_BLOCK;
> + i = start_nid % NAT_ENTRY_PER_BLOCK(sbi);
>
> - for (; i < NAT_ENTRY_PER_BLOCK; i++, start_nid++) {
> + for (; i < NAT_ENTRY_PER_BLOCK(sbi); i++, start_nid++) {
> if (unlikely(start_nid >= nm_i->max_nid))
> break;
>
> @@ -2587,16 +2589,16 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi)
> continue;
> if (!nm_i->free_nid_count[i])
> continue;
> - for (idx = 0; idx < NAT_ENTRY_PER_BLOCK; idx++) {
> + for (idx = 0; idx < NAT_ENTRY_PER_BLOCK(sbi); idx++) {
> idx = find_next_bit_le(nm_i->free_nid_bitmap[i],
> - NAT_ENTRY_PER_BLOCK, idx);
> - if (idx >= NAT_ENTRY_PER_BLOCK)
> + NAT_ENTRY_PER_BLOCK(sbi), idx);
> + if (idx >= NAT_ENTRY_PER_BLOCK(sbi))
> break;
>
> - nid = i * NAT_ENTRY_PER_BLOCK + idx;
> + nid = i * NAT_ENTRY_PER_BLOCK(sbi) + idx;
> add_free_nid(sbi, nid, true, false);
>
> - if (nm_i->nid_cnt[FREE_NID] >= MAX_FREE_NIDS)
> + if (nm_i->nid_cnt[FREE_NID] >= MAX_FREE_NIDS(sbi))
> goto out;
> }
> }
> @@ -2617,11 +2619,11 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
> if (unlikely(nid >= nm_i->max_nid))
> nid = 0;
>
> - if (unlikely(nid % NAT_ENTRY_PER_BLOCK))
> - nid = NAT_BLOCK_OFFSET(nid) * NAT_ENTRY_PER_BLOCK;
> + if (unlikely(nid % NAT_ENTRY_PER_BLOCK(sbi)))
> + nid = NAT_BLOCK_OFFSET(sbi, nid) * NAT_ENTRY_PER_BLOCK(sbi);
>
> /* Enough entries */
> - if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK)
> + if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK(sbi))
> return 0;
>
> if (!sync && !f2fs_available_free_memory(sbi, FREE_NIDS))
> @@ -2631,18 +2633,18 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
> /* try to find free nids in free_nid_bitmap */
> scan_free_nid_bits(sbi);
>
> - if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK)
> + if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK(sbi))
> return 0;
> }
>
> /* readahead nat pages to be scanned */
> - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES,
> + f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(sbi, nid), FREE_NID_PAGES,
> META_NAT, true);
>
> f2fs_down_read_trace(&nm_i->nat_tree_lock, &lc);
>
> while (1) {
> - if (!test_bit_le(NAT_BLOCK_OFFSET(nid),
> + if (!test_bit_le(NAT_BLOCK_OFFSET(sbi, nid),
> nm_i->nat_block_bitmap)) {
> struct folio *folio = get_current_nat_folio(sbi, nid);
>
> @@ -2668,7 +2670,8 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
> }
> }
>
> - nid += (NAT_ENTRY_PER_BLOCK - (nid % NAT_ENTRY_PER_BLOCK));
> + nid += NAT_ENTRY_PER_BLOCK(sbi) -
> + (nid % NAT_ENTRY_PER_BLOCK(sbi));
> if (unlikely(nid >= nm_i->max_nid))
> nid = 0;
>
> @@ -2684,7 +2687,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
>
> f2fs_up_read_trace(&nm_i->nat_tree_lock, &lc);
>
> - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid),
> + f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(sbi, nm_i->next_scan_nid),
> nm_i->ra_nid_pages, META_NAT, false);
>
> return 0;
> @@ -2811,20 +2814,20 @@ int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink)
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> int nr = nr_shrink;
>
> - if (nm_i->nid_cnt[FREE_NID] <= MAX_FREE_NIDS)
> + if (nm_i->nid_cnt[FREE_NID] <= MAX_FREE_NIDS(sbi))
> return 0;
>
> if (!mutex_trylock(&nm_i->build_lock))
> return 0;
>
> - while (nr_shrink && nm_i->nid_cnt[FREE_NID] > MAX_FREE_NIDS) {
> + while (nr_shrink && nm_i->nid_cnt[FREE_NID] > MAX_FREE_NIDS(sbi)) {
> struct free_nid *i, *next;
> unsigned int batch = SHRINK_NID_BATCH_SIZE;
>
> spin_lock(&nm_i->nid_list_lock);
> list_for_each_entry_safe(i, next, &nm_i->free_nid_list, list) {
> if (!nr_shrink || !batch ||
> - nm_i->nid_cnt[FREE_NID] <= MAX_FREE_NIDS)
> + nm_i->nid_cnt[FREE_NID] <= MAX_FREE_NIDS(sbi))
> break;
> __remove_free_nid(sbi, i, FREE_NID);
> kmem_cache_free(free_nid_slab, i);
> @@ -3074,7 +3077,7 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi)
> spin_unlock(&nm_i->nid_list_lock);
> }
>
> - __set_nat_cache_dirty(nm_i, ne, init_dirty);
> + __set_nat_cache_dirty(sbi, nm_i, ne, init_dirty);
> }
> update_nats_in_cursum(journal, -i);
> up_write(&curseg->journal_rwsem);
> @@ -3102,7 +3105,7 @@ static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
> const struct f2fs_nat_block *nat_blk)
> {
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> - unsigned int nat_index = start_nid / NAT_ENTRY_PER_BLOCK;
> + unsigned int nat_index = start_nid / NAT_ENTRY_PER_BLOCK(sbi);
> int valid = 0;
> int i = 0;
>
> @@ -3113,7 +3116,7 @@ static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
> valid = 1;
> i = 1;
> }
> - for (; i < NAT_ENTRY_PER_BLOCK; i++) {
> + for (; i < NAT_ENTRY_PER_BLOCK(sbi); i++) {
> if (le32_to_cpu(nat_blk->entries[i].block_addr) != NULL_ADDR)
> valid++;
> }
> @@ -3124,7 +3127,7 @@ static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
> }
>
> __clear_bit_le(nat_index, nm_i->empty_nat_bits);
> - if (valid == NAT_ENTRY_PER_BLOCK)
> + if (valid == NAT_ENTRY_PER_BLOCK(sbi))
> __set_bit_le(nat_index, nm_i->full_nat_bits);
> else
> __clear_bit_le(nat_index, nm_i->full_nat_bits);
> @@ -3135,7 +3138,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
> {
> struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
> struct f2fs_journal *journal = curseg->journal;
> - nid_t start_nid = set->set * NAT_ENTRY_PER_BLOCK;
> + nid_t start_nid = set->set * NAT_ENTRY_PER_BLOCK(sbi);
> bool to_journal = true;
> struct f2fs_nat_block *nat_blk;
> struct nat_entry *ne, *cur;
> @@ -3342,8 +3345,8 @@ static inline void load_free_nid_bitmap(struct f2fs_sb_info *sbi)
>
> __set_bit_le(i, nm_i->nat_block_bitmap);
>
> - nid = i * NAT_ENTRY_PER_BLOCK;
> - last_nid = nid + NAT_ENTRY_PER_BLOCK;
> + nid = i * NAT_ENTRY_PER_BLOCK(sbi);
> + last_nid = nid + NAT_ENTRY_PER_BLOCK(sbi);
>
> spin_lock(&NM_I(sbi)->nid_list_lock);
> for (; nid < last_nid; nid++)
> @@ -3373,7 +3376,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
> /* segment_count_nat includes pair segment so divide to 2. */
> nat_segs = le32_to_cpu(sb_raw->segment_count_nat) >> 1;
> nm_i->nat_blocks = nat_segs << le32_to_cpu(sb_raw->log_blocks_per_seg);
> - nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nm_i->nat_blocks;
> + nm_i->max_nid = NAT_ENTRY_PER_BLOCK(sbi) * nm_i->nat_blocks;
>
> /* not used nids: 0, node, meta, (and root counted as valid node) */
> nm_i->available_nids = nm_i->max_nid - sbi->total_valid_node_count -
> @@ -3436,7 +3439,7 @@ static int init_free_nid_cache(struct f2fs_sb_info *sbi)
>
> for (i = 0; i < nm_i->nat_blocks; i++) {
> nm_i->free_nid_bitmap[i] = f2fs_kvzalloc(sbi,
> - f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK), GFP_KERNEL);
> + f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK(sbi)), GFP_KERNEL);
> if (!nm_i->free_nid_bitmap[i])
> return -ENOMEM;
> }
> diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
> index 5e114f352099..0dce97aac5fc 100644
> --- a/fs/f2fs/node.h
> +++ b/fs/f2fs/node.h
> @@ -6,14 +6,23 @@
> * http://www.samsung.com/
> */
> /* start node id of a node block dedicated to the given node id */
> -#define START_NID(nid) (((nid) / NAT_ENTRY_PER_BLOCK) * NAT_ENTRY_PER_BLOCK)
> +static inline nid_t f2fs_start_nid(struct f2fs_sb_info *sbi, nid_t nid)
> +{
> + unsigned int entries = NAT_ENTRY_PER_BLOCK(sbi);
> +
> + return (nid / entries) * entries;
> +}
> +
> +#define START_NID(sbi, nid) f2fs_start_nid(sbi, nid)
Do we still need START_NID()? Otherwise, plz, remove it.
Thanks,
>
> /* node block offset on the NAT area dedicated to the given start node id */
> -#define NAT_BLOCK_OFFSET(start_nid) ((start_nid) / NAT_ENTRY_PER_BLOCK)
> +#define NAT_BLOCK_OFFSET(sbi, start_nid) \
> + ((start_nid) / NAT_ENTRY_PER_BLOCK(sbi))
>
> /* # of pages to perform synchronous readahead before building free nids */
> #define FREE_NID_PAGES 8
> -#define MAX_FREE_NIDS (NAT_ENTRY_PER_BLOCK * FREE_NID_PAGES)
> +#define MAX_FREE_NIDS(sbi) ((unsigned long)NAT_ENTRY_PER_BLOCK(sbi) * \
> + FREE_NID_PAGES)
>
> /* size of free nid batch when shrinking */
> #define SHRINK_NID_BATCH_SIZE 8
> @@ -208,7 +217,7 @@ static inline pgoff_t current_nat_addr(struct f2fs_sb_info *sbi, nid_t start)
> * OLD = (segment_off * 512) * 2 + off_in_segment
> * NEW = 2 * (segment_off * 512 + off_in_segment) - off_in_segment
> */
> - block_off = NAT_BLOCK_OFFSET(start);
> + block_off = NAT_BLOCK_OFFSET(sbi, start);
>
> block_addr = (pgoff_t)(nm_i->nat_blkaddr +
> (block_off << 1) -
> @@ -230,9 +239,10 @@ static inline pgoff_t next_nat_addr(struct f2fs_sb_info *sbi,
> return block_addr + nm_i->nat_blkaddr;
> }
>
> -static inline void set_to_next_nat(struct f2fs_nm_info *nm_i, nid_t start_nid)
> +static inline void set_to_next_nat(struct f2fs_sb_info *sbi,
> + struct f2fs_nm_info *nm_i, nid_t start_nid)
> {
> - unsigned int block_off = NAT_BLOCK_OFFSET(start_nid);
> + unsigned int block_off = NAT_BLOCK_OFFSET(sbi, start_nid);
>
> f2fs_change_bit(block_off, nm_i->nat_bitmap);
> #ifdef CONFIG_F2FS_CHECK_FS
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index b3bf1b62cdad..b29df65ab5b7 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -512,10 +512,10 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg)
>
> /* check the # of cached NAT entries */
> if (!f2fs_available_free_memory(sbi, NAT_ENTRIES))
> - f2fs_try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK);
> + f2fs_try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK(sbi));
>
> if (!f2fs_available_free_memory(sbi, FREE_NIDS))
> - f2fs_try_to_free_nids(sbi, MAX_FREE_NIDS);
> + f2fs_try_to_free_nids(sbi, MAX_FREE_NIDS(sbi));
> else
> f2fs_build_free_nids(sbi, false, false);
>
> diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
> index 4f6bf5926de4..e3e0a7e89406 100644
> --- a/fs/f2fs/shrinker.c
> +++ b/fs/f2fs/shrinker.c
> @@ -23,7 +23,7 @@ static unsigned long __count_nat_entries(struct f2fs_sb_info *sbi)
>
> static unsigned long __count_free_nids(struct f2fs_sb_info *sbi)
> {
> - long count = NM_I(sbi)->nid_cnt[FREE_NID] - MAX_FREE_NIDS;
> + long count = NM_I(sbi)->nid_cnt[FREE_NID] - MAX_FREE_NIDS(sbi);
>
> return count > 0 ? count : 0;
> }
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 4bd1c9fb1f7f..fdc2b0c51c06 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4382,6 +4382,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
> le32_to_cpu(raw_super->log_sectors_per_block);
> sbi->log_blocksize = le32_to_cpu(raw_super->log_blocksize);
> sbi->blocksize = BIT(sbi->log_blocksize);
> + sbi->nat_entries_per_block = sbi->blocksize /
> + sizeof(struct f2fs_nat_entry);
> sbi->sit_entries_per_block = sbi->blocksize /
> sizeof(struct f2fs_sit_entry);
> sbi->log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
> @@ -4391,7 +4393,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
> sbi->total_sections = le32_to_cpu(raw_super->section_count);
> sbi->total_node_count = SEGS_TO_BLKS(sbi,
> ((le32_to_cpu(raw_super->segment_count_nat) / 2) *
> - NAT_ENTRY_PER_BLOCK));
> + NAT_ENTRY_PER_BLOCK(sbi)));
> sbi->allocate_section_hint = le32_to_cpu(raw_super->section_count);
> sbi->allocate_section_policy = ALLOCATE_FORWARD_NOHINT;
> F2FS_ROOT_INO(sbi) = le32_to_cpu(raw_super->root_ino);
> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> index ecd6694af572..061f906a7b94 100644
> --- a/include/linux/f2fs_fs.h
> +++ b/include/linux/f2fs_fs.h
> @@ -375,8 +375,6 @@ struct f2fs_node {
> /*
> * For NAT entries
> */
> -#define NAT_ENTRY_PER_BLOCK (F2FS_BLKSIZE / sizeof(struct f2fs_nat_entry))
> -
> struct f2fs_nat_entry {
> __u8 version; /* latest version of cached nat entry */
> __le32 ino; /* inode number */
> @@ -384,7 +382,8 @@ struct f2fs_nat_entry {
> } __packed;
>
> struct f2fs_nat_block {
> - struct f2fs_nat_entry entries[NAT_ENTRY_PER_BLOCK];
> + /* The entry count depends on the filesystem block size. */
> + DECLARE_FLEX_ARRAY(struct f2fs_nat_entry, entries);
> } __packed;
>
> /*
> --
> 2.53.0
>
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@xxxxxxxxxxxxxxxxxxxxx
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel