Re: [f2fs-dev] [DISCUSSION] f2fs: compatibility between compressed files and large folios

Chao Yu via Linux-f2fs-devel <[email protected]> Thu, 30 Jul 2026 21:45:50 +0800
Newsgroups net.sourceforge.lists.linux-f2fs-devel
Message-ID <[email protected]>
Nanzhe,

Thanks for the proposal.

On 7/29/26 08:28, Nanzhe Zhao wrote:
> Hi all,
> 
> Chao Yu and I discussed the compatibility between compressed files and large
> folios.
> 
> The main race scenario is that f2fs_new_inode() creates an inode without the
> compression flag and enables large-folio support for its mapping. Later,
> f2fs_setflags_common() can set the compression flag while large-folio support
> is already enabled for the inode. Neither f2fs_iget() nor f2fs_new_inode()
> can prevent this for an active inode.
> 
> Here are the two approaches I am considering.
> 
> 1. Reject setting the compression flag on a large-folio mapping
> 
> We can reject setting the compression flag in f2fs_setflags_common() if the
> inode mapping supports large folios:
> 
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -2250,6 +2250,9 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
>          if ((iflags ^ masked_flags) & F2FS_COMPR_FL) {
>                  if (masked_flags & F2FS_COMPR_FL) {
>                          if (!f2fs_disable_compressed_file(inode))
>                                  return -EINVAL;
>                  } else {
> +                       if (mapping_large_folio_support(inode->i_mapping))
> +                               return -EOPNOTSUPP;
> +
>                          /* try to convert inline_data to support compression */
>                          int err = f2fs_convert_inline_inode(inode);
>                          if (err)
>                                  return err;
> 
> Another implementation is:
> 
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -2250,6 +2250,9 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
>          if ((iflags ^ masked_flags) & F2FS_COMPR_FL) {
>                  if (masked_flags & F2FS_COMPR_FL) {
>                          if (!f2fs_disable_compressed_file(inode))
>                                  return -EINVAL;
>                  } else {
> +                       if (IS_ENABLED(CONFIG_F2FS_LARGE_FOLIO))
> +                               return -EOPNOTSUPP;
> +
>                          /* try to convert inline_data to support compression */
>                          int err = f2fs_convert_inline_inode(inode);
>                          if (err)
>                                  return err;
> 
> The concern with this approach is that new files trying to set compression
> through the ioctl will be rejected, so compression will not be available. I
> think we can document that enabling large-folio support in f2fs disables
> compression.
> 
> 2. Keep the compression flag and restore order 0
> 
> If the compression flag and compression functionality need to remain
> available, we can restore the mapping order to 0 after set_compress_context()
> successfully sets the compression flag in f2fs_setflags_common():
> 
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -2268,6 +2268,10 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
>                                  return -EINVAL;
>                          }
>                          err = set_compress_context(inode);
> +                       if (!err &&
> +                           mapping_large_folio_support(inode->i_mapping))
> +                               mapping_set_folio_order_range(
> +                                       inode->i_mapping, 0, 0);

I prefer this solution, it keeps f2fs compression functionality available, rather
than just disabling it after we enable large folio. I suspect there is existing
users: applications are using it, I don't want to break any userspace use.

>                          f2fs_up_write(&fi->i_sem);
> 
>                          if (err)
>                                  return err;
> 
> Under normal Android workloads, a file whose compression flag can be set by
> f2fs_setflags_common() has no data blocks. Also, an application will not read
> a newly created file with size 0 and fill the page cache with zeroed large
> folios. Therefore, setting the mapping order to 0 here is safe.
> 
> A theoretical sequence is: create a file, use ftruncate() to extend it to a
> non-zero size without allocating data blocks, read the file holes so that
> zeroed large folios are left in the page cache, and then set the compression
> flag through the ioctl. If truncate_inode_pages() is not called before the
> mapping order is reset, the existing large folios remain in the page cache.
> Also, since mapping_set_folio_order_range() is not atomic, readahead may
> theoretically access the mapping's folio-order flags without holding the inode
> lock. Neither case is expected under normal Android workloads.

Can we call truncate_inode_pages() after mapping_set_folio_order_range()? something
like this:

		filemap_invalidate_lock

		mapping_set_folio_order_range(, 0, 0)
		truncate_inode_pages()

		if (mapping->nrpages) {
			err = -EBUSY;
			goto out_unlock;
		}

		...
		err = set_compress_context(inode);
		...

		filemap_invalidate_unlock

Thanks,

> 
> Jaegeuk previously mentioned that a file could have both the compression flag
> and a large-folio mapping. Its writeback could use the normal large-folio path
> without actually compressing the file. After the inode is evicted and the file
> is opened again, f2fs_iget() would see the compression flag, prevent the
> large-folio mapping from being enabled, and return to the normal order-0 read
> path. Chao Yu pointed out that it would be functionally strange if a file
> with the compression flag was not compressed during its first writeback.
> 
> Please let us know which of the above approaches you think is better, or
> whether we have another better approach.
> 
> Thanks,
> 
> Nanzhe
> 



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel