From: Chao Yu <chao@kernel.org>
To: Daeho Jeong <daeho43@gmail.com>,
linux-kernel@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net, kernel-team@android.com
Cc: chao@kernel.org, Daeho Jeong <daehojeong@google.com>
Subject: Re: [f2fs-dev] [PATCH 02/20] f2fs: support subpage block size superblock and mount
Date: Tue, 3 Nov 2026 17:26:00 +0800 [thread overview]
Message-ID: <0ac04f29-982c-423c-b65d-ebed996c4a52@kernel.org> (raw)
In-Reply-To: <20261102193952.3002018-3-daeho43@gmail.com>
On 11/3/26 03:39, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> Add the infrastructure to mount F2FS with a block size smaller than
> PAGE_SIZE, e.g. 4KB blocks on a 16KB page kernel.
>
> - Add helpers to convert between block indices, folio indices and
> offsets within a folio.
> - Take the block size from the 1st superblock, which is at the same
> offset for every block size. If it is invalid, probe the 2nd
> superblock with each supported block size.
> - Allow log_blocksize up to PAGE_SHIFT, and write back only the target
> superblock block instead of the whole folio.
> - Keep rejecting subpage block sizes, and return -EOPNOTSUPP for the
> features that do not support them yet. Later patches add the support
> and lift these restrictions.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
> ---
> fs/f2fs/compress.c | 2 +
> fs/f2fs/f2fs.h | 61 ++++++++++++---
> fs/f2fs/file.c | 42 +++++++++++
> fs/f2fs/super.c | 160 ++++++++++++++++++++++++++++------------
> fs/f2fs/verity.c | 3 +
> include/linux/f2fs_fs.h | 1 +
> 6 files changed, 212 insertions(+), 57 deletions(-)
>
> diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> index c7910688c318..0b0f31af6626 100644
> --- a/fs/f2fs/compress.c
> +++ b/fs/f2fs/compress.c
> @@ -550,6 +550,8 @@ bool f2fs_is_compress_backend_ready(struct inode *inode)
> {
> if (!f2fs_compressed_file(inode))
> return true;
> + if (f2fs_has_subpage_blocks(F2FS_I_SB(inode)))
> + return false;
> return f2fs_cops[F2FS_I(inode)->i_compress_algorithm];
> }
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 50a5f845176d..11de12a3e804 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1372,11 +1372,11 @@ struct f2fs_io_info {
> };
>
> #define F2FS_FIO_LBLK(fio) \
> - (((fio)->folio)->index + (fio)->folio_offset)
> + (f2fs_folio_lblk((fio)->sbi, (fio)->folio) + (fio)->folio_offset)
> #define F2FS_FIO_BLKCNT(fio) \
> ((fio)->folio_blkcnt)
> #define F2FS_FIO_BIO_OFFSET(fio) \
> - ((fio)->folio_offset << PAGE_SHIFT)
> + F2FS_BLK_TO_BYTES((fio)->sbi, (fio)->folio_offset)
> #define F2FS_FIO_BIO_SIZE(fio) \
> F2FS_BLK_TO_BYTES((fio)->sbi, F2FS_FIO_BLKCNT(fio))
>
> @@ -2326,19 +2326,59 @@ static inline void make_dentry_ptr_block(struct inode *inode,
> SIZE_OF_DIR_ENTRY * entries;
> }
>
> +static inline unsigned int f2fs_blocks_per_folio(struct f2fs_sb_info *sbi,
> + const struct folio *folio)
> +{
> + return folio_size(folio) >> sbi->log_blocksize;
> +}
> +
> +static inline bool f2fs_has_subpage_blocks(struct f2fs_sb_info *sbi)
> +{
> + return F2FS_BLKSIZE(sbi) < PAGE_SIZE;
> +}
> +
> +static inline pgoff_t f2fs_folio_lblk(struct f2fs_sb_info *sbi,
> + const struct folio *folio)
> +{
> + return ((loff_t)folio->index << PAGE_SHIFT) >> sbi->log_blocksize;
> +}
> +
> +static inline pgoff_t f2fs_lblk_to_folio_index(struct f2fs_sb_info *sbi,
> + pgoff_t index)
> +{
> + return F2FS_BLK_TO_BYTES(sbi, index) >> PAGE_SHIFT;
> +}
> +
> +static inline pgoff_t f2fs_folio_blk_offset(struct f2fs_sb_info *sbi,
> + const struct folio *folio,
> + pgoff_t index)
> +{
> + return index - f2fs_folio_lblk(sbi, folio);
> +}
> +
> +static inline size_t f2fs_folio_byte_offset(struct f2fs_sb_info *sbi,
> + const struct folio *folio,
> + pgoff_t index)
> +{
> + return F2FS_BLK_TO_BYTES(sbi, f2fs_folio_blk_offset(sbi, folio, index));
> +}
> +
> +static inline void *f2fs_folio_lblk_address(struct f2fs_sb_info *sbi,
> + struct folio *folio, pgoff_t index)
> +{
> + return folio_address(folio) + f2fs_folio_byte_offset(sbi, folio, index);
> +}
> +
> static inline struct f2fs_super_block *F2FS_RAW_SUPER(struct f2fs_sb_info *sbi)
> {
> return (struct f2fs_super_block *)(sbi->raw_super);
> }
>
> -static inline struct f2fs_super_block *F2FS_SUPER_BLOCK(struct folio *folio,
> - pgoff_t index)
> +static inline struct f2fs_super_block *
> +F2FS_SUPER_BLOCK(struct f2fs_sb_info *sbi, struct folio *folio, pgoff_t index)
> {
> - pgoff_t idx_in_folio = index % folio_nr_pages(folio);
> -
> return (struct f2fs_super_block *)
> - (page_address(folio_page(folio, idx_in_folio)) +
> - F2FS_SUPER_OFFSET);
> + (f2fs_folio_lblk_address(sbi, folio, index) + F2FS_SUPER_OFFSET);
> }
>
> static inline struct f2fs_checkpoint *F2FS_CKPT(struct f2fs_sb_info *sbi)
> @@ -3905,11 +3945,10 @@ static inline bool f2fs_is_time_consistent(struct inode *inode)
>
> static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
> {
> + struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> bool ret;
>
> if (dsync) {
> - struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> -
> spin_lock(&sbi->inode_lock[DIRTY_META]);
> ret = list_empty(&F2FS_I(inode)->gdirty_list);
> spin_unlock(&sbi->inode_lock[DIRTY_META]);
> @@ -3917,7 +3956,7 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
> }
> if (!is_inode_flag_set(inode, FI_AUTO_RECOVER) ||
> file_keep_isize(inode) ||
> - i_size_read(inode) & ~PAGE_MASK)
> + i_size_read(inode) & (F2FS_BLKSIZE(sbi) - 1))
Use F2FS_BLKSIZE_MASK(sbi) for cleanup
> return false;
>
> if (!f2fs_is_time_consistent(inode))
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 93d3088c96f0..82eb62301c48 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -2207,6 +2207,15 @@ static long f2fs_fallocate(struct file *file, int mode,
> goto out;
> }
>
> + if (f2fs_has_subpage_blocks(F2FS_I_SB(inode))) {
> + if ((mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)) ||
> + f2fs_is_pinned_file(inode) || f2fs_is_atomic_file(inode) ||
> + f2fs_compressed_file(inode)) {
> + ret = -EOPNOTSUPP;
> + goto out;
> + }
> + }
> +
> ret = file_modified(file);
> if (ret)
> goto out;
> @@ -2455,6 +2464,9 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
> loff_t isize;
> int ret;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!(filp->f_mode & FMODE_WRITE))
> return -EBADF;
>
> @@ -3262,6 +3274,9 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg)
> struct f2fs_defragment range;
> int err;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!capable(CAP_SYS_ADMIN))
> return -EPERM;
>
> @@ -3484,6 +3499,9 @@ static int f2fs_ioc_move_range(struct file *filp, unsigned long arg)
> {
> struct f2fs_move_range range;
>
> + if (f2fs_has_subpage_blocks(F2FS_I_SB(file_inode(filp))))
> + return -EOPNOTSUPP;
> +
> if (copy_from_user(&range, (struct f2fs_move_range __user *)arg,
> sizeof(range)))
> return -EFAULT;
> @@ -3734,6 +3752,9 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg)
> __u32 pin;
> int ret = 0;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (get_user(pin, (__u32 __user *)arg))
> return -EFAULT;
>
> @@ -4114,6 +4135,9 @@ static int f2fs_ioc_resize_fs(struct file *filp, unsigned long arg)
> struct f2fs_sb_info *sbi = F2FS_I_SB(file_inode(filp));
> __u64 block_count;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!capable(CAP_SYS_ADMIN))
> return -EPERM;
>
> @@ -4131,6 +4155,9 @@ static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg)
> {
> struct inode *inode = file_inode(filp);
>
> + if (f2fs_has_subpage_blocks(F2FS_I_SB(inode)))
> + return -EOPNOTSUPP;
> +
> f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
>
> if (!f2fs_sb_has_verity(F2FS_I_SB(inode))) {
> @@ -4311,6 +4338,9 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
> int ret;
> int writecount;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!f2fs_sb_has_compression(sbi))
> return -EOPNOTSUPP;
>
> @@ -4506,6 +4536,9 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
> unsigned int reserved_blocks = 0;
> int ret;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!f2fs_sb_has_compression(sbi))
> return -EOPNOTSUPP;
>
> @@ -4827,6 +4860,9 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
> struct f2fs_comp_option option;
> int ret = 0;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!f2fs_sb_has_compression(sbi))
> return -EOPNOTSUPP;
>
> @@ -4965,6 +5001,9 @@ static int f2fs_ioc_decompress_file(struct file *filp)
> pgoff_t page_idx = 0, last_idx, cluster_idx;
> int ret;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!f2fs_sb_has_compression(sbi) ||
> F2FS_OPTION(sbi).compress_mode != COMPR_MODE_USER)
> return -EOPNOTSUPP;
> @@ -5046,6 +5085,9 @@ static int f2fs_ioc_compress_file(struct file *filp)
> pgoff_t page_idx = 0, last_idx, cluster_idx;
> int ret;
>
> + if (f2fs_has_subpage_blocks(sbi))
> + return -EOPNOTSUPP;
> +
> if (!f2fs_sb_has_compression(sbi) ||
> F2FS_OPTION(sbi).compress_mode != COMPR_MODE_USER)
> return -EOPNOTSUPP;
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 78dbf1e92285..f34558b661eb 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4000,7 +4000,7 @@ static int __f2fs_commit_super(struct f2fs_sb_info *sbi, struct folio *folio,
> folio_lock(folio);
> folio_wait_writeback(folio);
> if (update)
> - memcpy(F2FS_SUPER_BLOCK(folio, index), F2FS_RAW_SUPER(sbi),
> + memcpy(F2FS_SUPER_BLOCK(sbi, folio, index), F2FS_RAW_SUPER(sbi),
> sizeof(struct f2fs_super_block));
> folio_mark_dirty(folio);
> folio_clear_dirty_for_io(folio);
> @@ -4010,9 +4010,10 @@ static int __f2fs_commit_super(struct f2fs_sb_info *sbi, struct folio *folio,
> bio = bio_alloc(sbi->sb->s_bdev, 1, opf, GFP_NOFS);
>
> /* it doesn't need to set crypto context for superblock update */
> - bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(sbi, folio->index);
> + bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(sbi, index);
>
> - if (!bio_add_folio(bio, folio, folio_size(folio), 0))
> + if (!bio_add_folio(bio, folio, F2FS_BLKSIZE(sbi),
> + f2fs_folio_byte_offset(sbi, folio, index)))
> f2fs_bug_on(sbi, 1);
>
> ret = submit_bio_wait(bio);
> @@ -4025,7 +4026,7 @@ static int __f2fs_commit_super(struct f2fs_sb_info *sbi, struct folio *folio,
> static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
> struct folio *folio, pgoff_t index)
> {
> - struct f2fs_super_block *raw_super = F2FS_SUPER_BLOCK(folio, index);
> + struct f2fs_super_block *raw_super = F2FS_SUPER_BLOCK(sbi, folio, index);
> struct super_block *sb = sbi->sb;
> u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
> u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr);
> @@ -4107,11 +4108,13 @@ static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
> res = "internally";
> } else {
> /*
> - * __f2fs_commit_super() will access log_blocksize
> - * in SECTOR_FROM_BLOCK(), init it in advance.
> + * __f2fs_commit_super() will access log_blocksize and
> + * blocksize to locate the superblock, init them in
> + * advance.
> */
> sbi->log_blocksize =
> le32_to_cpu(raw_super->log_blocksize);
> + sbi->blocksize = BIT(sbi->log_blocksize);
> err = __f2fs_commit_super(sbi, folio, index, false);
> res = err ? "failed" : "done";
> }
> @@ -4129,7 +4132,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
> {
> block_t segment_count, segs_per_sec, secs_per_zone, segment_count_main;
> block_t total_sections, blocks_per_seg;
> - struct f2fs_super_block *raw_super = F2FS_SUPER_BLOCK(folio, index);
> + struct f2fs_super_block *raw_super = F2FS_SUPER_BLOCK(sbi, folio, index);
> size_t crc_offset = 0;
> __u32 crc = 0;
>
> @@ -4155,14 +4158,23 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
> }
> }
>
> - /* only support block_size equals to PAGE_SIZE */
> - if (le32_to_cpu(raw_super->log_blocksize) != PAGE_SHIFT) {
> - f2fs_info(sbi, "Invalid log_blocksize (%u), supports only %u",
> + /* Keep one or more filesystem blocks in each base-page folio. */
> + if (le32_to_cpu(raw_super->log_blocksize) <
> + F2FS_MIN_LOG_BLOCKSIZE ||
> + le32_to_cpu(raw_super->log_blocksize) > F2FS_MAX_LOG_BLOCKSIZE) {
> + f2fs_info(sbi, "Invalid log_blocksize (%u), supports %u..%u",
> le32_to_cpu(raw_super->log_blocksize),
> - PAGE_SHIFT);
> + F2FS_MIN_LOG_BLOCKSIZE, F2FS_MAX_LOG_BLOCKSIZE);
> return -EFSCORRUPTED;
> }
>
> + /* Subpage block size is enabled after all paths support it. */
> + if (le32_to_cpu(raw_super->log_blocksize) != PAGE_SHIFT) {
> + f2fs_info(sbi, "Subpage block size (%u) is not supported yet",
> + le32_to_cpu(raw_super->log_blocksize));
> + return -EOPNOTSUPP;
> + }
> +
> /* check log blocks per segment */
> if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) {
> f2fs_info(sbi, "Invalid log blocks per segment (%u)",
> @@ -4181,7 +4193,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
> }
> if (le32_to_cpu(raw_super->log_sectors_per_block) +
> le32_to_cpu(raw_super->log_sectorsize) !=
> - F2FS_MAX_LOG_SECTOR_SIZE) {
> + le32_to_cpu(raw_super->log_blocksize)) {
> f2fs_info(sbi, "Invalid log sectors per block(%u) log sectorsize(%u)",
> le32_to_cpu(raw_super->log_sectors_per_block),
> le32_to_cpu(raw_super->log_sectorsize));
> @@ -4703,56 +4715,103 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
> * to get the first valid one. If any one of them is broken, we pass
> * them recovery flag back to the caller.
> */
> +static int check_super_block(struct f2fs_sb_info *sbi,
> + struct f2fs_super_block *super,
> + int block, int *valid_super_block,
> + struct f2fs_super_block **raw_super)
> +{
> + struct folio *folio;
> + int err;
> +
> + folio = read_mapping_folio(sbi->sb->s_bdev->bd_mapping,
> + f2fs_lblk_to_folio_index(sbi, block), NULL);
> + if (IS_ERR(folio))
> + return PTR_ERR(folio);
> +
> + /* Skip unmatched magic during probing to avoid noisy logs */
> + if (block != 0 && !*raw_super &&
> + le32_to_cpu(F2FS_SUPER_BLOCK(sbi, folio, block)->magic) !=
> + F2FS_SUPER_MAGIC) {
> + folio_put(folio);
> + return -EINVAL;
err = -EINVAL;
goto out_put;
> + }
> +
> + /*
> + * The 2nd superblock was located with sbi->log_blocksize. Check it
> + * before sanity_check_raw_super(), which may write the superblock
> + * back with its own log_blocksize.
> + */
> + err = 0;
> + if (block) {
Can we combine above "if (block != 0)" and "if (block)":
if (block) {
/* ... */
if (!*raw_super &&
le32_to_cpu(F2FS_SUPER_BLOCK(sbi, folio, block)->magic) !=
F2FS_SUPER_MAGIC) {
...
}
/* ... */
if (log_bs != sbi->log_blocksize) {
...
}
}
> + u32 log_bs = le32_to_cpu(F2FS_SUPER_BLOCK(sbi, folio,
> + block)->log_blocksize);
> +
> + if (log_bs != sbi->log_blocksize) {
> + f2fs_info(sbi, "Mismatched log_blocksize (%u) in 2nd superblock, expected %u",
> + log_bs, sbi->log_blocksize);
> + err = -EFSCORRUPTED;
goto out_put;
Then we can clean up below !err check.
> + }
> + }
> + if (!err)
> + err = sanity_check_raw_super(sbi, folio, block);
err = sanity_check_raw_super(sbi, folio, block);
> + if (!err && !*raw_super) {
> + memcpy(super, F2FS_SUPER_BLOCK(sbi, folio, block),
> + sizeof(*super));
> + *valid_super_block = block;
> + *raw_super = super;
> + sbi->log_blocksize = le32_to_cpu(super->log_blocksize);
> + sbi->blocksize = BIT(sbi->log_blocksize);
> + }
out_put:
> + folio_put(folio);
> + return err;
> +}
> +
> static int read_raw_super_block(struct f2fs_sb_info *sbi,
> struct f2fs_super_block **raw_super,
> int *valid_super_block, int *recovery)
> {
> - struct super_block *sb = sbi->sb;
> - int block;
> - struct folio *folio;
> struct f2fs_super_block *super;
> - int err = 0;
> + int log_bs, err;
>
> super = kzalloc_obj(struct f2fs_super_block);
> if (!super)
> return -ENOMEM;
>
> - for (block = 0; block < 2; block++) {
> - folio = read_mapping_folio(sb->s_bdev->bd_mapping, block, NULL);
> - if (IS_ERR(folio)) {
> - f2fs_err(sbi, "Unable to read %dth superblock",
> - block + 1);
> - err = PTR_ERR(folio);
> - *recovery = 1;
> - continue;
> - }
> + /* 1. Read 1st superblock (block 0) */
> + err = check_super_block(sbi, super, 0, valid_super_block, raw_super);
> + if (err) {
> + f2fs_err(sbi, "Can't find valid F2FS filesystem in 1st superblock");
> + *recovery = 1;
> + }
>
> - /* sanity checking of raw super */
> - err = sanity_check_raw_super(sbi, folio, block);
> - if (err) {
> - f2fs_err(sbi, "Can't find valid F2FS filesystem in %dth superblock",
> - block + 1);
> - folio_put(folio);
> + /* 2. Read 2nd superblock (block 1) */
> + if (*raw_super) {
> + if (check_super_block(sbi, super, 1, valid_super_block, raw_super)) {
> + f2fs_err(sbi, "Can't find valid F2FS filesystem in 2nd superblock");
> *recovery = 1;
> - continue;
> }
> -
> + } else {
> + for (log_bs = F2FS_MIN_LOG_BLOCKSIZE;
> + log_bs <= F2FS_MAX_LOG_BLOCKSIZE; log_bs++) {
> + sbi->log_blocksize = log_bs;
> + sbi->blocksize = BIT(log_bs);
> + err = check_super_block(sbi, super, 1, valid_super_block,
> + raw_super);
> + if (!err)
> + break;
Later err = -EINVAL due to sb magic mismatch (not exist) will overwrite previous
err = -EFSCORRUPTED due to sb corruption, how about not overwriting it for such case?
to get correct error number.
> + }
> if (!*raw_super) {
> - memcpy(super, F2FS_SUPER_BLOCK(folio, block),
> - sizeof(*super));
> - *valid_super_block = block;
> - *raw_super = super;
> + f2fs_err(sbi, "Can't find valid F2FS filesystem in 2nd superblock");
> + *recovery = 1;
Not needed to set *recovery, because both superblocks are corrupted.
Thanks,
> }
> - folio_put(folio);
> }
>
> - /* No valid superblock */
> - if (!*raw_super)
> + /* No valid superblock: return the error of the last probe. */
> + if (!*raw_super) {
> kfree(super);
> - else
> - err = 0;
> -
> - return err;
> + return err;
> + }
> + return 0;
> }
>
> int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
> @@ -4777,7 +4836,8 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
>
> /* write back-up superblock first */
> index = sbi->valid_super_block ? 0 : 1;
> - folio = read_mapping_folio(sbi->sb->s_bdev->bd_mapping, index, NULL);
> + folio = read_mapping_folio(sbi->sb->s_bdev->bd_mapping,
> + f2fs_lblk_to_folio_index(sbi, index), NULL);
> if (IS_ERR(folio))
> return PTR_ERR(folio);
> err = __f2fs_commit_super(sbi, folio, index, true);
> @@ -4789,7 +4849,8 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
>
> /* write current valid superblock */
> index = sbi->valid_super_block;
> - folio = read_mapping_folio(sbi->sb->s_bdev->bd_mapping, index, NULL);
> + folio = read_mapping_folio(sbi->sb->s_bdev->bd_mapping,
> + f2fs_lblk_to_folio_index(sbi, index), NULL);
> if (IS_ERR(folio))
> return PTR_ERR(folio);
> err = __f2fs_commit_super(sbi, folio, index, true);
> @@ -5263,6 +5324,13 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
> }
> mutex_init(&sbi->flush_lock);
>
> + /*
> + * The 1st superblock is at F2FS_SUPER_OFFSET of block 0 for every
> + * block size, so locate it with the minimum supported block size.
> + */
> + sbi->log_blocksize = F2FS_MIN_LOG_BLOCKSIZE;
> + sbi->blocksize = F2FS_MIN_BLKSIZE;
> +
> err = read_raw_super_block(sbi, &raw_super, &valid_super_block,
> &recovery);
> if (err)
> diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
> index 4a2cea4288f9..af1b7f21c1d8 100644
> --- a/fs/f2fs/verity.c
> +++ b/fs/f2fs/verity.c
> @@ -94,6 +94,9 @@ static int f2fs_begin_enable_verity(struct file *filp)
> struct inode *inode = file_inode(filp);
> int err;
>
> + if (f2fs_has_subpage_blocks(F2FS_I_SB(inode)))
> + return -EOPNOTSUPP;
> +
> if (f2fs_verity_in_progress(inode))
> return -EBUSY;
>
> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> index 3081702b1ddb..1b3276d57bce 100644
> --- a/include/linux/f2fs_fs.h
> +++ b/include/linux/f2fs_fs.h
> @@ -15,6 +15,7 @@
> #define F2FS_MIN_LOG_SECTOR_SIZE 9 /* 9 bits for 512 bytes */
> #define F2FS_MAX_LOG_SECTOR_SIZE PAGE_SHIFT /* Max is Block Size */
> #define F2FS_MIN_LOG_BLOCKSIZE 12
> +#define F2FS_MAX_LOG_BLOCKSIZE PAGE_SHIFT
> #define F2FS_MIN_BLKSIZE 4096UL
> #define F2FS_MAX_BLKSIZE PAGE_SIZE
> #define F2FS_MAX_EXTENSION 64 /* # of extension entries */
next prev parent reply other threads:[~2026-11-03 9:26 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 19:39 [PATCH 00/20] f2fs: support block size smaller than PAGE_SIZE Daeho Jeong
2026-11-02 19:39 ` [PATCH 01/20] f2fs: use block-based index and size calculations in remaining paths Daeho Jeong
2026-11-03 7:04 ` [f2fs-dev] " Chao Yu
2026-11-02 19:39 ` [PATCH 02/20] f2fs: support subpage block size superblock and mount Daeho Jeong
2026-11-03 9:26 ` Chao Yu [this message]
2026-11-02 19:39 ` [PATCH 03/20] f2fs: extend f2fs_folio_state for subpage blocks Daeho Jeong
2026-11-02 19:39 ` [PATCH 04/20] f2fs: support subpage blocks in directory operations Daeho Jeong
2026-11-02 19:39 ` [PATCH 05/20] f2fs: convert inode dirty page counters to dirty block counters Daeho Jeong
2026-11-02 19:39 ` [PATCH 06/20] f2fs: support subpage blocks in data read path and GC Daeho Jeong
2026-11-02 19:39 ` [PATCH 07/20] f2fs: support subpage blocks in data write path and writeback Daeho Jeong
2026-11-02 19:39 ` [PATCH 08/20] f2fs: adapt range operations and mmap for subpage blocks Daeho Jeong
2026-11-02 19:39 ` [PATCH 09/20] f2fs: support subpage blocks in pinned files Daeho Jeong
2026-11-02 19:39 ` [PATCH 10/20] f2fs: support subpage blocks in collapse and insert range Daeho Jeong
2026-11-02 19:39 ` [PATCH 11/20] f2fs: support subpage blocks in move range Daeho Jeong
2026-11-02 19:39 ` [PATCH 12/20] f2fs: support subpage blocks in defragmentation Daeho Jeong
2026-11-02 19:39 ` [PATCH 13/20] f2fs: support subpage blocks in swapfile activation Daeho Jeong
2026-11-02 19:39 ` [PATCH 14/20] f2fs: support subpage blocks in fs-verity enablement Daeho Jeong
2026-11-02 19:39 ` [PATCH 15/20] f2fs: support subpage blocks in atomic writes Daeho Jeong
2026-11-02 19:39 ` [PATCH 16/20] f2fs: preserve inline data in subpage block mode Daeho Jeong
2026-11-02 19:39 ` [PATCH 17/20] f2fs: support subpage blocks in online resize Daeho Jeong
2026-11-02 19:39 ` [PATCH 18/20] f2fs: support subpage blocks in compression Daeho Jeong
2026-11-02 19:39 ` [PATCH 19/20] f2fs: count compress cache entries in pages for its memory limit Daeho Jeong
2026-11-02 19:39 ` [PATCH 20/20] f2fs: enable subpage block size support Daeho Jeong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0ac04f29-982c-423c-b65d-ebed996c4a52@kernel.org \
--to=chao@kernel.org \
--cc=daeho43@gmail.com \
--cc=daehojeong@google.com \
--cc=kernel-team@android.com \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®