Skip to content

Commit 97e4f47

Browse files
Daeho Jeonggregkh
authored andcommitted
f2fs: support non-4KB block size without packed_ssa feature
commit e48e16f upstream. Currently, F2FS requires the packed_ssa feature to be enabled when utilizing non-4KB block sizes (e.g., 16KB). This restriction limits the flexibility of filesystem formatting options. This patch allows F2FS to support non-4KB block sizes even when the packed_ssa feature is disabled. It adjusts the SSA calculation logic to correctly handle summary entries in larger blocks without the packed layout. Cc: stable@kernel.org Fixes: 7ee8bc3 ("f2fs: revert summary entry count from 2048 to 512 in 16kb block support") Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 995030b commit 97e4f47

8 files changed

Lines changed: 166 additions & 123 deletions

File tree

fs/f2fs/f2fs.h

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -508,13 +508,25 @@ struct fsync_inode_entry {
508508
#define nats_in_cursum(jnl) (le16_to_cpu((jnl)->n_nats))
509509
#define sits_in_cursum(jnl) (le16_to_cpu((jnl)->n_sits))
510510

511-
#define nat_in_journal(jnl, i) ((jnl)->nat_j.entries[i].ne)
512-
#define nid_in_journal(jnl, i) ((jnl)->nat_j.entries[i].nid)
513-
#define sit_in_journal(jnl, i) ((jnl)->sit_j.entries[i].se)
514-
#define segno_in_journal(jnl, i) ((jnl)->sit_j.entries[i].segno)
515-
516-
#define MAX_NAT_JENTRIES(jnl) (NAT_JOURNAL_ENTRIES - nats_in_cursum(jnl))
517-
#define MAX_SIT_JENTRIES(jnl) (SIT_JOURNAL_ENTRIES - sits_in_cursum(jnl))
511+
#define nat_in_journal(jnl, i) \
512+
(((struct nat_journal_entry *)(jnl)->nat_j.entries)[i].ne)
513+
#define nid_in_journal(jnl, i) \
514+
(((struct nat_journal_entry *)(jnl)->nat_j.entries)[i].nid)
515+
#define sit_in_journal(jnl, i) \
516+
(((struct sit_journal_entry *)(jnl)->sit_j.entries)[i].se)
517+
#define segno_in_journal(jnl, i) \
518+
(((struct sit_journal_entry *)(jnl)->sit_j.entries)[i].segno)
519+
520+
#define sum_entries(sum) ((struct f2fs_summary *)(sum))
521+
#define sum_journal(sbi, sum) \
522+
((struct f2fs_journal *)((char *)(sum) + \
523+
((sbi)->entries_in_sum * sizeof(struct f2fs_summary))))
524+
#define sum_footer(sbi, sum) \
525+
((struct summary_footer *)((char *)(sum) + (sbi)->sum_blocksize - \
526+
sizeof(struct summary_footer)))
527+
528+
#define MAX_NAT_JENTRIES(sbi, jnl) ((sbi)->nat_journal_entries - nats_in_cursum(jnl))
529+
#define MAX_SIT_JENTRIES(sbi, jnl) ((sbi)->sit_journal_entries - sits_in_cursum(jnl))
518530

519531
static inline int update_nats_in_cursum(struct f2fs_journal *journal, int i)
520532
{
@@ -532,14 +544,6 @@ static inline int update_sits_in_cursum(struct f2fs_journal *journal, int i)
532544
return before;
533545
}
534546

535-
static inline bool __has_cursum_space(struct f2fs_journal *journal,
536-
int size, int type)
537-
{
538-
if (type == NAT_JOURNAL)
539-
return size <= MAX_NAT_JENTRIES(journal);
540-
return size <= MAX_SIT_JENTRIES(journal);
541-
}
542-
543547
/* for inline stuff */
544548
#define DEF_INLINE_RESERVED_SIZE 1
545549
static inline int get_extra_isize(struct inode *inode);
@@ -1750,6 +1754,15 @@ struct f2fs_sb_info {
17501754
bool readdir_ra; /* readahead inode in readdir */
17511755
u64 max_io_bytes; /* max io bytes to merge IOs */
17521756

1757+
/* variable summary block units */
1758+
unsigned int sum_blocksize; /* sum block size */
1759+
unsigned int sums_per_block; /* sum block count per block */
1760+
unsigned int entries_in_sum; /* entry count in sum block */
1761+
unsigned int sum_entry_size; /* total entry size in sum block */
1762+
unsigned int sum_journal_size; /* journal size in sum block */
1763+
unsigned int nat_journal_entries; /* nat journal entry count in the journal */
1764+
unsigned int sit_journal_entries; /* sit journal entry count in the journal */
1765+
17531766
block_t user_block_count; /* # of user blocks */
17541767
block_t total_valid_block_count; /* # of valid blocks */
17551768
block_t discard_blks; /* discard command candidats */
@@ -2799,6 +2812,14 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
27992812
return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum);
28002813
}
28012814

