Skip to content

Commit e48e16f

Browse files
Daeho JeongJaegeuk Kim
authored andcommitted
f2fs: support non-4KB block size without packed_ssa feature
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>
1 parent 1dd3b43 commit e48e16f

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
@@ -545,13 +545,25 @@ struct fsync_inode_entry {
545545
#define nats_in_cursum(jnl) (le16_to_cpu((jnl)->n_nats))
546546
#define sits_in_cursum(jnl) (le16_to_cpu((jnl)->n_sits))
547547

548-
#define nat_in_journal(jnl, i) ((jnl)->nat_j.entries[i].ne)
549-
#define nid_in_journal(jnl, i) ((jnl)->nat_j.entries[i].nid)
550-
#define sit_in_journal(jnl, i) ((jnl)->sit_j.entries[i].se)
551-
#define segno_in_journal(jnl, i) ((jnl)->sit_j.entries[i].segno)
552-
553-
#define MAX_NAT_JENTRIES(jnl) (NAT_JOURNAL_ENTRIES - nats_in_cursum(jnl))
554-
#define MAX_SIT_JENTRIES(jnl) (SIT_JOURNAL_ENTRIES - sits_in_cursum(jnl))
548+
#define nat_in_journal(jnl, i) \
549+
(((struct nat_journal_entry *)(jnl)->nat_j.entries)[i].ne)
550+
#define nid_in_journal(jnl, i) \
551+
(((struct nat_journal_entry *)(jnl)->nat_j.entries)[i].nid)
552+
#define sit_in_journal(jnl, i) \
553+
(((struct sit_journal_entry *)(jnl)->sit_j.entries)[i].se)
554+
#define segno_in_journal(jnl, i) \
555+
(((struct sit_journal_entry *)(jnl)->sit_j.entries)[i].segno)
556+
557+
#define sum_entries(sum) ((struct f2fs_summary *)(sum))
558+
#define sum_journal(sbi, sum) \
559+
((struct f2fs_journal *)((char *)(sum) + \
560+
((sbi)->entries_in_sum * sizeof(struct f2fs_summary))))
561+
#define sum_footer(sbi, sum) \
562+
((struct summary_footer *)((char *)(sum) + (sbi)->sum_blocksize - \
563+
sizeof(struct summary_footer)))
564+
565+
#define MAX_NAT_JENTRIES(sbi, jnl) ((sbi)->nat_journal_entries - nats_in_cursum(jnl))
566+
#define MAX_SIT_JENTRIES(sbi, jnl) ((sbi)->sit_journal_entries - sits_in_cursum(jnl))
555567

556568
static inline int update_nats_in_cursum(struct f2fs_journal *journal, int i)
557569
{
@@ -569,14 +581,6 @@ static inline int update_sits_in_cursum(struct f2fs_journal *journal, int i)
569581
return before;
570582
}
571583

572-
static inline bool __has_cursum_space(struct f2fs_journal *journal,
573-
int size, int type)
574-
{
575-
if (type == NAT_JOURNAL)
576-
return size <= MAX_NAT_JENTRIES(journal);
577-
return size <= MAX_SIT_JENTRIES(journal);
578-
}
579-
580584
/* for inline stuff */
581585
#define DEF_INLINE_RESERVED_SIZE 1
582586
static inline int get_extra_isize(struct inode *inode);
@@ -1809,6 +1813,15 @@ struct f2fs_sb_info {
18091813
bool readdir_ra; /* readahead inode in readdir */
18101814
unsigned int max_io_bytes; /* max io bytes to merge IOs */
18111815

1816+
/* variable summary block units */
1817+
unsigned int sum_blocksize; /* sum block size */
1818+
unsigned int sums_per_block; /* sum block count per block */
1819+
unsigned int entries_in_sum; /* entry count in sum block */
1820+
unsigned int sum_entry_size; /* total entry size in sum block */
1821+
unsigned int sum_journal_size; /* journal size in sum block */
1822+
unsigned int nat_journal_entries; /* nat journal entry count in the journal */
1823+
unsigned int sit_journal_entries; /* sit journal entry count in the journal */
1824+
18121825
block_t user_block_count; /* # of user blocks */
18131826
block_t total_valid_block_count; /* # of valid blocks */
18141827
block_t discard_blks; /* discard command candidats */
@@ -2850,6 +2863,14 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
28502863
return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum);
28512864
}
28522865

2866+
static inline bool __has_cursum_space(struct f2fs_sb_info *sbi,
2867+
struct f2fs_journal *journal, int size, int type)
2868+
{
2869+
if (type == NAT_JOURNAL)
2870+
return size <= MAX_NAT_JENTRIES(sbi, journal);
2871+
return size <= MAX_SIT_JENTRIES(sbi, journal);
2872+
}
2873+
28532874
extern void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync);
28542875
static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
28552876
struct inode *inode, bool is_inode)
@@ -3993,7 +4014,8 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
39934014
block_t len);
39944015
void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
39954016
void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
3996-
int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
4017+
int f2fs_lookup_journal_in_cursum(struct f2fs_sb_info *sbi,
4018+
struct f2fs_journal *journal, int type,
39974019
unsigned int val, int alloc);
39984020
void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
39994021
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
@@ -1782,8 +1782,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17821782