2815+
static inline bool __has_cursum_space(struct f2fs_sb_info *sbi,
2816+
struct f2fs_journal *journal, int size, int type)
2817+
{
2818+
if (type == NAT_JOURNAL)
2819+
return size <= MAX_NAT_JENTRIES(sbi, journal);
2820+
return size <= MAX_SIT_JENTRIES(sbi, journal);
2821+
}
2822+
28022823
extern void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync);
28032824
static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
28042825
struct inode *inode, bool is_inode)
@@ -3952,7 +3973,8 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
39523973
block_t len);
39533974
void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
39543975
void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
3955-
int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
3976+
int f2fs_lookup_journal_in_cursum(struct f2fs_sb_info *sbi,
3977+
struct f2fs_journal *journal, int type,
39563978
unsigned int val, int alloc);
39573979
void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
39583980
int f2fs_check_and_fix_write_pointer(struct f2fs_sb_info *sbi);

fs/f2fs/gc.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,8 +1766,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17661766

17671767
sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
17681768

1769-
segno = rounddown(segno, SUMS_PER_BLOCK);
1770-
sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, SUMS_PER_BLOCK);
1769+
segno = rounddown(segno, sbi->sums_per_block);
1770+
sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, sbi->sums_per_block);
17711771
/* readahead multi ssa blocks those have contiguous address */
17721772
if (__is_large_section(sbi))
17731773
f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
@@ -1777,17 +1777,17 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17771777
while (segno < end_segno) {
17781778
struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno);
17791779

1780-
segno += SUMS_PER_BLOCK;
1780+
segno += sbi->sums_per_block;
17811781
if (IS_ERR(sum_folio)) {
17821782
int err = PTR_ERR(sum_folio);
17831783

1784-
end_segno = segno - SUMS_PER_BLOCK;
1785-
segno = rounddown(start_segno, SUMS_PER_BLOCK);
1784+
end_segno = segno - sbi->sums_per_block;
1785+
segno = rounddown(start_segno, sbi->sums_per_block);
17861786
while (segno < end_segno) {
17871787
sum_folio = filemap_get_folio(META_MAPPING(sbi),
17881788
GET_SUM_BLOCK(sbi, segno));
17891789
folio_put_refs(sum_folio, 2);
1790-
segno += SUMS_PER_BLOCK;
1790+
segno += sbi->sums_per_block;
17911791
}
17921792
return err;
17931793
}
@@ -1803,8 +1803,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
18031803
/* find segment summary of victim */
18041804
struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi),
18051805
GET_SUM_BLOCK(sbi, segno));
1806-
unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK)
1807-
+ SUMS_PER_BLOCK;
1806+
unsigned int block_end_segno = rounddown(segno, sbi->sums_per_block)
1807+
+ sbi->sums_per_block;
18081808

18091809
if (block_end_segno > end_segno)
18101810
block_end_segno = end_segno;
@@ -1830,12 +1830,13 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
18301830
migrated >= sbi->migration_granularity)
18311831
continue;
18321832

1833-
sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno);
1834-
if (type != GET_SUM_TYPE((&sum->footer))) {
1833+
sum = SUM_BLK_PAGE_ADDR(sbi, sum_folio, cur_segno);
1834+
if (type != GET_SUM_TYPE(sum_footer(sbi, sum))) {
18351835
f2fs_err(sbi, "Inconsistent segment (%u) type "
18361836
"[%d, %d] in SSA and SIT",
18371837
cur_segno, type,
1838-
GET_SUM_TYPE((&sum->footer)));
1838+
GET_SUM_TYPE(
1839+
sum_footer(sbi, sum)));
18391840
f2fs_stop_checkpoint(sbi, false,
18401841
STOP_CP_REASON_CORRUPTED_SUMMARY);
18411842
continue;

fs/f2fs/node.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
606606
goto retry;
607607
}
608608

609-
i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0);
609+
i = f2fs_lookup_journal_in_cursum(sbi, journal, NAT_JOURNAL, nid, 0);
610610
if (i >= 0) {
611611
ne = nat_in_journal(journal, i);
612612
node_info_from_raw_nat(ni, &ne);
@@ -2943,7 +2943,7 @@ int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
29432943
/* scan the node segment */
29442944
last_offset = BLKS_PER_SEG(sbi);
29452945
addr = START_BLOCK(sbi, segno);
2946-
sum_entry = &sum->entries[0];
2946+
sum_entry = sum_entries(sum);
29472947

29482948
for (i = 0; i < last_offset; i += nrpages, addr += nrpages) {
29492949
nrpages = bio_max_segs(last_offset - i);
@@ -3084,7 +3084,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
30843084
* #2, flush nat entries to nat page.
30853085
*/
30863086
if (enabled_nat_bits(sbi, cpc) ||
3087-
!__has_cursum_space(journal, set->entry_cnt, NAT_JOURNAL))
3087+
!__has_cursum_space(sbi, journal, set->entry_cnt, NAT_JOURNAL))
30883088
to_journal = false;
30893089

30903090
if (to_journal) {
@@ -3107,7 +3107,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
31073107
f2fs_bug_on(sbi, nat_get_blkaddr(ne) == NEW_ADDR);
31083108

31093109
if (to_journal) {
3110-
offset = f2fs_lookup_journal_in_cursum(journal,
3110+
offset = f2fs_lookup_journal_in_cursum(sbi, journal,
31113111
NAT_JOURNAL, nid, 1);
31123112
f2fs_bug_on(sbi, offset < 0);
31133113
raw_ne = &nat_in_journal(journal, offset);
@@ -3178,7 +3178,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
31783178
* into nat entry set.
31793179
*/
31803180
if (enabled_nat_bits(sbi, cpc) ||
3181-
!__has_cursum_space(journal,
3181+
!__has_cursum_space(sbi, journal,
31823182
nm_i->nat_cnt[DIRTY_NAT], NAT_JOURNAL))
31833183
remove_nats_in_journal(sbi);
31843184

@@ -3189,7 +3189,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
31893189
set_idx = setvec[found - 1]->set + 1;
31903190
for (idx = 0; idx < found; idx++)
31913191
__adjust_nat_entry_set(setvec[idx], &sets,
3192-
MAX_NAT_JENTRIES(journal));
3192+
MAX_NAT_JENTRIES(sbi, journal));
31933193
}
31943194

31953195
/* flush dirty nats in nat entry set */

fs/f2fs/recovery.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -514,16 +514,16 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
514514
struct curseg_info *curseg = CURSEG_I(sbi, i);
515515

516516
if (curseg->segno == segno) {
517-
sum = curseg->sum_blk->entries[blkoff];
517+
sum = sum_entries(curseg->sum_blk)[blkoff];
518518
goto got_it;
519519
}
520520
}
521521

522522
sum_folio = f2fs_get_sum_folio(sbi, segno);
523523
if (IS_ERR(sum_folio))
524524
return PTR_ERR(sum_folio);
525-
sum_node = SUM_BLK_PAGE_ADDR(sum_folio, segno);
526-
sum = sum_node->entries[blkoff];
525+
sum_node = SUM_BLK_PAGE_ADDR(sbi, sum_folio, segno);
526+
sum = sum_entries(sum_node)[blkoff];
527527
f2fs_folio_put(sum_folio, true);
528528
got_it:
529529
/* Use the locked dnode page and inode */

0 commit comments

Comments
 (0)