17831783
sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
17841784

1785-
segno = rounddown(segno, SUMS_PER_BLOCK);
1786-
sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, SUMS_PER_BLOCK);
1785+
segno = rounddown(segno, sbi->sums_per_block);
1786+
sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, sbi->sums_per_block);
17871787
/* readahead multi ssa blocks those have contiguous address */
17881788
if (__is_large_section(sbi))
17891789
f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
@@ -1793,17 +1793,17 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
17931793
while (segno < end_segno) {
17941794
struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno);
17951795

1796-
segno += SUMS_PER_BLOCK;
1796+
segno += sbi->sums_per_block;
17971797
if (IS_ERR(sum_folio)) {
17981798
int err = PTR_ERR(sum_folio);
17991799

1800-
end_segno = segno - SUMS_PER_BLOCK;
1801-
segno = rounddown(start_segno, SUMS_PER_BLOCK);
1800+
end_segno = segno - sbi->sums_per_block;
1801+
segno = rounddown(start_segno, sbi->sums_per_block);
18021802
while (segno < end_segno) {
18031803
sum_folio = filemap_get_folio(META_MAPPING(sbi),
18041804
GET_SUM_BLOCK(sbi, segno));
18051805
folio_put_refs(sum_folio, 2);
1806-
segno += SUMS_PER_BLOCK;
1806+
segno += sbi->sums_per_block;
18071807
}
18081808
return err;
18091809
}
@@ -1819,8 +1819,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
18191819
/* find segment summary of victim */
18201820
struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi),
18211821
GET_SUM_BLOCK(sbi, segno));
1822-
unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK)
1823-
+ SUMS_PER_BLOCK;
1822+
unsigned int block_end_segno = rounddown(segno, sbi->sums_per_block)
1823+
+ sbi->sums_per_block;
18241824

18251825
if (block_end_segno > end_segno)
18261826
block_end_segno = end_segno;
@@ -1846,12 +1846,13 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
18461846
migrated >= sbi->migration_granularity)
18471847
continue;
18481848

1849-
sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno);
1850-
if (type != GET_SUM_TYPE((&sum->footer))) {
1849+
sum = SUM_BLK_PAGE_ADDR(sbi, sum_folio, cur_segno);
1850+
if (type != GET_SUM_TYPE(sum_footer(sbi, sum))) {
18511851
f2fs_err(sbi, "Inconsistent segment (%u) type "
18521852
"[%d, %d] in SSA and SIT",
18531853
cur_segno, type,
1854-
GET_SUM_TYPE((&sum->footer)));
1854+
GET_SUM_TYPE(
1855+
sum_footer(sbi, sum)));
18551856
f2fs_stop_checkpoint(sbi, false,
18561857
STOP_CP_REASON_CORRUPTED_SUMMARY);
18571858
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);
@@ -2955,7 +2955,7 @@ int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
29552955
/* scan the node segment */
29562956
last_offset = BLKS_PER_SEG(sbi);
29572957
addr = START_BLOCK(sbi, segno);
2958-
sum_entry = &sum->entries[0];
2958+
sum_entry = sum_entries(sum);
29592959

29602960
for (i = 0; i < last_offset; i += nrpages, addr += nrpages) {
29612961
nrpages = bio_max_segs(last_offset - i);
@@ -3096,7 +3096,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
30963096
* #2, flush nat entries to nat page.
30973097
*/
30983098
if (enabled_nat_bits(sbi, cpc) ||
3099-
!__has_cursum_space(journal, set->entry_cnt, NAT_JOURNAL))
3099+
!__has_cursum_space(sbi, journal, set->entry_cnt, NAT_JOURNAL))
31003100
to_journal = false;
31013101

31023102
if (to_journal) {
@@ -3119,7 +3119,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
31193119
f2fs_bug_on(sbi, nat_get_blkaddr(ne) == NEW_ADDR);
31203120

31213121
if (to_journal) {
3122-
offset = f2fs_lookup_journal_in_cursum(journal,
3122+
offset = f2fs_lookup_journal_in_cursum(sbi, journal,
31233123
NAT_JOURNAL, nid, 1);
31243124
f2fs_bug_on(sbi, offset < 0);
31253125
raw_ne = &nat_in_journal(journal, offset);
@@ -3190,7 +3190,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
31903190
* into nat entry set.
31913191
*/
31923192
if (enabled_nat_bits(sbi, cpc) ||
3193-
!__has_cursum_space(journal,
3193+
!__has_cursum_space(sbi, journal,
31943194
nm_i->nat_cnt[DIRTY_NAT], NAT_JOURNAL))
31953195
remove_nats_in_journal(sbi);
31963196

@@ -3201,7 +3201,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
32013201
set_idx = setvec[found - 1]->set + 1;
32023202
for (idx = 0; idx < found; idx++)
32033203
__adjust_nat_entry_set(setvec[idx], &sets,
3204-
MAX_NAT_JENTRIES(journal));
3204+
MAX_NAT_JENTRIES(sbi, journal));
32053205
}
32063206

32073207
/* 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)