[f2fs-dev] [PATCH] f2fs: remove unreachable lazytime mount option parsing

2024-06-28 Thread Eric Sandeen
The lazytime/nolazytime options are now handled in the VFS, and are
never seen in filesystem parsers, so remove handling of these
options from f2fs.

Note: when lazytime support was added in 6d94c74ab85f it made
lazytime the default in default_options() - as a result, lazytime
cannot be disabled (because Opt_nolazytime is never seen in f2fs
parsing).

If lazytime is desired to be configurable, and default off is OK,
default_options() could be updated to stop setting it by default
and allow mount option control.

Signed-off-by: Eric Sandeen 
---

(I came across this when looking at mount API conversion, which still
has not gotten very far, sorry!)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 1f1b3647a998..12bf7f014fc4 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -151,8 +151,6 @@ enum {
Opt_mode,
Opt_fault_injection,
Opt_fault_type,
-   Opt_lazytime,
-   Opt_nolazytime,
Opt_quota,
Opt_noquota,
Opt_usrquota,
@@ -229,8 +227,6 @@ static match_table_t f2fs_tokens = {
{Opt_mode, "mode=%s"},
{Opt_fault_injection, "fault_injection=%u"},
{Opt_fault_type, "fault_type=%u"},
-   {Opt_lazytime, "lazytime"},
-   {Opt_nolazytime, "nolazytime"},
{Opt_quota, "quota"},
{Opt_noquota, "noquota"},
{Opt_usrquota, "usrquota"},
@@ -918,12 +914,6 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
f2fs_info(sbi, "fault_type options not supported");
break;
 #endif
-   case Opt_lazytime:
-   sb->s_flags |= SB_LAZYTIME;
-   break;
-   case Opt_nolazytime:
-   sb->s_flags &= ~SB_LAZYTIME;
-   break;
 #ifdef CONFIG_QUOTA
case Opt_quota:
case Opt_usrquota:



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 0/9] f2fs: new mount API conversion

2024-08-30 Thread Eric Sandeen
Just FWIW - 

I had missed this thread when I got temporarily unsubscribed from fsdevel.
I have a series that I was hacking on for this same work, at
https://git.kernel.org/pub/scm/linux/kernel/git/sandeen/linux.git/commit/?h=f2fs-mount-api
but it's very rough and almost certainly contains bugs. It may or may not
be of any help to you, but just FYI.

I'll try to help review/test your series since I tried to solve this as
well, but I never completed the work. :)

Thanks,
-Eric

On 8/27/24 6:47 AM, Hongbo Li wrote:
> Does there exist CI test for f2fs? I can only write the mount test for f2fs 
> refer to tests/ext4/053. And I have tested this in local.
> 
> Thanks,
> Hongbo
> 
> On 2024/8/14 10:39, Hongbo Li wrote:
>> Since many filesystems have done the new mount API conversion,
>> we introduce the new mount API conversion in f2fs.
>>
>> The series can be applied on top of the current mainline tree
>> and the work is based on the patches from Lukas Czerner (has
>> done this in ext4[1]). His patch give me a lot of ideas.
>>
>> Here is a high level description of the patchset:
>>
>> 1. Prepare the f2fs mount parameters required by the new mount
>> API and use it for parsing, while still using the old API to
>> get mount options string. Split the parameter parsing and
>> validation of the parse_options helper into two separate
>> helpers.
>>
>>    f2fs: Add fs parameter specifications for mount options
>>    f2fs: move the option parser into handle_mount_opt
>>    f2fs: move option validation into a separate helper
>>
>> 2. Remove the use of sb/sbi structure of f2fs from all the
>> parsing code, because with the new mount API the parsing is
>> going to be done before we even get the super block. In this
>> part, we introduce f2fs_fs_context to hold the temporary
>> options when parsing. For the simple options check, it has
>> to be done during parsing by using f2fs_fs_context structure.
>> For the check which needs sb/sbi, we do this during super
>> block filling.
>>
>>    f2fs: Allow sbi to be NULL in f2fs_printk
>>    f2fs: Add f2fs_fs_context to record the mount options
>>    f2fs: separate the options parsing and options checking
>>
>> 3. Switch the f2fs to use the new mount API for mount and
>> remount.
>>
>>    f2fs: introduce fs_context_operation structure
>>    f2fs: switch to the new mount api
>>
>> 4. Cleanup the old unused structures and helpers.
>>
>>    f2fs: remove unused structure and functions
>>
>> There is still a potential to do some cleanups and perhaps
>> refactoring. However that can be done later after the conversion
>> to the new mount API which is the main purpose of the patchset.
>>
>> [1] https://lore.kernel.org/all/20211021114508.21407-1-lczer...@redhat.com/
>>
>> Hongbo Li (9):
>>    f2fs: Add fs parameter specifications for mount options
>>    f2fs: move the option parser into handle_mount_opt
>>    f2fs: move option validation into a separate helper
>>    f2fs: Allow sbi to be NULL in f2fs_printk
>>    f2fs: Add f2fs_fs_context to record the mount options
>>    f2fs: separate the options parsing and options checking
>>    f2fs: introduce fs_context_operation structure
>>    f2fs: switch to the new mount api
>>    f2fs: remove unused structure and functions
>>
>>   fs/f2fs/super.c | 2211 ---
>>   1 file changed, 1341 insertions(+), 870 deletions(-)
>>
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 1/9] f2fs: Add fs parameter specifications for mount options

2024-08-30 Thread Eric Sandeen
On 8/13/24 9:39 PM, Hongbo Li wrote:
> Use an array of `fs_parameter_spec` called f2fs_param_specs to
> hold the mount option specifications for the new mount api.
> 
> Signed-off-by: Hongbo Li 
> ---
>  fs/f2fs/super.c | 79 +
>  1 file changed, 79 insertions(+)
> 
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 3959fd137cc9..1bd923a73c1f 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -28,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "f2fs.h"
>  #include "node.h"
> @@ -189,9 +190,87 @@ enum {
>   Opt_memory_mode,
>   Opt_age_extent_cache,
>   Opt_errors,
> + Opt_jqfmt,
> + Opt_checkpoint,

If adding an opt_jqfmt to use with an enum, you can/should remove
Opt_jqfmt_vfsold Opt_jqfmt_vfsv0, and Opt_jqfmt_vfsv1, because they
are no longer used.

Similarly for Opt_checkpoint_disable_* symbols.

>   Opt_err,
>  };
>  
> +static const struct constant_table f2fs_param_jqfmt[] = {
> + {"vfsold",  QFMT_VFS_OLD},
> + {"vfsv0",   QFMT_VFS_V0},
> + {"vfsv1",   QFMT_VFS_V1},
> + {}
> +};
> +
> +static const struct fs_parameter_spec f2fs_param_specs[] = {
> + fsparam_string("background_gc", Opt_gc_background),
> + fsparam_flag("disable_roll_forward", Opt_disable_roll_forward),
> + fsparam_flag("norecovery", Opt_norecovery),

Many/most other filesystems tab-align the param_spec, like

...
+   fsparam_string  ("background_gc",   Opt_gc_background),
+   fsparam_flag("disable_roll_forward",Opt_disable_roll_forward),
+   fsparam_flag("norecovery",  Opt_norecovery),
...

but that's just a style thing, up to you and the maintainers.

I'd also suggest making more use of enums (as you did for f2fs_param_jqfmt).
I think it can simplify parsing in the long run if you choose to. It avoids
the "if strcmp() else if strcmp() else if strcmp()... pattern, for example
you can do:

static const struct constant_table f2fs_param_background_gc[] = {
{"on",  BGGC_MODE_ON},
{"off", BGGC_MODE_OFF},
{"sync",BGGC_MODE_SYNC},
{}
};

...

fsparam_enum("background_gc",   Opt_gc_background, 
f2fs_param_background_gc),

...

and then parsing becomes simply:

case Opt_gc_background:
F2FS_CTX_INFO(ctx).bggc_mode = result.uint_32;
ctx->spec_mask |= F2FS_SPEC_background_gc;
break;

When I tried this I made a lot of use of enums, see
https://git.kernel.org/pub/scm/linux/kernel/git/sandeen/linux.git/tree/fs/f2fs/super.c?h=f2fs-mount-api#n182
and see what you think?

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH v2 20/23] xfs: add fs-verity support

2023-04-05 Thread Eric Sandeen
On 4/4/23 11:27 AM, Darrick J. Wong wrote:
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index d40de32362b1..b6e99ed3b187 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -30,6 +30,7 @@
>  #include "xfs_filestream.h"
>  #include "xfs_quota.h"
>  #include "xfs_sysfs.h"
> +#include "xfs_verity.h"
>  #include "xfs_ondisk.h"
>  #include "xfs_rmap_item.h"
>  #include "xfs_refcount_item.h"
> @@ -1489,6 +1490,9 @@ xfs_fs_fill_super(
>   sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
>  #endif
>   sb->s_op = &xfs_super_operations;
> +#ifdef CONFIG_FS_VERITY
> + sb->s_vop = &xfs_verity_ops;
> +#endif
>  

Hi Andrey - it might be nicer to just do:

fsverity_set_ops(sb, &xfs_verity_ops);

here and use the (existing) helper to avoid the #ifdef.  (the #ifdef is handled 
by the helper)

(ext4 & btrfs could use this too ...)

Thanks!

-Eric


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] xfstests: generic/342 run failed in f2fs

2017-12-24 Thread Eric Sandeen
On 12/24/17 9:28 PM, Chen Rong wrote:
> Hi, everyone:
> 
> the issue as below:

First we need to look - what does the test do?

# Test that if we rename a file, create a new file that has the old name of the
# other file and is a child of the same parent directory, fsync the new inode,
# power fail and mount the filesystem, we do not lose the first file and that
# file has the name it was renamed to.

Ok, so it is a test of fsync'd file renames/creation over simulated device
failure, and wants to be sure that all files and file contents are as
expected if data integrity syscalls were made before the device failure.

> # ./check generic/342
> FSTYP -- f2fs
> PLATFORM  -- Linux/x86_64 node01 4.15.0-rc4
> MKFS_OPTIONS  -- /dev/sde1
> MOUNT_OPTIONS -- -o acl,user_xattr /dev/sde1 /tmp/test1
> 
> generic/342  - output mismatch (see 
> /home/ubuntu/git/xfstests-dev/results//generic/342.out.bad)
>     --- tests/generic/342.out   2017-12-13 13:47:20.14400 -0500
>     +++ /home/ubuntu/git/xfstests-dev/results//generic/342.out.bad 2017-12-25 
> 11:13:12.92800 -0500
>     @@ -8,8 +8,7 @@
>  48c940ba3b8671d3d6ea74e4ccad8ca3  SCRATCH_MNT/a/bar
>  Directory a/ contents after log replay:
>  SCRATCH_MNT/a:
>     -bar

the test created foo, fsynced it, then renamed it to bar and created a
/new/ file also named foo, then fsynced the new file foo.

Despite that 2nd fsync, the renamed file "bar" is not present in
your case.

However, don't we really need to fsync the directory after
the rename and recreation to ensure persistence?

iows:  does this patch make the test pass on f2fs?  It does
for me, and I think it's the only valid way to run the test:

diff --git a/tests/generic/342 b/tests/generic/342
index ed64e05..6a9e5bd 100755
--- a/tests/generic/342
+++ b/tests/generic/342
@@ -68,6 +68,7 @@ sync
 mv $SCRATCH_MNT/a/foo $SCRATCH_MNT/a/bar
 $XFS_IO_PROG -f -c "pwrite -S 0xba 0 16K" $SCRATCH_MNT/a/foo | _filter_xfs_io
 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a/foo
+$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a
 
 echo "File digests before log replay:"
 md5sum $SCRATCH_MNT/a/foo | _filter_scratch

without an fsync of the parent dir, I don't think we can
guarantee that filename changes or additions will persist
on every filesystem.

>  foo
>  File digests after log replay:
>  9e5d56a1f9b2c93589f9d55480f971a1  SCRATCH_MNT/a/foo
>     ...
>     (Run 'diff -u tests/generic/342.out 
> /home/ubuntu/git/xfstests-dev/results//generic/342.out.bad'  to see the 
> entire diff)

Generally best to do that suggested diff command to see if 
there are any more pieces of changed/wrong test output.

> Ran: generic/342
> Failures: generic/342
> Failed 1 of 1 tests
> 
> Is it a problem with my computer or a already known issue with f2fs?

or a problem with the test itself ...

-Eric
 
> thanks!
> 
> -- 
> To unsubscribe from this list: send the line "unsubscribe fstests" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] xfstests: generic/342 run failed in f2fs

2017-12-24 Thread Eric Sandeen


On 12/24/17 10:30 PM, Chen Rong wrote:
> 
> 
> On 2017年12月25日 13:56, Eric Sandeen wrote:
>> On 12/24/17 9:28 PM, Chen Rong wrote:
>>> Hi, everyone:
>>>
>>> the issue as below:
>> First we need to look - what does the test do?
>>
>> # Test that if we rename a file, create a new file that has the old name of 
>> the
>> # other file and is a child of the same parent directory, fsync the new 
>> inode,
>> # power fail and mount the filesystem, we do not lose the first file and that
>> # file has the name it was renamed to.
>>
>> Ok, so it is a test of fsync'd file renames/creation over simulated device
>> failure, and wants to be sure that all files and file contents are as
>> expected if data integrity syscalls were made before the device failure.
>>
>>> # ./check generic/342
>>> FSTYP -- f2fs
>>> PLATFORM  -- Linux/x86_64 node01 4.15.0-rc4
>>> MKFS_OPTIONS  -- /dev/sde1
>>> MOUNT_OPTIONS -- -o acl,user_xattr /dev/sde1 /tmp/test1
>>>
>>> generic/342  - output mismatch (see 
>>> /home/ubuntu/git/xfstests-dev/results//generic/342.out.bad)
>>>  --- tests/generic/342.out   2017-12-13 13:47:20.14400 -0500
>>>  +++ /home/ubuntu/git/xfstests-dev/results//generic/342.out.bad 
>>> 2017-12-25 11:13:12.92800 -0500
>>>  @@ -8,8 +8,7 @@
>>>   48c940ba3b8671d3d6ea74e4ccad8ca3  SCRATCH_MNT/a/bar
>>>   Directory a/ contents after log replay:
>>>   SCRATCH_MNT/a:
>>>  -bar
>> the test created foo, fsynced it, then renamed it to bar and created a
>> /new/ file also named foo, then fsynced the new file foo.
>>
>> Despite that 2nd fsync, the renamed file "bar" is not present in
>> your case.
>>
>> However, don't we really need to fsync the directory after
>> the rename and recreation to ensure persistence?
>>
>> iows:  does this patch make the test pass on f2fs?  It does
>> for me, and I think it's the only valid way to run the test:
> the patch works for me. but btrfs could pass the test without it, why so 
> different?

Filesystems are free to do /more/ than the minimum required by posix -
see ext4_sync_parent for example.  Or xfs_finish_rename, for synchronous
mounts:

 * If this is a synchronous mount, make sure that the rename transaction
 * goes to disk before returning to the user.
 */
if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
xfs_trans_set_sync(tp);

so behavior can be fs-dependent, or mount option dependent, etc.

But to be portable, if an app wants directory changes to be persistent
before proceeding, it must fsync the directory after making changes.

I don't know about f2fs's design intent, whether it guarantees more
than posix requires, but to guarantee that this test works on any posix
fs, I think that directory fsync is needed.

-Eric

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] xfstests: generic/342 run failed in f2fs

2017-12-28 Thread Eric Sandeen
On 12/28/17 1:09 AM, Dave Chinner wrote:
...

> There's a whole lot more detail in the kernel commit 2be63d5ce929
> ("Btrfs: fix file loss on log replay after renaming a file and
> fsync") but my point is that we considered this a btrfs filesystem
> bug and so changing the test defeats it's purpose as a regression
> test for the btrfs bug.
> 
> So IMO the test should not be changed. And I think we should be
> consistent and consider this f2fs failure as a f2fs bug that needs
> fixing to bring it's behaviour in line with xfs, ext4, and btrfs.
> 
> Remember this when quoting POSIX about fsync behaviour: Posix is a
> terrible standard when it comes to data integrity. We go way, way
> beyond what POSIX specifies as a valid fsync implementation (i.e.
> posix allows "do nothing and return success" as a conformant
> implementation). Ext4, XFS and btrfs all have strictly ordered
> metadata crash recovery semantics and all of the crash recovery
> tests expect this behaviour from the filesytem being tested. The
> underlying intention is that by encoding it into these tests, all
> widely used and future linux filesystems meet or exceed this crash
> integrity requirement.
> 
> IOWs, changing the test is the wrong thing to do on many levels
> 
> Cheers,
> 
> Dave.
> 

Thanks for digging into the btrfs commit which changed the behavior
tested by this testcase, I had meant to do that. 

Yeah, that's all fair, for sure.  But this shouldn't be implicit in the
testcase; it should explicitly document that it is testing a de-facto
new standard adhered to by several filesystems, what that standard is,
etc, and not leave it to the reader.  ;)  

If a filesystem explicitly chooses not to adhere to that standard they
/could/ opt out of the test.

It's makes a lot of sense for linux filesystems to behave in consistent
ways, but if we're going to start enforcing that through xfstests we
need to be very clear about it, IMHO.


-Eric

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] doc: cgroup: add f2fs and xfs to supported list for writeback

2020-06-29 Thread Eric Sandeen
f2fs and xfs have both added support for cgroup writeback:

578c647 f2fs: implement cgroup writeback support
adfb5fb xfs: implement cgroup aware writeback

so add them to the supported list in the docs.

Signed-off-by: Eric Sandeen 
---

TBH I wonder about the wisdom of having this detail in
the doc, as it apparently gets missed quite often ...

diff --git a/Documentation/admin-guide/cgroup-v2.rst 
b/Documentation/admin-guide/cgroup-v2.rst
index ce3e05e..4f82afa 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -1684,9 +1684,9 @@ per-cgroup dirty memory states are examined and the more 
restrictive
 of the two is enforced.
 
 cgroup writeback requires explicit support from the underlying
-filesystem.  Currently, cgroup writeback is implemented on ext2, ext4
-and btrfs.  On other filesystems, all writeback IOs are attributed to
-the root cgroup.
+filesystem.  Currently, cgroup writeback is implemented on ext2, ext4,
+btrfs, f2fs, and xfs.  On other filesystems, all writeback IOs are 
+attributed to the root cgroup.
 
 There are inherent differences in memory and writeback management
 which affects how cgroup ownership is tracked.  Memory is tracked per



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] doc: cgroup: add f2fs and xfs to supported list for writeback

2020-06-30 Thread Eric Sandeen
On 6/30/20 12:42 AM, Christoph Hellwig wrote:
> On Mon, Jun 29, 2020 at 02:08:09PM -0500, Eric Sandeen wrote:
>> f2fs and xfs have both added support for cgroup writeback:
>>
>> 578c647 f2fs: implement cgroup writeback support
>> adfb5fb xfs: implement cgroup aware writeback
>>
>> so add them to the supported list in the docs.
>>
>> Signed-off-by: Eric Sandeen 
>> ---
>>
>> TBH I wonder about the wisdom of having this detail in
>> the doc, as it apparently gets missed quite often ...
> 
> I'd rather remove the list of file systems.  It has no chance of
> staying uptodate.

Is there any way for a user to know whether a filesytem does or doesn't
support it, in practice?

Thanks,
-Eric


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] doc: cgroup: add f2fs and xfs to supported list for writeback

2020-07-01 Thread Eric Sandeen
On 7/1/20 3:32 AM, Christoph Hellwig wrote:
> On Tue, Jun 30, 2020 at 08:59:34AM -0500, Eric Sandeen wrote:
>> On 6/30/20 12:42 AM, Christoph Hellwig wrote:
>>> On Mon, Jun 29, 2020 at 02:08:09PM -0500, Eric Sandeen wrote:
>>>> f2fs and xfs have both added support for cgroup writeback:
>>>>
>>>> 578c647 f2fs: implement cgroup writeback support
>>>> adfb5fb xfs: implement cgroup aware writeback
>>>>
>>>> so add them to the supported list in the docs.
>>>>
>>>> Signed-off-by: Eric Sandeen 
>>>> ---
>>>>
>>>> TBH I wonder about the wisdom of having this detail in
>>>> the doc, as it apparently gets missed quite often ...
>>>
>>> I'd rather remove the list of file systems.  It has no chance of
>>> staying uptodate.
>>
>> Is there any way for a user to know whether a filesytem does or doesn't
>> support it, in practice?
> 
> git-grep SB_I_CGROUPWB

Sure, but that's not quite what I meant by "a user" :)  So I'll take that
as a no.

Thanks,
-Eric


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 1/2] src/godown: support f2fs triggering specific ioctl

2015-01-08 Thread Eric Sandeen
On 1/8/15 12:31 PM, Jaegeuk Kim wrote:
> This patch triggers the F2FS-related ioctl for godown.

hohum, wouldn't it be a whole lot easier to just re-use the XFS ioctl
number in f2fs?  Then you wouldn't have to duplicate all this code.

If you really want your own unique ioctl number, what about
just doing statfs on the target, and if f_type returns F2FS_SUPER_MAGIC,
swictch the ioctl nr to F2FS_IOC_GOINGDOWN.

Then if not F2FS_SUPER_MAGIC, leave the ioctl nr at XFS_IOC_GOINGDOWN, and
if it fails, it fails (other filesystems might support the original nr.)

And then you can probably just add "f2fs" to the existing testcase,
and move it to tests/shared?

-Eric

> Signed-off-by: Jaegeuk Kim 
> ---
>  src/godown.c | 88 
> 
>  1 file changed, 65 insertions(+), 23 deletions(-)
> 
> diff --git a/src/godown.c b/src/godown.c
> index b140a41..b44790b 100644
> --- a/src/godown.c
> +++ b/src/godown.c
> @@ -19,33 +19,82 @@
>  #include 
>  #include "global.h"
>  
> +#define F2FS_IOCTL_MAGIC 0xf5
> +#define F2FS_IOC_GOINGDOWN   _IO(F2FS_IOCTL_MAGIC, 6)
> +
> +enum ftypes {
> + XFS_FS,
> + F2FS_FS,
> +};
> +
>  static char *xprogname;
> +static char *mnt_dir;
> +static int verbose_opt = 0;
> +static int flushlog_opt = 0;
>  
> +static enum ftypes fs = XFS_FS;
>  
>  static void
>  usage(void)
>  {
> - fprintf(stderr, "usage: %s [-f] [-v] mnt-dir\n", xprogname);
> + fprintf(stderr, "usage: %s [-f] [-v] [-s 0/1] mnt-dir\n", xprogname);
> +}
> +
> +static int
> +xfs_goingdown(int fd)
> +{
> + int flag;
> +
> + flag = (flushlog_opt ? XFS_FSOP_GOING_FLAGS_LOGFLUSH
> + : XFS_FSOP_GOING_FLAGS_NOLOGFLUSH);
> + if (verbose_opt) {
> + printf("Calling XFS_IOC_GOINGDOWN\n");
> + }
> +
> + syslog(LOG_WARNING, "xfstests-induced forced shutdown of %s:\n",
> + mnt_dir);
> + if ((xfsctl(mnt_dir, fd, XFS_IOC_GOINGDOWN, &flag)) == -1) {
> + fprintf(stderr, "%s: error on xfsctl(GOINGDOWN) of \"%s\": 
> %s\n",
> + xprogname, mnt_dir, strerror(errno));
> + return 1;
> + }
> + return 0;
> +}
> +
> +static int
> +f2fs_goingdown(int fd)
> +{
> + if (verbose_opt) {
> + printf("Calling F2FS_IOC_GOINGDOWN\n");
> + }
> + syslog(LOG_WARNING, "xfstests-induced forced shutdown of %s:\n",
> + mnt_dir);
> + if ((ioctl(fd, F2FS_IOC_GOINGDOWN)) == -1) {
> + fprintf(stderr, "%s: error on ioctl(GOINGDOWN) of \"%s\": %s\n",
> + xprogname, mnt_dir, strerror(errno));
> + return 1;
> + }
> + return 0;
> +
>  }
>  
>  int
>  main(int argc, char *argv[])
>  {
> - int c;
> - int flag;
> - int flushlog_opt = 0;
> - int verbose_opt = 0;
> + int c, fd;
>   struct stat st;
> - char *mnt_dir;
> - int fd;
> + int ret = 0;
>  
>   xprogname = argv[0];
>  
> - while ((c = getopt(argc, argv, "fv")) != -1) {
> + while ((c = getopt(argc, argv, "fs:v")) != -1) {
>   switch (c) {
>   case 'f':
>   flushlog_opt = 1;
>   break;
> + case 's':
> + fs = atoi(optarg);
> + break;
>   case 'v':
>   verbose_opt = 1;
>   break;
> @@ -94,10 +143,6 @@ main(int argc, char *argv[])
>   }
>  #endif
>  
> -
> - flag = (flushlog_opt ? XFS_FSOP_GOING_FLAGS_LOGFLUSH 
> - : XFS_FSOP_GOING_FLAGS_NOLOGFLUSH);
> -
>   if (verbose_opt) {
>   printf("Opening \"%s\"\n", mnt_dir);
>   }
> @@ -107,18 +152,15 @@ main(int argc, char *argv[])
>   return 1;
>   }
>  
> - if (verbose_opt) {
> - printf("Calling XFS_IOC_GOINGDOWN\n");
> + switch (fs) {
> + case XFS_FS:
> + ret = xfs_goingdown(fd);
> + break;
> + case F2FS_FS:
> + ret = f2fs_goingdown(fd);
> + break;
>   }
> - syslog(LOG_WARNING, "xfstests-induced forced shutdown of %s:\n",
> - mnt_dir);
> - if ((xfsctl(mnt_dir, fd, XFS_IOC_GOINGDOWN, &flag)) == -1) {
> - fprintf(stderr, "%s: error on xfsctl(GOINGDOWN) of \"%s\": 
> %s\n",
> - xprogname, mnt_dir, strerror(errno));
> - return 1;
> - }
> -
>   close(fd);
>  
> - return 0;
> + return ret;
>  }
> 


--
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net

Re: [f2fs-dev] [PATCH 2/6] f2fs: support goingdown for fs shutdown

2015-01-08 Thread Eric Sandeen
On 1/8/15 12:10 PM, Jaegeuk Kim wrote:
> This patch add an ioctl to shutdown f2fs, which stops all the further block
> writes after this point.

would it make sense to just re-use the xfs ioctl nr, if the semantics are
the same?

That way any test using it will "just work" on f2fs...

-Eric

> Signed-off-by: Jaegeuk Kim 
> ---
>  fs/f2fs/f2fs.h |  1 +
>  fs/f2fs/file.c | 14 ++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index ba30218..febad35 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -209,6 +209,7 @@ static inline bool __has_cursum_space(struct 
> f2fs_summary_block *sum, int size,
>  #define F2FS_IOC_START_VOLATILE_WRITE_IO(F2FS_IOCTL_MAGIC, 3)
>  #define F2FS_IOC_RELEASE_VOLATILE_WRITE  _IO(F2FS_IOCTL_MAGIC, 4)
>  #define F2FS_IOC_ABORT_VOLATILE_WRITE_IO(F2FS_IOCTL_MAGIC, 5)
> +#define F2FS_IOC_GOINGDOWN   _IO(F2FS_IOCTL_MAGIC, 6)
>  
>  #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
>  /*
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 5df3367..de2f669 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -1020,6 +1020,18 @@ static int f2fs_ioc_abort_volatile_write(struct file 
> *filp)
>   return ret;
>  }
>  
> +static int f2fs_ioc_goingdown(struct file *filp)
> +{
> + struct inode *inode = file_inode(filp);
> + struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + f2fs_stop_checkpoint(sbi);
> + return 0;
> +}
> +
>  static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
>  {
>   struct inode *inode = file_inode(filp);
> @@ -1067,6 +1079,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, 
> unsigned long arg)
>   return f2fs_ioc_release_volatile_write(filp);
>   case F2FS_IOC_ABORT_VOLATILE_WRITE:
>   return f2fs_ioc_abort_volatile_write(filp);
> + case F2FS_IOC_GOINGDOWN:
> + return f2fs_ioc_goingdown(filp);
>   case FITRIM:
>   return f2fs_ioc_fitrim(filp, arg);
>   default:
> 


--
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 2/6] f2fs: support goingdown for fs shutdown

2015-01-08 Thread Eric Sandeen
On 1/8/15 2:18 PM, Jaegeuk Kim wrote:
> On Thu, Jan 08, 2015 at 01:54:20PM -0600, Eric Sandeen wrote:
>> On 1/8/15 12:10 PM, Jaegeuk Kim wrote:
>>> This patch add an ioctl to shutdown f2fs, which stops all the further block
>>> writes after this point.
>>
>> would it make sense to just re-use the xfs ioctl nr, if the semantics are
>> the same?
> 
> The semantics are not same for now.
> In order to reuse xfs ioctl, it needs to support options for flushing logs.

the xfs iotl has 3 behaviors optional:

#define XFS_FSOP_GOING_FLAGS_DEFAULT0x0 /* going down */
#define XFS_FSOP_GOING_FLAGS_LOGFLUSH   0x1 /* flush log but not 
data */
#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor 
data */

if f2fs currently supports a subset, you could just -EOPNOTSUPP on the others.

If the semantics are completely different, maybe it shouldn't share the
name at all.  ;)

Just a thought...

-Eric

> Thanks,
> 
>>
>> That way any test using it will "just work" on f2fs...
>>
>> -Eric


--
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 1/2] generic/065: f2fs serves 64KB size with zero data

2015-02-26 Thread Eric Sandeen
On 2/26/15 7:23 PM, Jaegeuk Kim wrote:
> The f2fs provides 64KB size with 0 data after fsync was done to directory 
> file.
> 
> Cc: Filipe Manana 
> Signed-off-by: Jaegeuk Kim 
> ---
>  tests/generic/065 | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/tests/generic/065 b/tests/generic/065
> index b5a296d..3d2b437 100755
> --- a/tests/generic/065
> +++ b/tests/generic/065
> @@ -139,6 +139,10 @@ ext3)
>   # a 64Kb file, with all bytes having the value 0xff
>   [ $hello_digest == "ecb99e6ffea7be1e5419350f725da86b" ] && digest_ok=yes
>   ;;
> +f2fs)
> + # a 64Kb file, with all bytes having the value 0
> + [ $hello_digest == "fcd6bcb56c1689fcef28b57c22475bad" ] && digest_ok=yes
> + ;;

whoa... I will admit to having poorly reviewed this test.  Given that this file 
was
never fsynced, I don't think the test should be looking at file contents *at 
all*
I'll do an ex post facto review, I think, and really, I think all of the above 
should
just be removed from the test.  Without fsync, we don't know what's in the file.
(ext3 could be mounted with writeback mode, for example).

-Eric

>  *)
>   # an empty file
>   [ $hello_digest == "d41d8cd98f00b204e9800998ecf8427e" ] && digest_ok=yes
> 


--
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] Revert "f2fs: remove unreachable lazytime mount option parsing"

2024-11-20 Thread Eric Sandeen
On 11/20/24 8:27 AM, Eric Sandeen wrote:
> On 11/12/24 3:39 PM, Jaegeuk Kim wrote:
>> Hi Eric,
>>
>> Could you please check this revert as it breaks the mount()?
>> It seems F2FS needs to implement new mount support.
>>
>> Thanks,
> 
> I'm sorry, I missed this email. I will look into it more today.

Ok, I see that I had not considered a direct mount call passing
the lazytime option strings. :(

Using mount(8), "lazytime" is never passed as an option all the way to f2fs,
nor is "nolazytime" -

# mount -o loop,nolazytime f2fsfile.img mnt
# mount | grep lazytime
/root/f2fs-test/f2fsfile.img on /root/f2fs-test/mnt type f2fs 
(rw,relatime,lazytime,seclabel,background_gc=on,nogc_merge,discard,discard_unit=block,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,barrier,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,checkpoint_merge,fsync_mode=posix,memory=normal,errors=continue)

(note that lazytime is still set despite -o nolazytime)

when mount(8) is using the new mount API, it does do fsconfig for (no)lazytime:

fsconfig(3, FSCONFIG_SET_FLAG, "nolazytime", NULL, 0) = 0

but that is consumed by the VFS and never sent into f2fs for parsing.

And because default_options() does:

sbi->sb->s_flags |= SB_LAZYTIME;

by default, it overrides the "nolazytime" that the vfs had previously handled.

I'm fairly sure that when mount(8) was using the old mount API (long ago) it 
also
did not send in the lazytime option string - it sent it as a flag instead.

However - a direct call to mount(2) /will/ pass those options all the way
to f2fs, and parse_options() does need to handle them there or it will be 
rejected
as an invalid option.

(Note that f2fs is the only filesystem that attempts to handle lazytime within
the filesystem itself):

[linux]# grep -r \"lazytime\" fs/*/
fs/f2fs/super.c:{Opt_lazytime, "lazytime"},
[linux]#

I'm not entirely sure how to untangle all this, but regressions are not 
acceptable,
so please revert my commit for now.

Thanks,
-Eric


> As for f2fs new mount API support, I have been struggling with it for a
> long time, f2fs has been uniquely complex. The assumption that the superblock
> and on-disk features are known at option parsing time makes it much more
> difficult than most other filesystems.
> 
> But if there's a problem/regression with this commit, I have no objection to
> reverting the commit for now, and I'm sorry for the error.
> 
> -Eric
> 
>> On 11/12, Jaegeuk Kim wrote:
>>> This reverts commit 54f43a10fa257ad4af02a1d157fefef6ebcfa7dc.
>>>
>>> The above commit broke the lazytime mount, given
>>>
>>> mount("/dev/vdb", "/mnt/test", "f2fs", 0, "lazytime");
>>>
>>> CC: sta...@vger.kernel.org # 6.11+
>>> Signed-off-by: Daniel Rosenberg 
>>> Signed-off-by: Jaegeuk Kim 
>>> ---
>>>  fs/f2fs/super.c | 10 ++
>>>  1 file changed, 10 insertions(+)
>>>
>>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>>> index 49519439b770..35c4394e4fc6 100644
>>> --- a/fs/f2fs/super.c
>>> +++ b/fs/f2fs/super.c
>>> @@ -150,6 +150,8 @@ enum {
>>> Opt_mode,
>>> Opt_fault_injection,
>>> Opt_fault_type,
>>> +   Opt_lazytime,
>>> +   Opt_nolazytime,
>>> Opt_quota,
>>> Opt_noquota,
>>> Opt_usrquota,
>>> @@ -226,6 +228,8 @@ static match_table_t f2fs_tokens = {
>>> {Opt_mode, "mode=%s"},
>>> {Opt_fault_injection, "fault_injection=%u"},
>>> {Opt_fault_type, "fault_type=%u"},
>>> +   {Opt_lazytime, "lazytime"},
>>> +   {Opt_nolazytime, "nolazytime"},
>>> {Opt_quota, "quota"},
>>> {Opt_noquota, "noquota"},
>>> {Opt_usrquota, "usrquota"},
>>> @@ -922,6 +926,12 @@ static int parse_options(struct super_block *sb, char 
>>> *options, bool is_remount)
>>> f2fs_info(sbi, "fault_type options not supported");
>>> break;
>>>  #endif
>>> +   case Opt_lazytime:
>>> +   sb->s_flags |= SB_LAZYTIME;
>>> +   break;
>>> +   case Opt_nolazytime:
>>> +   sb->s_flags &= ~SB_LAZYTIME;
>>> +   break;
>>>  #ifdef CONFIG_QUOTA
>>> case Opt_quota:
>>> case Opt_usrquota:
>>> -- 
>>> 2.47.0.277.g8800431eea-goog
>>
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] Revert "f2fs: remove unreachable lazytime mount option parsing"

2024-11-20 Thread Eric Sandeen
On 11/12/24 3:39 PM, Jaegeuk Kim wrote:
> Hi Eric,
> 
> Could you please check this revert as it breaks the mount()?
> It seems F2FS needs to implement new mount support.
> 
> Thanks,

I'm sorry, I missed this email. I will look into it more today.

As for f2fs new mount API support, I have been struggling with it for a
long time, f2fs has been uniquely complex. The assumption that the superblock
and on-disk features are known at option parsing time makes it much more
difficult than most other filesystems.

But if there's a problem/regression with this commit, I have no objection to
reverting the commit for now, and I'm sorry for the error.

-Eric

> On 11/12, Jaegeuk Kim wrote:
>> This reverts commit 54f43a10fa257ad4af02a1d157fefef6ebcfa7dc.
>>
>> The above commit broke the lazytime mount, given
>>
>> mount("/dev/vdb", "/mnt/test", "f2fs", 0, "lazytime");
>>
>> CC: sta...@vger.kernel.org # 6.11+
>> Signed-off-by: Daniel Rosenberg 
>> Signed-off-by: Jaegeuk Kim 
>> ---
>>  fs/f2fs/super.c | 10 ++
>>  1 file changed, 10 insertions(+)
>>
>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>> index 49519439b770..35c4394e4fc6 100644
>> --- a/fs/f2fs/super.c
>> +++ b/fs/f2fs/super.c
>> @@ -150,6 +150,8 @@ enum {
>>  Opt_mode,
>>  Opt_fault_injection,
>>  Opt_fault_type,
>> +Opt_lazytime,
>> +Opt_nolazytime,
>>  Opt_quota,
>>  Opt_noquota,
>>  Opt_usrquota,
>> @@ -226,6 +228,8 @@ static match_table_t f2fs_tokens = {
>>  {Opt_mode, "mode=%s"},
>>  {Opt_fault_injection, "fault_injection=%u"},
>>  {Opt_fault_type, "fault_type=%u"},
>> +{Opt_lazytime, "lazytime"},
>> +{Opt_nolazytime, "nolazytime"},
>>  {Opt_quota, "quota"},
>>  {Opt_noquota, "noquota"},
>>  {Opt_usrquota, "usrquota"},
>> @@ -922,6 +926,12 @@ static int parse_options(struct super_block *sb, char 
>> *options, bool is_remount)
>>  f2fs_info(sbi, "fault_type options not supported");
>>  break;
>>  #endif
>> +case Opt_lazytime:
>> +sb->s_flags |= SB_LAZYTIME;
>> +break;
>> +case Opt_nolazytime:
>> +sb->s_flags &= ~SB_LAZYTIME;
>> +break;
>>  #ifdef CONFIG_QUOTA
>>  case Opt_quota:
>>  case Opt_usrquota:
>> -- 
>> 2.47.0.277.g8800431eea-goog
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH] Revert "f2fs: remove unreachable lazytime mount option parsing"

2024-11-21 Thread Eric Sandeen
On 11/20/24 2:38 PM, Jaegeuk Kim wrote:
> On 11/20, Eric Sandeen wrote:

...

>> (Note that f2fs is the only filesystem that attempts to handle lazytime 
>> within
>> the filesystem itself):
>>
>> [linux]# grep -r \"lazytime\" fs/*/
>> fs/f2fs/super.c: {Opt_lazytime, "lazytime"},
>> [linux]#
>>
>> I'm not entirely sure how to untangle all this, but regressions are not 
>> acceptable,
>> so please revert my commit for now.
> 
> Thanks for the explanation. At a glance, I thought it's caused that f2fs 
> doesn't
> implement fs_context_operations. We'll take a look at how to support it.

(cc: list trimmed)

I had thought the conversion would resolve this too, but had not considered 
direct
mount(2) calls passing the string in, which is something that probably needs to 
be
supported even after the conversion, sadly.

As a reminder, this might be a start / sketch of how to convert to the new 
mount API:

https://git.kernel.org/pub/scm/linux/kernel/git/sandeen/linux.git/log/?h=f2fs-mount-api

It's not entirely correct, but at least the first several patches are probably 
the right
idea - getting sb / sbi out of the parsing path, and deferring 
option-vs-disk-feature
checks until after the superblock is read, etc.

The final patch is probably not the way to go - it allocates an entire 
f2fs_sb_info
in f2fs_init_fs_context - it probably makes more sense to create a new context
structure which holds only mount options, which is then transferred into the
sbi after option parsing during mount or remount.

I was doing these conversions as a side project, and given the f2fs conversion
complexity, I have yet to get to a series that I'm happy with. Perhaps expert
eyes can help!

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 7/9] f2fs: defer readonly check vs norecovery

2025-03-03 Thread Eric Sandeen
Defer the readonly-vs-norecovery check until after option parsing is done
so that option parsing does not require an active superblock for the test.
Add a helpful message, while we're at it.

(I think could be moved back into parsing after we switch to the new mount
API if desired, as the fs context will have RO state available.)

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8866a74ce6aa..bc1aab749689 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -727,10 +727,8 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
set_opt(sbi, DISABLE_ROLL_FORWARD);
break;
case Opt_norecovery:
-   /* this option mounts f2fs with ro */
+   /* requires ro mount, checked in f2fs_default_check */
set_opt(sbi, NORECOVERY);
-   if (!f2fs_readonly(sb))
-   return -EINVAL;
break;
case Opt_discard:
if (!f2fs_hw_support_discard(sbi)) {
@@ -1411,6 +1409,12 @@ static int f2fs_default_check(struct f2fs_sb_info *sbi)
f2fs_err(sbi, "Allow to mount readonly mode only");
return -EROFS;
}
+
+   if (test_opt(sbi, NORECOVERY) && !f2fs_readonly(sbi->sb)) {
+   f2fs_err(sbi, "norecovery requires readonly mount");
+   return -EINVAL;
+   }
+
return 0;
 }
 
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 0/9] f2fs: first steps towards mount API conversion

2025-03-03 Thread Eric Sandeen
I have been struggling to get to a good series to convert f2fs to the
new mount API. f2fs is more complex, because much of the option parsing
assumes that the superblock has already been read from disk, and uses
that to test various on-disk features, etc. All of those tests will need
to be moved to after parsing is complete, and this series is just a
start.

The first two patches in this series are incidental, just things I
noticed when working on this. They are not critical to the conversion,
but they may be desirable anyway.

The rest of the patches move towards removal of explicit references to
*sb in parse_options(), using *sbi instead. (The full conversion may use
a private context structure instead of *sbi, since the *sbi is rather
large.)

It's up to you if you want to merge these now or not, but I thought I'd
share the direction I was moving, to get some feedback about whether
this seems to make sense. Next steps would be moving more of the feature
checks to later in the mount process, after parsing is complete.

This has been tested with random combinations of valid and invalid mount
options, but it has not been tested with a wide range of on-disk
features. My testing did not turn up any differences in behavior.
(I also did explicit testing of direct mount syscalls with "lazytime" as
an option string, keeping in mind the earlier regression there.)

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 6/9] f2fs: Pass sbi rather than sb to f2fs_set_test_dummy_encryption

2025-03-03 Thread Eric Sandeen
This removes another sb instance from parse_options()

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index e63b3bd75f85..8866a74ce6aa 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -483,12 +483,11 @@ static int f2fs_check_quota_options(struct f2fs_sb_info 
*sbi)
 }
 #endif
 
-static int f2fs_set_test_dummy_encryption(struct super_block *sb,
+static int f2fs_set_test_dummy_encryption(struct f2fs_sb_info *sbi,
  const char *opt,
  const substring_t *arg,
  bool is_remount)
 {
-   struct f2fs_sb_info *sbi = F2FS_SB(sb);
struct fs_parameter param = {
.type = fs_value_is_string,
.string = arg->from ? arg->from : "",
@@ -1029,7 +1028,7 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
kfree(name);
break;
case Opt_test_dummy_encryption:
-   ret = f2fs_set_test_dummy_encryption(sb, p, &args[0],
+   ret = f2fs_set_test_dummy_encryption(sbi, p, &args[0],
 is_remount);
if (ret)
return ret;
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 3/9] f2fs: factor out an f2fs_default_check function

2025-03-03 Thread Eric Sandeen
From: Eric Sandeen 

The current options parsing function both parses options and validates
them - factor the validation out to reduce the size of the function and
make transition to the new mount API possible, because under the new mount
API, options are parsed one at a time, and cannot all be tested at the end
of the parsing function.

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 29b3aa1ee99c..7cfd5e4e806e 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -687,7 +687,7 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
int ret;
 
if (!options)
-   goto default_check;
+   return 0;
 
while ((p = strsep(&options, ",")) != NULL) {
int token;
@@ -1318,7 +1318,11 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
return -EINVAL;
}
}
-default_check:
+   return 0;
+}
+
+static int f2fs_default_check(struct f2fs_sb_info *sbi)
+{
 #ifdef CONFIG_QUOTA
if (f2fs_check_quota_options(sbi))
return -EINVAL;
@@ -2364,6 +2368,10 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
}
 #endif
 
+   err = f2fs_default_check(sbi);
+   if (err)
+   goto restore_opts;
+
/* flush outstanding errors before changing fs state */
flush_work(&sbi->s_error_work);
 
@@ -4489,6 +4497,10 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
if (err)
goto free_options;
 
+   err = f2fs_default_check(sbi);
+   if (err)
+   goto free_options;
+
sb->s_maxbytes = max_file_blocks(NULL) <<
le32_to_cpu(raw_super->log_blocksize);
sb->s_max_links = F2FS_LINK_MAX;
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 9/9] f2fs: pass sbi rather than sb to parse_options()

2025-03-03 Thread Eric Sandeen
With the new mount API the sb will not be available during initial option
parsing, which will happen before fill_super reads sb from disk.

Now that the sb is no longer directly referenced in parse_options, switch
it to use sbi.

(Note that all calls to f2fs_sb_has_* originating from parse_options will
need to be deferred to later before we can use the new mount API.)

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 9edb200caae7..579c96a80fe2 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -670,9 +670,8 @@ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, 
const char *str)
 #endif
 #endif
 
-static int parse_options(struct super_block *sb, char *options, bool 
is_remount)
+static int parse_options(struct f2fs_sb_info *sbi, char *options, bool 
is_remount)
 {
-   struct f2fs_sb_info *sbi = F2FS_SB(sb);
substring_t args[MAX_OPT_ARGS];
 #ifdef CONFIG_F2FS_FS_COMPRESSION
unsigned char (*ext)[F2FS_EXTENSION_LEN];
@@ -2356,7 +2355,7 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
default_options(sbi, true);
 
/* parse mount options */
-   err = parse_options(sb, data, true);
+   err = parse_options(sbi, data, true);
if (err)
goto restore_opts;
 
@@ -4496,7 +4495,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
goto free_sb_buf;
}
 
-   err = parse_options(sb, options, false);
+   err = parse_options(sbi, options, false);
if (err)
goto free_options;
 
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 5/9] f2fs: make LAZYTIME a mount option flag

2025-03-03 Thread Eric Sandeen
Set LAZYTIME into sbi during parsing, and transfer it to the sb in
fill_super, so that an sb is not required during option parsing.

(Note: While lazytime is normally handled via mount flag in the vfs,
some f2fs users do expect to be able to use it as an explicit mount
option string via the mount syscall, so this option must remain.)

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/f2fs.h  |  5 +
 fs/f2fs/super.c | 11 ---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 15e4f5a77eb5..5c83e3a558f9 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -115,6 +115,11 @@ extern const char *f2fs_fault_name[FAULT_MAX];
 #define F2FS_MOUNT_COMPRESS_CACHE  0x0400
 #define F2FS_MOUNT_AGE_EXTENT_CACHE0x0800
 #define F2FS_MOUNT_INLINECRYPT 0x1000
+/*
+ * Some f2fs environments expect to be able to pass the "lazytime" option
+ * string rather than using the MS_LAZYTIME flag, so this must remain.
+ */
+#define F2FS_MOUNT_LAZYTIME0x2000
 
 #define F2FS_OPTION(sbi)   ((sbi)->mount_opt)
 #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 643d19bbc156..e63b3bd75f85 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -917,10 +917,10 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
break;
 #endif
case Opt_lazytime:
-   sb->s_flags |= SB_LAZYTIME;
+   set_opt(sbi, LAZYTIME);
break;
case Opt_nolazytime:
-   sb->s_flags &= ~SB_LAZYTIME;
+   clear_opt(sbi, LAZYTIME);
break;
 #ifdef CONFIG_QUOTA
case Opt_quota:
@@ -2169,8 +2169,8 @@ static void default_options(struct f2fs_sb_info *sbi, 
bool remount)
set_opt(sbi, INLINE_DATA);
set_opt(sbi, INLINE_DENTRY);
set_opt(sbi, MERGE_CHECKPOINT);
+   set_opt(sbi, LAZYTIME);
F2FS_OPTION(sbi).unusable_cap = 0;
-   sbi->sb->s_flags |= SB_LAZYTIME;
if (!f2fs_is_readonly(sbi))
set_opt(sbi, FLUSH_MERGE);
if (f2fs_sb_has_blkzoned(sbi))
@@ -4538,6 +4538,11 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
if (test_opt(sbi, INLINECRYPT))
sb->s_flags |= SB_INLINECRYPT;
 
+   if (test_opt(sbi, LAZYTIME))
+   sb->s_flags |= SB_LAZYTIME;
+   else
+   sb->s_flags &= ~SB_LAZYTIME;
+
super_set_uuid(sb, (void *) raw_super->uuid, sizeof(raw_super->uuid));
super_set_sysfs_name_bdev(sb);
sb->s_iflags |= SB_I_CGROUPWB;
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 3/9] f2fs: factor out an f2fs_default_check function

2025-03-12 Thread Eric Sandeen
On 3/11/25 10:10 PM, Chao Yu wrote:
> On 3/4/25 01:12, Eric Sandeen wrote:
>> From: Eric Sandeen 
>>
>> The current options parsing function both parses options and validates
>> them - factor the validation out to reduce the size of the function and
>> make transition to the new mount API possible, because under the new mount
>> API, options are parsed one at a time, and cannot all be tested at the end
>> of the parsing function.
>>
>> Signed-off-by: Eric Sandeen 
>> ---
>>  fs/f2fs/super.c | 16 ++--
>>  1 file changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>> index 29b3aa1ee99c..7cfd5e4e806e 100644
>> --- a/fs/f2fs/super.c
>> +++ b/fs/f2fs/super.c
>> @@ -687,7 +687,7 @@ static int parse_options(struct super_block *sb, char 
>> *options, bool is_remount)
>>  int ret;
>>  
>>  if (!options)
>> -goto default_check;
> 
> Eric, do you know in which condition options can be NULL, mount w/o any
> specified options?
> 
> If so, maybe we'd keep this in order to chech whether default options
> generated from default_options() is conflicted or not? What do you think?
> 
> Thanks,

Yes, that's I think that is correct - (!options) is true when no f2fs-specific
options are present for parsing.

However, I think that we do still check default options with my patch in this
case, because both calls to parse_options() still call f2fs_default_check()
when parse_options() completes.

Or am I misunderstanding your question?

I added printks to check:

# mount -o loop,ro  f2fsfile.img mnt
[root@fedora-rawhide f2fs-test]# dmesg 
[847946.326384] loop2: detected capacity change from 0 to 819200
[847946.337625] parse_options: (!options) is true
[847946.337637] enter f2fs_default_check()

Thank you for reviewing this series. I think at least the first 2 or 3 patches
are suitable for merge now, if you agree. I am fairly certain that the rest of
them are proper steps towards mount API conversion as well, but as I have not
yet finished the work, I can't guarantee it yet. :)

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 4/9] f2fs: make INLINECRYPT a mount option flag

2025-03-03 Thread Eric Sandeen
From: Eric Sandeen 

Set INLINECRYPT into sbi during parsing, and transfer it to the sb in
fill_super, so that an sb is not required during option parsing.

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/f2fs.h  | 1 +
 fs/f2fs/super.c | 5 -
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 1afa7be16e7d..15e4f5a77eb5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -114,6 +114,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
 #defineF2FS_MOUNT_GC_MERGE 0x0200
 #define F2FS_MOUNT_COMPRESS_CACHE  0x0400
 #define F2FS_MOUNT_AGE_EXTENT_CACHE0x0800
+#define F2FS_MOUNT_INLINECRYPT 0x1000
 
 #define F2FS_OPTION(sbi)   ((sbi)->mount_opt)
 #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 7cfd5e4e806e..643d19bbc156 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1036,7 +1036,7 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
break;
case Opt_inlinecrypt:
 #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
-   sb->s_flags |= SB_INLINECRYPT;
+   set_opt(sbi, INLINECRYPT);
 #else
f2fs_info(sbi, "inline encryption not supported");
 #endif
@@ -4535,6 +4535,9 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
sb->s_time_gran = 1;
sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
(test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0);
+   if (test_opt(sbi, INLINECRYPT))
+   sb->s_flags |= SB_INLINECRYPT;
+
super_set_uuid(sb, (void *) raw_super->uuid, sizeof(raw_super->uuid));
super_set_sysfs_name_bdev(sb);
sb->s_iflags |= SB_I_CGROUPWB;
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 8/9] f2fs: pass sbi rather than sb to quota qf_name helpers

2025-03-03 Thread Eric Sandeen
With the new mount api we will not have the superblock available during
option parsing. Prepare for this by passing *sbi rather than *sb.

For now, we are parsing after fill_super has been done, so sbi->sb will
exist. Under the new mount API this will require more care, but do the
simple change for now.

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index bc1aab749689..9edb200caae7 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -383,10 +383,10 @@ static void init_once(void *foo)
 #ifdef CONFIG_QUOTA
 static const char * const quotatypes[] = INITQFNAMES;
 #define QTYPE2NAME(t) (quotatypes[t])
-static int f2fs_set_qf_name(struct super_block *sb, int qtype,
+static int f2fs_set_qf_name(struct f2fs_sb_info *sbi, int qtype,
substring_t *args)
 {
-   struct f2fs_sb_info *sbi = F2FS_SB(sb);
+   struct super_block *sb = sbi->sb;
char *qname;
int ret = -EINVAL;
 
@@ -424,9 +424,9 @@ static int f2fs_set_qf_name(struct super_block *sb, int 
qtype,
return ret;
 }
 
-static int f2fs_clear_qf_name(struct super_block *sb, int qtype)
+static int f2fs_clear_qf_name(struct f2fs_sb_info *sbi, int qtype)
 {
-   struct f2fs_sb_info *sbi = F2FS_SB(sb);
+   struct super_block *sb = sbi->sb;
 
if (sb_any_quota_loaded(sb) && F2FS_OPTION(sbi).s_qf_names[qtype]) {
f2fs_err(sbi, "Cannot change journaled quota options when quota 
turned on");
@@ -931,32 +931,32 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
set_opt(sbi, PRJQUOTA);
break;
case Opt_usrjquota:
-   ret = f2fs_set_qf_name(sb, USRQUOTA, &args[0]);
+   ret = f2fs_set_qf_name(sbi, USRQUOTA, &args[0]);
if (ret)
return ret;
break;
case Opt_grpjquota:
-   ret = f2fs_set_qf_name(sb, GRPQUOTA, &args[0]);
+   ret = f2fs_set_qf_name(sbi, GRPQUOTA, &args[0]);
if (ret)
return ret;
break;
case Opt_prjjquota:
-   ret = f2fs_set_qf_name(sb, PRJQUOTA, &args[0]);
+   ret = f2fs_set_qf_name(sbi, PRJQUOTA, &args[0]);
if (ret)
return ret;
break;
case Opt_offusrjquota:
-   ret = f2fs_clear_qf_name(sb, USRQUOTA);
+   ret = f2fs_clear_qf_name(sbi, USRQUOTA);
if (ret)
return ret;
break;
case Opt_offgrpjquota:
-   ret = f2fs_clear_qf_name(sb, GRPQUOTA);
+   ret = f2fs_clear_qf_name(sbi, GRPQUOTA);
if (ret)
return ret;
break;
case Opt_offprjjquota:
-   ret = f2fs_clear_qf_name(sb, PRJQUOTA);
+   ret = f2fs_clear_qf_name(sbi, PRJQUOTA);
if (ret)
return ret;
break;
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 1/9] f2fs: use f2fs_sb_has_device_alias during option parsing

2025-03-03 Thread Eric Sandeen
Rather than using F2FS_HAS_FEATURE directly, use f2fs_sb_has_device_alias
macro during option parsing for consistency.

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 19b67828ae32..dd35d199775a 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -838,7 +838,7 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
set_opt(sbi, READ_EXTENT_CACHE);
break;
case Opt_noextent_cache:
-   if (F2FS_HAS_FEATURE(sbi, F2FS_FEATURE_DEVICE_ALIAS)) {
+   if (f2fs_sb_has_device_alias(sbi)) {
f2fs_err(sbi, "device aliasing requires extent 
cache");
return -EINVAL;
}
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/9] f2fs: consolidate unsupported option handling errors

2025-03-03 Thread Eric Sandeen
When certain build-time options are disabled, some mount options are not
accepted. For quota and compression, all related options are dismissed
with a single error message. For xattr, acl, and fault injection, each
option is handled individually. In addition, inline_xattr_size was missed
when CONFIG_F2FS_FS_XATTR was disabled.

Collapse xattr, acl, and fault injection errors into a single string, for
simplicity, and handle the missing inline_xattr_size case.

Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 18 --
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index dd35d199775a..29b3aa1ee99c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -772,16 +772,11 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
break;
 #else
case Opt_user_xattr:
-   f2fs_info(sbi, "user_xattr options not supported");
-   break;
case Opt_nouser_xattr:
-   f2fs_info(sbi, "nouser_xattr options not supported");
-   break;
case Opt_inline_xattr:
-   f2fs_info(sbi, "inline_xattr options not supported");
-   break;
case Opt_noinline_xattr:
-   f2fs_info(sbi, "noinline_xattr options not supported");
+   case Opt_inline_xattr_size:
+   f2fs_info(sbi, "xattr options not supported");
break;
 #endif
 #ifdef CONFIG_F2FS_FS_POSIX_ACL
@@ -793,10 +788,8 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
break;
 #else
case Opt_acl:
-   f2fs_info(sbi, "acl options not supported");
-   break;
case Opt_noacl:
-   f2fs_info(sbi, "noacl options not supported");
+   f2fs_info(sbi, "acl options not supported");
break;
 #endif
case Opt_active_logs:
@@ -919,11 +912,8 @@ static int parse_options(struct super_block *sb, char 
*options, bool is_remount)
break;
 #else
case Opt_fault_injection:
-   f2fs_info(sbi, "fault_injection options not supported");
-   break;
-
case Opt_fault_type:
-   f2fs_info(sbi, "fault_type options not supported");
+   f2fs_info(sbi, "fault injection options not supported");
break;
 #endif
case Opt_lazytime:
-- 
2.48.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 0/9] f2fs: first steps towards mount API conversion

2025-04-05 Thread Eric Sandeen via Linux-f2fs-devel
I was working on next steps for this, and I have a followup question.

Today, several mount options are simply ignored if the on-disk format
does not support them. For example:

case Opt_compress_mode:
if (!f2fs_sb_has_compression(sbi)) {
f2fs_info(sbi, "Image doesn't support 
compression");
break;
}
name = match_strdup(&args[0]);
if (!name)
return -ENOMEM;
if (!strcmp(name, "fs")) {
F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS;
} else if (!strcmp(name, "user")) {
F2FS_OPTION(sbi).compress_mode = 
COMPR_MODE_USER;
} else {
kfree(name);
return -EINVAL;
}
kfree(name);
break;

so if f2fs_sb_has_compression() is not true, then the option is ignored without
any validation.

in other words, "mount -o compress_mode=nope ..." will succeed if the feature
is disabled on the filesystem.

If I move the f2fs_sb_has_compression() check to later for the new mount API,
then "mount -o compress_mode=nope ..."  will start failing for all images. Is
this acceptable? It seems wise to reject invalid options rather than ignore 
them,
even if they are incompatible with the format, but this would be a behavior
change.

The above would be simple enough to defer (maybe set to COMPR_MODE_INVAL and
reject it later) but I think other options such as compress/nocompress 
extensions
would be very messy to approach as "accept all options given during parsing,
and validate them later only if the corresponding feature is present."

So I wonder if a behavior change (stricter option validation) would be
acceptable here?

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 0/9] f2fs: first steps towards mount API conversion

2025-04-01 Thread Eric Sandeen via Linux-f2fs-devel
On 3/31/25 3:31 AM, Chao Yu wrote:
> On 3/29/25 12:18, Eric Sandeen wrote:
>> I was working on next steps for this, and I have a followup question.
>>
>> Today, several mount options are simply ignored if the on-disk format
>> does not support them. For example:
>>
>> case Opt_compress_mode:
>> if (!f2fs_sb_has_compression(sbi)) {
>> f2fs_info(sbi, "Image doesn't support 
>> compression");
>> break;
>> }
>> name = match_strdup(&args[0]);
>> if (!name)
>> return -ENOMEM;
>> if (!strcmp(name, "fs")) {
>> F2FS_OPTION(sbi).compress_mode = 
>> COMPR_MODE_FS;
>> } else if (!strcmp(name, "user")) {
>> F2FS_OPTION(sbi).compress_mode = 
>> COMPR_MODE_USER;
>> } else {
>> kfree(name);
>> return -EINVAL;
>> }
>> kfree(name);
>> break;
>>
>> so if f2fs_sb_has_compression() is not true, then the option is ignored 
>> without
>> any validation.
>>
>> in other words, "mount -o compress_mode=nope ..." will succeed if the feature
>> is disabled on the filesystem.
>>
>> If I move the f2fs_sb_has_compression() check to later for the new mount API,
>> then "mount -o compress_mode=nope ..."  will start failing for all images. Is
>> this acceptable? It seems wise to reject invalid options rather than ignore 
>> them,
>> even if they are incompatible with the format, but this would be a behavior
>> change.
> 
> I'm fine w/ this change. IIRC, I haven't saw above use case, otherwise user
> should stop passing invalid mount option to f2fs.

Great, I will proceed with this. It will make the conversion simpler (but may
make testing/validation more difficult, as behavior will change with invalid 
input).

-Eric

> Thanks,



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 0/7 V2] f2fs: new mount API conversion

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
On 4/20/25 10:24 AM, Eric Sandeen wrote:
> This is a forward-port of Hongbo's original f2fs mount API conversion,
> posted last August at 
> https://lore.kernel.org/linux-f2fs-devel/20240814023912.3959299-1-lihongb...@huawei.com/

I'll rebase this onto jaegeuk's dev tree and send a V3.

-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH V3 6/7] f2fs: introduce fs_context_operation structure

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

The handle_mount_opt() helper is used to parse mount parameters,
and so we can rename this function to f2fs_parse_param() and set
it as .param_param in fs_context_operations.

Signed-off-by: Hongbo Li 
[sandeen: forward port]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 149134775870..37497fd80bb9 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -707,7 +707,7 @@ static int f2fs_set_zstd_level(struct f2fs_fs_context *ctx, 
const char *str)
 #endif
 #endif
 
-static int handle_mount_opt(struct fs_context *fc, struct fs_parameter *param)
+static int f2fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
struct f2fs_fs_context *ctx = fc->fs_private;
 #ifdef CONFIG_F2FS_FS_COMPRESSION
@@ -1173,7 +1173,7 @@ static int parse_options(struct fs_context *fc, char 
*options)
param.key = key;
param.size = v_len;
 
-   ret = handle_mount_opt(fc, ¶m);
+   ret = f2fs_parse_param(fc, ¶m);
kfree(param.string);
if (ret < 0)
return ret;
@@ -5277,6 +5277,10 @@ static struct dentry *f2fs_mount(struct file_system_type 
*fs_type, int flags,
return mount_bdev(fs_type, flags, dev_name, data, f2fs_fill_super);
 }
 
+static const struct fs_context_operations f2fs_context_ops = {
+   .parse_param= f2fs_parse_param,
+};
+
 static void kill_f2fs_super(struct super_block *sb)
 {
struct f2fs_sb_info *sbi = F2FS_SB(sb);
-- 
2.49.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH V3 3/7] f2fs: Allow sbi to be NULL in f2fs_printk

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

At the parsing phase of the new mount api, sbi will not be
available. So here allows sbi to be NULL in f2fs log helpers
and use that in handle_mount_opt().

Signed-off-by: Hongbo Li 
[sandeen: forward port]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 90 +++--
 1 file changed, 49 insertions(+), 41 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 20dee7c40d59..35190db4501c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -323,11 +323,19 @@ void f2fs_printk(struct f2fs_sb_info *sbi, bool 
limit_rate,
vaf.fmt = printk_skip_level(fmt);
vaf.va = &args;
if (limit_rate)
-   printk_ratelimited("%c%cF2FS-fs (%s): %pV\n",
-   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   if (sbi)
+   printk_ratelimited("%c%cF2FS-fs (%s): %pV\n",
+   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   else
+   printk_ratelimited("%c%cF2FS-fs: %pV\n",
+   KERN_SOH_ASCII, level, &vaf);
else
-   printk("%c%cF2FS-fs (%s): %pV\n",
-   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   if (sbi)
+   printk("%c%cF2FS-fs (%s): %pV\n",
+   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   else
+   printk("%c%cF2FS-fs: %pV\n",
+   KERN_SOH_ASCII, level, &vaf);
 
va_end(args);
 }
@@ -737,13 +745,13 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
case Opt_discard:
if (result.negated) {
if (f2fs_hw_should_discard(sbi)) {
-   f2fs_warn(sbi, "discard is required for zoned 
block devices");
+   f2fs_warn(NULL, "discard is required for zoned 
block devices");
return -EINVAL;
}
clear_opt(sbi, DISCARD);
} else {
if (!f2fs_hw_support_discard(sbi)) {
-   f2fs_warn(sbi, "device does not support 
discard");
+   f2fs_warn(NULL, "device does not support 
discard");
break;
}
set_opt(sbi, DISCARD);
@@ -751,7 +759,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
break;
case Opt_noheap:
case Opt_heap:
-   f2fs_warn(sbi, "heap/no_heap options were deprecated");
+   f2fs_warn(NULL, "heap/no_heap options were deprecated");
break;
 #ifdef CONFIG_F2FS_FS_XATTR
case Opt_user_xattr:
@@ -774,7 +782,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
case Opt_user_xattr:
case Opt_inline_xattr:
case Opt_inline_xattr_size:
-   f2fs_info(sbi, "%s options not supported", param->key);
+   f2fs_info(NULL, "%s options not supported", param->key);
break;
 #endif
 #ifdef CONFIG_F2FS_FS_POSIX_ACL
@@ -786,7 +794,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
break;
 #else
case Opt_acl:
-   f2fs_info(sbi, "%s options not supported", param->key);
+   f2fs_info(NULL, "%s options not supported", param->key);
break;
 #endif
case Opt_active_logs:
@@ -840,7 +848,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
break;
case Opt_reserve_root:
if (test_opt(sbi, RESERVE_ROOT)) {
-   f2fs_info(sbi, "Preserve previous reserve_root=%u",
+   f2fs_info(NULL, "Preserve previous reserve_root=%u",
  F2FS_OPTION(sbi).root_reserved_blocks);
} else {
F2FS_OPTION(sbi).root_reserved_blocks = result.int_32;
@@ -871,7 +879,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
 #else
case Opt_fault_injection:
case Opt_fault_type:
-   f2fs_info(sbi, "%s options not supported", param->key);
+   f2fs_info(NULL, "%s options not supported", param->key);
break;
 #endif
case Opt_lazytime:
@@ -934,7 +942,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
case Opt_usrjquota:
case Opt_grpjquota:

[f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
V3:
- Rebase onto git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
  dev branch
- Fix up some 0day robot warnings

This is a forward-port of Hongbo's original f2fs mount API conversion,
posted last August at 
https://lore.kernel.org/linux-f2fs-devel/20240814023912.3959299-1-lihongb...@huawei.com/

I had been trying to approach this with a little less complexity,
but in the end I realized that Hongbo's approach (which follows
the ext4 approach) was a good one, and I was not making any progrss
myself. 😉

In addition to the forward-port, I have also fixed a couple bugs I found
during testing, and some improvements / style choices as well. Hongbo and
I have discussed most of this off-list already, so I'm presenting the
net result here.

This does pass my typical testing which does a large number of random
mounts/remounts with valid and invalid option sets, on f2fs filesystem
images with various features in the on-disk superblock. (I was not able
to test all of this completely, as some options or features require
hardware I dn't have.)

Thanks,
-Eric

(A recap of Hongbo's original cover letter is below, edited slightly for
this series:)

Since many filesystems have done the new mount API conversion,
we introduce the new mount API conversion in f2fs.

The series can be applied on top of the current mainline tree
and the work is based on the patches from Lukas Czerner (has
done this in ext4[1]). His patch give me a lot of ideas.

Here is a high level description of the patchset:

1. Prepare the f2fs mount parameters required by the new mount
API and use it for parsing, while still using the old API to
get mount options string. Split the parameter parsing and
validation of the parse_options helper into two separate
helpers.

  f2fs: Add fs parameter specifications for mount options
  f2fs: move the option parser into handle_mount_opt

2. Remove the use of sb/sbi structure of f2fs from all the
parsing code, because with the new mount API the parsing is
going to be done before we even get the super block. In this
part, we introduce f2fs_fs_context to hold the temporary
options when parsing. For the simple options check, it has
to be done during parsing by using f2fs_fs_context structure.
For the check which needs sb/sbi, we do this during super
block filling.

  f2fs: Allow sbi to be NULL in f2fs_printk
  f2fs: Add f2fs_fs_context to record the mount options
  f2fs: separate the options parsing and options checking

3. Switch the f2fs to use the new mount API for mount and
remount.

  f2fs: introduce fs_context_operation structure
  f2fs: switch to the new mount api

[1] https://lore.kernel.org/all/20211021114508.21407-1-lczer...@redhat.com/



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH V3 4/7] f2fs: Add f2fs_fs_context to record the mount options

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

At the parsing phase of mouont in the new mount api, options
value will be recorded with the context, and then it will be
used in fill_super and other helpers.

Note that, this is a temporary status, we want remove the sb
and sbi usages in handle_mount_opt. So here the f2fs_fs_context
only records the mount options, it will be copied in sb/sbi in
later process. (At this point in the series, mount options are
temporarily not set during mount.)

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 419 
 1 file changed, 244 insertions(+), 175 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 35190db4501c..15befeb45c94 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -310,8 +310,65 @@ static match_table_t f2fs_checkpoint_tokens = {
{Opt_err, NULL},
 };
 
+#define F2FS_SPEC_background_gc(1 << 0)
+#define F2FS_SPEC_inline_xattr_size(1 << 1)
+#define F2FS_SPEC_active_logs  (1 << 2)
+#define F2FS_SPEC_reserve_root (1 << 3)
+#define F2FS_SPEC_resgid   (1 << 4)
+#define F2FS_SPEC_resuid   (1 << 5)
+#define F2FS_SPEC_mode (1 << 6)
+#define F2FS_SPEC_fault_injection  (1 << 7)
+#define F2FS_SPEC_fault_type   (1 << 8)
+#define F2FS_SPEC_jqfmt(1 << 9)
+#define F2FS_SPEC_alloc_mode   (1 << 10)
+#define F2FS_SPEC_fsync_mode   (1 << 11)
+#define F2FS_SPEC_checkpoint_disable_cap   (1 << 12)
+#define F2FS_SPEC_checkpoint_disable_cap_perc  (1 << 13)
+#define F2FS_SPEC_compress_level   (1 << 14)
+#define F2FS_SPEC_compress_algorithm   (1 << 15)
+#define F2FS_SPEC_compress_log_size(1 << 16)
+#define F2FS_SPEC_compress_extension   (1 << 17)
+#define F2FS_SPEC_nocompress_extension (1 << 18)
+#define F2FS_SPEC_compress_chksum  (1 << 19)
+#define F2FS_SPEC_compress_mode(1 << 20)
+#define F2FS_SPEC_discard_unit (1 << 21)
+#define F2FS_SPEC_memory_mode  (1 << 22)
+#define F2FS_SPEC_errors   (1 << 23)
+
+struct f2fs_fs_context {
+   struct f2fs_mount_info info;
+   unsigned intopt_mask;   /* Bits changed */
+   unsigned intspec_mask;
+   unsigned short  qname_mask;
+   unsigned long   sflags;
+   unsigned long   sflags_mask;
+};
+
+#define F2FS_CTX_INFO(ctx) ((ctx)->info)
+
+static inline void ctx_set_opt(struct f2fs_fs_context *ctx,
+  unsigned int flag)
+{
+   ctx->info.opt |= flag;
+   ctx->opt_mask |= flag;
+}
+
+static inline void ctx_clear_opt(struct f2fs_fs_context *ctx,
+unsigned int flag)
+{
+   ctx->info.opt &= ~flag;
+   ctx->opt_mask |= flag;
+}
+
+static inline void ctx_set_flags(struct f2fs_fs_context *ctx,
+unsigned int flag)
+{
+   ctx->sflags |= flag;
+   ctx->sflags_mask |= flag;
+}
+
 void f2fs_printk(struct f2fs_sb_info *sbi, bool limit_rate,
-   const char *fmt, ...)
+   const char *fmt, ...)
 {
struct va_format vaf;
va_list args;
@@ -429,57 +486,51 @@ static void init_once(void *foo)
 #ifdef CONFIG_QUOTA
 static const char * const quotatypes[] = INITQFNAMES;
 #define QTYPE2NAME(t) (quotatypes[t])
-static int f2fs_set_qf_name(struct f2fs_sb_info *sbi, int qtype,
-   struct fs_parameter *param)
+/*
+ * Note the name of the specified quota file.
+ */
+static int f2fs_note_qf_name(struct fs_context *fc, int qtype,
+struct fs_parameter *param)
 {
-   struct super_block *sb = sbi->sb;
+   struct f2fs_fs_context *ctx = fc->fs_private;
char *qname;
-   int ret = -EINVAL;
 
-   if (sb_any_quota_loaded(sb) && !F2FS_OPTION(sbi).s_qf_names[qtype]) {
-   f2fs_err(sbi, "Cannot change journaled quota options when quota 
turned on");
+   if (param->size < 1) {
+   f2fs_err(NULL, "Missing quota name");
return -EINVAL;
}
-   if (f2fs_sb_has_quota_ino(sbi)) {
-   f2fs_info(sbi, "QUOTA feature is enabled, so ignore qf_name");
+   if (strchr(param->string, '/')) {
+   f2fs_err(NULL, "quotafile must be on filesystem root");
+   return -EINVAL;
+   }
+   if (ctx->info.s_qf_names[qtype]) {
+   if (strcmp(ctx->info.s_qf_names[qtype

[f2fs-dev] [PATCH V3 5/7] f2fs: separate the options parsing and options checking

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

The new mount api separates option parsing and super block setup
into two distinct steps and so we need to separate the options
parsing out of the parse_options().

In order to achieve this, here we handle the mount options with
three steps:
  - Firstly, we move sb/sbi out of handle_mount_opt.
As the former patch introduced f2fs_fs_context, so we record
the changed mount options in this context. In handle_mount_opt,
sb/sbi is null, so we should move all relative code out of
handle_mount_opt (thus, some check case which use sb/sbi should
move out).
  - Secondly, we introduce the some check helpers to keep the option
consistent.
During filling superblock period, sb/sbi are ready. So we check
the f2fs_fs_context which holds the mount options base on sb/sbi.
  - Thirdly, we apply the new mount options to sb/sbi.
After checking the f2fs_fs_context, all changed on mount options
are valid. So we can apply them to sb/sbi directly.

After do these, option parsing and super block setting have been
decoupled. Also it should have retained the original execution
flow.

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 693 +++-
 1 file changed, 510 insertions(+), 183 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 15befeb45c94..149134775870 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -360,6 +360,12 @@ static inline void ctx_clear_opt(struct f2fs_fs_context 
*ctx,
ctx->opt_mask |= flag;
 }
 
+static inline bool ctx_test_opt(struct f2fs_fs_context *ctx,
+   unsigned int flag)
+{
+   return ctx->info.opt & flag;
+}
+
 static inline void ctx_set_flags(struct f2fs_fs_context *ctx,
 unsigned int flag)
 {
@@ -533,51 +539,6 @@ static int f2fs_unnote_qf_name(struct fs_context *fc, int 
qtype)
ctx->qname_mask |= 1 << qtype;
return 0;
 }
-
-static int f2fs_check_quota_options(struct f2fs_sb_info *sbi)
-{
-   /*
-* We do the test below only for project quotas. 'usrquota' and
-* 'grpquota' mount options are allowed even without quota feature
-* to support legacy quotas in quota files.
-*/
-   if (test_opt(sbi, PRJQUOTA) && !f2fs_sb_has_project_quota(sbi)) {
-   f2fs_err(sbi, "Project quota feature not enabled. Cannot enable 
project quota enforcement.");
-   return -1;
-   }
-   if (F2FS_OPTION(sbi).s_qf_names[USRQUOTA] ||
-   F2FS_OPTION(sbi).s_qf_names[GRPQUOTA] ||
-   F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]) {
-   if (test_opt(sbi, USRQUOTA) &&
-   F2FS_OPTION(sbi).s_qf_names[USRQUOTA])
-   clear_opt(sbi, USRQUOTA);
-
-   if (test_opt(sbi, GRPQUOTA) &&
-   F2FS_OPTION(sbi).s_qf_names[GRPQUOTA])
-   clear_opt(sbi, GRPQUOTA);
-
-   if (test_opt(sbi, PRJQUOTA) &&
-   F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
-   clear_opt(sbi, PRJQUOTA);
-
-   if (test_opt(sbi, GRPQUOTA) || test_opt(sbi, USRQUOTA) ||
-   test_opt(sbi, PRJQUOTA)) {
-   f2fs_err(sbi, "old and new quota format mixing");
-   return -1;
-   }
-
-   if (!F2FS_OPTION(sbi).s_jquota_fmt) {
-   f2fs_err(sbi, "journaled quota format not specified");
-   return -1;
-   }
-   }
-
-   if (f2fs_sb_has_quota_ino(sbi) && F2FS_OPTION(sbi).s_jquota_fmt) {
-   f2fs_info(sbi, "QUOTA feature is enabled, so ignore 
jquota_fmt");
-   F2FS_OPTION(sbi).s_jquota_fmt = 0;
-   }
-   return 0;
-}
 #endif
 
 static int f2fs_parse_test_dummy_encryption(const struct fs_parameter *param,
@@ -636,28 +597,28 @@ static bool is_compress_extension_exist(struct 
f2fs_mount_info *info,
  * extension will be treated as special cases and will not be compressed.
  * 3. Don't allow the non-compress extension specifies all files.
  */
-static int f2fs_test_compress_extension(struct f2fs_sb_info *sbi)
+static int f2fs_test_compress_extension(unsigned char 
(*noext)[F2FS_EXTENSION_LEN],
+   int noext_cnt,
+   unsigned char 
(*ext)[F2FS_EXTENSION_LEN],
+   int ext_cnt)
 {
-   unsigned char (*ext)[F2FS_EXTENSION_LEN];
-   unsigned char (*noext)[F2FS_EXTENSION_LEN];
-   int ext_cnt, noext_cnt, index = 0, no_index = 0;
-
-   ext = F2FS_OPTION(sbi).extensions;
-   ext_cnt = F2FS_OPTION(sbi).compress_ext_cn

[f2fs-dev] [PATCH V3 7/7] f2fs: switch to the new mount api

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

The new mount api will execute .parse_param, .init_fs_context, .get_tree
and will call .remount if remount happened. So we add the necessary
functions for the fs_context_operations. If .init_fs_context is added,
the old .mount should remove.

See Documentation/filesystems/mount_api.rst for more information.

Signed-off-by: Hongbo Li 
[sandeen: forward port]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 156 +++-
 1 file changed, 62 insertions(+), 94 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 37497fd80bb9..041bd6c482a0 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1141,47 +1141,6 @@ static int f2fs_parse_param(struct fs_context *fc, 
struct fs_parameter *param)
return 0;
 }
 
-static int parse_options(struct fs_context *fc, char *options)
-{
-   struct fs_parameter param;
-   char *key;
-   int ret;
-
-   if (!options)
-   return 0;
-
-   while ((key = strsep(&options, ",")) != NULL) {
-   if (*key) {
-   size_t v_len = 0;
-   char *value = strchr(key, '=');
-
-   param.type = fs_value_is_flag;
-   param.string = NULL;
-
-   if (value) {
-   if (value == key)
-   continue;
-
-   *value++ = 0;
-   v_len = strlen(value);
-   param.string = kmemdup_nul(value, v_len, 
GFP_KERNEL);
-   if (!param.string)
-   return -ENOMEM;
-   param.type = fs_value_is_string;
-   }
-
-   param.key = key;
-   param.size = v_len;
-
-   ret = f2fs_parse_param(fc, ¶m);
-   kfree(param.string);
-   if (ret < 0)
-   return ret;
-   }
-   }
-   return 0;
-}
-
 /*
  * Check quota settings consistency.
  */
@@ -2583,13 +2542,12 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info 
*sbi)
f2fs_flush_ckpt_thread(sbi);
 }
 
-static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+static int __f2fs_remount(struct fs_context *fc, struct super_block *sb)
 {
struct f2fs_sb_info *sbi = F2FS_SB(sb);
struct f2fs_mount_info org_mount_opt;
-   struct f2fs_fs_context ctx;
-   struct fs_context fc;
unsigned long old_sb_flags;
+   unsigned int flags = fc->sb_flags;
int err;
bool need_restart_gc = false, need_stop_gc = false;
bool need_restart_flush = false, need_stop_flush = false;
@@ -2635,7 +2593,7 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
 #endif
 
/* recover superblocks we couldn't write due to previous RO mount */
-   if (!(*flags & SB_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
+   if (!(flags & SB_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
err = f2fs_commit_super(sbi, false);
f2fs_info(sbi, "Try to recover all the superblocks, ret: %d",
  err);
@@ -2645,21 +2603,11 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
 
default_options(sbi, true);
 
-   memset(&fc, 0, sizeof(fc));
-   memset(&ctx, 0, sizeof(ctx));
-   fc.fs_private = &ctx;
-   fc.purpose = FS_CONTEXT_FOR_RECONFIGURE;
-
-   /* parse mount options */
-   err = parse_options(&fc, data);
-   if (err)
-   goto restore_opts;
-
-   err = f2fs_check_opt_consistency(&fc, sb);
+   err = f2fs_check_opt_consistency(fc, sb);
if (err < 0)
goto restore_opts;
 
-   f2fs_apply_options(&fc, sb);
+   f2fs_apply_options(fc, sb);
 
 #ifdef CONFIG_BLK_DEV_ZONED
if (f2fs_sb_has_blkzoned(sbi) &&
@@ -2678,20 +2626,20 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
 * Previous and new state of filesystem is RO,
 * so skip checking GC and FLUSH_MERGE conditions.
 */
-   if (f2fs_readonly(sb) && (*flags & SB_RDONLY))
+   if (f2fs_readonly(sb) && (flags & SB_RDONLY))
goto skip;
 
-   if (f2fs_dev_is_readonly(sbi) && !(*flags & SB_RDONLY)) {
+   if (f2fs_dev_is_readonly(sbi) && !(flags & SB_RDONLY)) {
err = -EROFS;
goto restore_opts;
}
 
 #ifdef CONFIG_QUOTA
-   if (!f2fs_readonly(sb) && (*flags & SB_RDONLY)) {
+   if (!f2fs_readonly(sb) && (flags & SB_RDONLY)) {
err = dquot_suspend(sb, -1);
if (

[f2fs-dev] [PATCH V3 1/7] f2fs: Add fs parameter specifications for mount options

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

Use an array of `fs_parameter_spec` called f2fs_param_specs to
hold the mount option specifications for the new mount api.

Add constant_table structures for several options to facilitate
parsing.

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates, more fsparam_enum]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 122 
 1 file changed, 122 insertions(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 22f26871b7aa..ebea03bba054 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "f2fs.h"
 #include "node.h"
@@ -194,9 +195,130 @@ enum {
Opt_age_extent_cache,
Opt_errors,
Opt_nat_bits,
+   Opt_jqfmt,
+   Opt_checkpoint,
Opt_err,
 };
 
+static const struct constant_table f2fs_param_background_gc[] = {
+   {"on",  BGGC_MODE_ON},
+   {"off", BGGC_MODE_OFF},
+   {"sync",BGGC_MODE_SYNC},
+   {}
+};
+
+static const struct constant_table f2fs_param_mode[] = {
+   {"adaptive",FS_MODE_ADAPTIVE},
+   {"lfs", FS_MODE_LFS},
+   {"fragment:segment",FS_MODE_FRAGMENT_SEG},
+   {"fragment:block",  FS_MODE_FRAGMENT_BLK},
+   {}
+};
+
+static const struct constant_table f2fs_param_jqfmt[] = {
+   {"vfsold",  QFMT_VFS_OLD},
+   {"vfsv0",   QFMT_VFS_V0},
+   {"vfsv1",   QFMT_VFS_V1},
+   {}
+};
+
+static const struct constant_table f2fs_param_alloc_mode[] = {
+   {"default", ALLOC_MODE_DEFAULT},
+   {"reuse",   ALLOC_MODE_REUSE},
+   {}
+};
+static const struct constant_table f2fs_param_fsync_mode[] = {
+   {"posix",   FSYNC_MODE_POSIX},
+   {"strict",  FSYNC_MODE_STRICT},
+   {"nobarrier",   FSYNC_MODE_NOBARRIER},
+   {}
+};
+
+static const struct constant_table f2fs_param_compress_mode[] = {
+   {"fs",  COMPR_MODE_FS},
+   {"user",COMPR_MODE_USER},
+   {}
+};
+
+static const struct constant_table f2fs_param_discard_unit[] = {
+   {"block",   DISCARD_UNIT_BLOCK},
+   {"segment", DISCARD_UNIT_SEGMENT},
+   {"section", DISCARD_UNIT_SECTION},
+   {}
+};
+
+static const struct constant_table f2fs_param_memory_mode[] = {
+   {"normal",  MEMORY_MODE_NORMAL},
+   {"low", MEMORY_MODE_LOW},
+   {}
+};
+
+static const struct constant_table f2fs_param_errors[] = {
+   {"remount-ro",  MOUNT_ERRORS_READONLY},
+   {"continue",MOUNT_ERRORS_CONTINUE},
+   {"panic",   MOUNT_ERRORS_PANIC},
+   {}
+};
+
+static const struct fs_parameter_spec f2fs_param_specs[] = {
+   fsparam_enum("background_gc", Opt_gc_background, 
f2fs_param_background_gc),
+   fsparam_flag("disable_roll_forward", Opt_disable_roll_forward),
+   fsparam_flag("norecovery", Opt_norecovery),
+   fsparam_flag_no("discard", Opt_discard),
+   fsparam_flag("no_heap", Opt_noheap),
+   fsparam_flag("heap", Opt_heap),
+   fsparam_flag_no("user_xattr", Opt_user_xattr),
+   fsparam_flag_no("acl", Opt_acl),
+   fsparam_s32("active_logs", Opt_active_logs),
+   fsparam_flag("disable_ext_identify", Opt_disable_ext_identify),
+   fsparam_flag_no("inline_xattr", Opt_inline_xattr),
+   fsparam_s32("inline_xattr_size", Opt_inline_xattr_size),
+   fsparam_flag_no("inline_data", Opt_inline_data),
+   fsparam_flag_no("inline_dentry", Opt_inline_dentry),
+   fsparam_flag_no("flush_merge", Opt_flush_merge),
+   fsparam_flag_no("barrier", Opt_barrier),
+   fsparam_flag("fastboot", Opt_fastboot),
+   fsparam_flag_no("extent_cache", Opt_extent_cache),
+   fsparam_flag("data_flush", Opt_data_flush),
+   fsparam_u32("reserve_root", Opt_reserve_root),
+   fsparam_gid("resgid", Opt_resgid),
+   fsparam_uid("resuid", Opt_resuid),
+   fsparam_enum("mode", Opt_mode, f2fs_param_mode),
+   fsparam_s32("fault_injection", Opt_fault_injection),
+   fsparam_u32("fault_type", Opt_fault_type),
+   fsparam_flag_no("lazytime", Opt_lazytime),
+   fsparam_flag_no("quota", Opt_quota),
+   fsparam_flag("usrquota", Opt_usrquota),
+   fsparam_flag("grpquota", Opt_grpquota),
+   fsparam_flag("prjquota", Opt_prjquota),
+   fsparam_string_empty("usrjquota", O

[f2fs-dev] [PATCH V3 2/7] f2fs: move the option parser into handle_mount_opt

2025-04-24 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

In handle_mount_opt, we use fs_parameter to parse each option.
However we're still using the old API to get the options string.
Using fsparams parse_options allows us to remove many of the Opt_
enums, so remove them.

The checkpoint disable cap (or percent) involves rather complex
parsing; we retain the old match_table mechanism for this, which
handles it well.

There are some changes about parsing options:
  1. For `active_logs`, `inline_xattr_size` and `fault_injection`,
 we use s32 type according the internal structure to record the
 option's value.

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 1061 ++-
 1 file changed, 406 insertions(+), 655 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ebea03bba054..20dee7c40d59 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "f2fs.h"
@@ -124,29 +125,20 @@ enum {
Opt_disable_roll_forward,
Opt_norecovery,
Opt_discard,
-   Opt_nodiscard,
Opt_noheap,
Opt_heap,
Opt_user_xattr,
-   Opt_nouser_xattr,
Opt_acl,
-   Opt_noacl,
Opt_active_logs,
Opt_disable_ext_identify,
Opt_inline_xattr,
-   Opt_noinline_xattr,
Opt_inline_xattr_size,
Opt_inline_data,
Opt_inline_dentry,
-   Opt_noinline_dentry,
Opt_flush_merge,
-   Opt_noflush_merge,
Opt_barrier,
-   Opt_nobarrier,
Opt_fastboot,
Opt_extent_cache,
-   Opt_noextent_cache,
-   Opt_noinline_data,
Opt_data_flush,
Opt_reserve_root,
Opt_resgid,
@@ -155,21 +147,13 @@ enum {
Opt_fault_injection,
Opt_fault_type,
Opt_lazytime,
-   Opt_nolazytime,
Opt_quota,
-   Opt_noquota,
Opt_usrquota,
Opt_grpquota,
Opt_prjquota,
Opt_usrjquota,
Opt_grpjquota,
Opt_prjjquota,
-   Opt_offusrjquota,
-   Opt_offgrpjquota,
-   Opt_offprjjquota,
-   Opt_jqfmt_vfsold,
-   Opt_jqfmt_vfsv0,
-   Opt_jqfmt_vfsv1,
Opt_alloc,
Opt_fsync,
Opt_test_dummy_encryption,
@@ -179,17 +163,15 @@ enum {
Opt_checkpoint_disable_cap_perc,
Opt_checkpoint_enable,
Opt_checkpoint_merge,
-   Opt_nocheckpoint_merge,
Opt_compress_algorithm,
Opt_compress_log_size,
-   Opt_compress_extension,
Opt_nocompress_extension,
+   Opt_compress_extension,
Opt_compress_chksum,
Opt_compress_mode,
Opt_compress_cache,
Opt_atgc,
Opt_gc_merge,
-   Opt_nogc_merge,
Opt_discard_unit,
Opt_memory_mode,
Opt_age_extent_cache,
@@ -319,83 +301,12 @@ static const struct fs_parameter_spec f2fs_param_specs[] 
= {
{}
 };
 
-static match_table_t f2fs_tokens = {
-   {Opt_gc_background, "background_gc=%s"},
-   {Opt_disable_roll_forward, "disable_roll_forward"},
-   {Opt_norecovery, "norecovery"},
-   {Opt_discard, "discard"},
-   {Opt_nodiscard, "nodiscard"},
-   {Opt_noheap, "no_heap"},
-   {Opt_heap, "heap"},
-   {Opt_user_xattr, "user_xattr"},
-   {Opt_nouser_xattr, "nouser_xattr"},
-   {Opt_acl, "acl"},
-   {Opt_noacl, "noacl"},
-   {Opt_active_logs, "active_logs=%u"},
-   {Opt_disable_ext_identify, "disable_ext_identify"},
-   {Opt_inline_xattr, "inline_xattr"},
-   {Opt_noinline_xattr, "noinline_xattr"},
-   {Opt_inline_xattr_size, "inline_xattr_size=%u"},
-   {Opt_inline_data, "inline_data"},
-   {Opt_inline_dentry, "inline_dentry"},
-   {Opt_noinline_dentry, "noinline_dentry"},
-   {Opt_flush_merge, "flush_merge"},
-   {Opt_noflush_merge, "noflush_merge"},
-   {Opt_barrier, "barrier"},
-   {Opt_nobarrier, "nobarrier"},
-   {Opt_fastboot, "fastboot"},
-   {Opt_extent_cache, "extent_cache"},
-   {Opt_noextent_cache, "noextent_cache"},
-   {Opt_noinline_data, "noinline_data"},
-   {Opt_data_flush, "data_flush"},
-   {Opt_reserve_root, "reserve_root=%u"},
-   {Opt_resgid, "resgid=%u"},
-   {Opt_resuid, "resuid=%u"},
-   {Opt_mode, "mode=%s"},
-   {Opt_fault_injection, "fault_injection=%u"},
-   {Opt_fault_type, "fault_type=%u"},
-   {Opt_lazytime, "lazytime"},
-   {Opt_nolazytime, "nolazytime"},
-   {Opt_quota, "quota"},
-   {Opt_noquota, "noquota"

Re: [f2fs-dev] [PATCH 0/9] f2fs: first steps towards mount API conversion

2025-04-12 Thread Eric Sandeen via Linux-f2fs-devel
On 4/1/25 3:33 PM, Eric Sandeen wrote:
> On 3/31/25 3:31 AM, Chao Yu wrote:
>> On 3/29/25 12:18, Eric Sandeen wrote:
>>> I was working on next steps for this, and I have a followup question.
>>>
>>> Today, several mount options are simply ignored if the on-disk format
>>> does not support them. For example:
>>>
>>> case Opt_compress_mode:
>>> if (!f2fs_sb_has_compression(sbi)) {
>>> f2fs_info(sbi, "Image doesn't support 
>>> compression");
>>> break;
>>> }
>>> name = match_strdup(&args[0]);
>>> if (!name)
>>> return -ENOMEM;
>>> if (!strcmp(name, "fs")) {
>>> F2FS_OPTION(sbi).compress_mode = 
>>> COMPR_MODE_FS;
>>> } else if (!strcmp(name, "user")) {
>>> F2FS_OPTION(sbi).compress_mode = 
>>> COMPR_MODE_USER;
>>> } else {
>>> kfree(name);
>>> return -EINVAL;
>>> }
>>> kfree(name);
>>> break;
>>>
>>> so if f2fs_sb_has_compression() is not true, then the option is ignored 
>>> without
>>> any validation.
>>>
>>> in other words, "mount -o compress_mode=nope ..." will succeed if the 
>>> feature
>>> is disabled on the filesystem.
>>>
>>> If I move the f2fs_sb_has_compression() check to later for the new mount 
>>> API,
>>> then "mount -o compress_mode=nope ..."  will start failing for all images. 
>>> Is
>>> this acceptable? It seems wise to reject invalid options rather than ignore 
>>> them,
>>> even if they are incompatible with the format, but this would be a behavior
>>> change.
>>
>> I'm fine w/ this change. IIRC, I haven't saw above use case, otherwise user
>> should stop passing invalid mount option to f2fs.
> 
> Great, I will proceed with this. It will make the conversion simpler (but may
> make testing/validation more difficult, as behavior will change with invalid 
> input).

FYI - I don't think I will be able to complete this conversion task myself - 
f2fs is
by far the most difficult conversion I've encountered, and my time for these 
sorts of
projects is sadly limited. I do have one more patch series that moves a lot of 
the
on-disk feature checking out of option parsing, and perhaps I will send it as 
an example
at least.

But I think it may be time to ask the f2fs experts to take over this effort, 
because
I'm just not getting through it on my own.

(We are down to only a small handful of filesystems left - in fact, I think only
bfs, 9p, and f2fs, that don't have patches anywhere. So it would be really 
great to
get some help on this.)

Thanks,
-Eric
 
> -Eric
> 
>> Thanks,



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-05 Thread Eric Sandeen via Linux-f2fs-devel
Hi all - it would be nice to get some review or feedback on this;
seems that these patches tend to go stale fairly quickly as f2fs
evolves. :)

Thanks,
-Eric

On 4/23/25 12:08 PM, Eric Sandeen wrote:
> V3:
> - Rebase onto git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
>   dev branch
> - Fix up some 0day robot warnings
> 
> This is a forward-port of Hongbo's original f2fs mount API conversion,
> posted last August at 
> https://lore.kernel.org/linux-f2fs-devel/20240814023912.3959299-1-lihongb...@huawei.com/
> 
> I had been trying to approach this with a little less complexity,
> but in the end I realized that Hongbo's approach (which follows
> the ext4 approach) was a good one, and I was not making any progrss
> myself. 😉
> 
> In addition to the forward-port, I have also fixed a couple bugs I found
> during testing, and some improvements / style choices as well. Hongbo and
> I have discussed most of this off-list already, so I'm presenting the
> net result here.
> 
> This does pass my typical testing which does a large number of random
> mounts/remounts with valid and invalid option sets, on f2fs filesystem
> images with various features in the on-disk superblock. (I was not able
> to test all of this completely, as some options or features require
> hardware I dn't have.)
> 
> Thanks,
> -Eric
> 
> (A recap of Hongbo's original cover letter is below, edited slightly for
> this series:)
> 
> Since many filesystems have done the new mount API conversion,
> we introduce the new mount API conversion in f2fs.
> 
> The series can be applied on top of the current mainline tree
> and the work is based on the patches from Lukas Czerner (has
> done this in ext4[1]). His patch give me a lot of ideas.
> 
> Here is a high level description of the patchset:
> 
> 1. Prepare the f2fs mount parameters required by the new mount
> API and use it for parsing, while still using the old API to
> get mount options string. Split the parameter parsing and
> validation of the parse_options helper into two separate
> helpers.
> 
>   f2fs: Add fs parameter specifications for mount options
>   f2fs: move the option parser into handle_mount_opt
> 
> 2. Remove the use of sb/sbi structure of f2fs from all the
> parsing code, because with the new mount API the parsing is
> going to be done before we even get the super block. In this
> part, we introduce f2fs_fs_context to hold the temporary
> options when parsing. For the simple options check, it has
> to be done during parsing by using f2fs_fs_context structure.
> For the check which needs sb/sbi, we do this during super
> block filling.
> 
>   f2fs: Allow sbi to be NULL in f2fs_printk
>   f2fs: Add f2fs_fs_context to record the mount options
>   f2fs: separate the options parsing and options checking
> 
> 3. Switch the f2fs to use the new mount API for mount and
> remount.
> 
>   f2fs: introduce fs_context_operation structure
>   f2fs: switch to the new mount api
> 
> [1] https://lore.kernel.org/all/20211021114508.21407-1-lczer...@redhat.com/
> 
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH AUTOSEL 6.14 156/642] f2fs: defer readonly check vs norecovery

2025-05-05 Thread Eric Sandeen via Linux-f2fs-devel
This commit is in no way a bugfix and I don't see any reason to
backport it to stable kernels.

Thanks,
-Eric

On 5/5/25 5:06 PM, Sasha Levin wrote:
> From: Eric Sandeen 
> 
> [ Upstream commit 9cca49875997a1a7e92800a828a62bacb0f577b9 ]
> 
> Defer the readonly-vs-norecovery check until after option parsing is done
> so that option parsing does not require an active superblock for the test.
> Add a helpful message, while we're at it.
> 
> (I think could be moved back into parsing after we switch to the new mount
> API if desired, as the fs context will have RO state available.)
> 
> Signed-off-by: Eric Sandeen 
> Reviewed-by: Chao Yu 
> Signed-off-by: Jaegeuk Kim 
> Signed-off-by: Sasha Levin 
> ---
>  fs/f2fs/super.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index b8a0e925a4011..d3b04a589b525 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -728,10 +728,8 @@ static int parse_options(struct super_block *sb, char 
> *options, bool is_remount)
>   set_opt(sbi, DISABLE_ROLL_FORWARD);
>   break;
>   case Opt_norecovery:
> - /* this option mounts f2fs with ro */
> + /* requires ro mount, checked in f2fs_default_check */
>   set_opt(sbi, NORECOVERY);
> - if (!f2fs_readonly(sb))
> - return -EINVAL;
>   break;
>   case Opt_discard:
>   if (!f2fs_hw_support_discard(sbi)) {
> @@ -1418,6 +1416,12 @@ static int parse_options(struct super_block *sb, char 
> *options, bool is_remount)
>   f2fs_err(sbi, "Allow to mount readonly mode only");
>   return -EROFS;
>   }
> +
> + if (test_opt(sbi, NORECOVERY) && !f2fs_readonly(sbi->sb)) {
> + f2fs_err(sbi, "norecovery requires readonly mount");
> + return -EINVAL;
> + }
> +
>   return 0;
>  }
>  



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 0/9] f2fs: first steps towards mount API conversion

2025-04-14 Thread Eric Sandeen via Linux-f2fs-devel
On 4/12/25 12:17 PM, Eric Sandeen wrote:

...

> FYI - I don't think I will be able to complete this conversion task myself - 
> f2fs is
> by far the most difficult conversion I've encountered, and my time for these 
> sorts of
> projects is sadly limited. I do have one more patch series that moves a lot 
> of the
> on-disk feature checking out of option parsing, and perhaps I will send it as 
> an example
> at least.
> 
> But I think it may be time to ask the f2fs experts to take over this effort, 
> because
> I'm just not getting through it on my own.
> 
> (We are down to only a small handful of filesystems left - in fact, I think 
> only
> bfs, 9p, and f2fs, that don't have patches anywhere. So it would be really 
> great to
> get some help on this.)

Sorry for replying to myself.

Actually, I will take one more try at this - when I first looked at Hongo Li's 
patches
to do the conversion, it seemed like there were a few problems, and I didn't 
review
fully. I realize now that although it was a different approach than I had been 
taking,
perhaps it was on the right track after all.

I'll try to evaluate that patch series more carefully and see if it solved the 
problems
I am struggling with now.

If it does, I'd be happy to work with you, Hongbo, to get this completed. Your 
series
will take a bit of forward-porting, as the codebase has moved forward quite a 
lot
since then. But I'll go back to an older kernel and evaluate the net result of 
your
changes, since I have some custom mount-option-testing framework here, and see 
how
things look.

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/7] f2fs: move the option parser into handle_mount_opt

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

In handle_mount_opt, we use fs_parameter to parse each option.
However we're still using the old API to get the options string.
Using fsparams parse_options allows us to remove many of the Opt_
enums, so remove them.

The checkpoint disable cap (or percent) involves rather complex
parsing; we retain the old match_table mechanism for this, which
handles it well.

There are some changes about parsing options:
  1. For `active_logs`, `inline_xattr_size` and `fault_injection`,
 we use s32 type according the internal structure to record the
 option's value.

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 1063 ++-
 1 file changed, 407 insertions(+), 656 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index c3623e052cde..8343dc2a515d 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "f2fs.h"
@@ -122,29 +123,20 @@ enum {
Opt_disable_roll_forward,
Opt_norecovery,
Opt_discard,
-   Opt_nodiscard,
Opt_noheap,
Opt_heap,
Opt_user_xattr,
-   Opt_nouser_xattr,
Opt_acl,
-   Opt_noacl,
Opt_active_logs,
Opt_disable_ext_identify,
Opt_inline_xattr,
-   Opt_noinline_xattr,
Opt_inline_xattr_size,
Opt_inline_data,
Opt_inline_dentry,
-   Opt_noinline_dentry,
Opt_flush_merge,
-   Opt_noflush_merge,
Opt_barrier,
-   Opt_nobarrier,
Opt_fastboot,
Opt_extent_cache,
-   Opt_noextent_cache,
-   Opt_noinline_data,
Opt_data_flush,
Opt_reserve_root,
Opt_resgid,
@@ -153,21 +145,13 @@ enum {
Opt_fault_injection,
Opt_fault_type,
Opt_lazytime,
-   Opt_nolazytime,
Opt_quota,
-   Opt_noquota,
Opt_usrquota,
Opt_grpquota,
Opt_prjquota,
Opt_usrjquota,
Opt_grpjquota,
Opt_prjjquota,
-   Opt_offusrjquota,
-   Opt_offgrpjquota,
-   Opt_offprjjquota,
-   Opt_jqfmt_vfsold,
-   Opt_jqfmt_vfsv0,
-   Opt_jqfmt_vfsv1,
Opt_alloc,
Opt_fsync,
Opt_test_dummy_encryption,
@@ -177,17 +161,15 @@ enum {
Opt_checkpoint_disable_cap_perc,
Opt_checkpoint_enable,
Opt_checkpoint_merge,
-   Opt_nocheckpoint_merge,
Opt_compress_algorithm,
Opt_compress_log_size,
-   Opt_compress_extension,
Opt_nocompress_extension,
+   Opt_compress_extension,
Opt_compress_chksum,
Opt_compress_mode,
Opt_compress_cache,
Opt_atgc,
Opt_gc_merge,
-   Opt_nogc_merge,
Opt_discard_unit,
Opt_memory_mode,
Opt_age_extent_cache,
@@ -317,83 +299,12 @@ static const struct fs_parameter_spec f2fs_param_specs[] 
= {
{}
 };
 
-static match_table_t f2fs_tokens = {
-   {Opt_gc_background, "background_gc=%s"},
-   {Opt_disable_roll_forward, "disable_roll_forward"},
-   {Opt_norecovery, "norecovery"},
-   {Opt_discard, "discard"},
-   {Opt_nodiscard, "nodiscard"},
-   {Opt_noheap, "no_heap"},
-   {Opt_heap, "heap"},
-   {Opt_user_xattr, "user_xattr"},
-   {Opt_nouser_xattr, "nouser_xattr"},
-   {Opt_acl, "acl"},
-   {Opt_noacl, "noacl"},
-   {Opt_active_logs, "active_logs=%u"},
-   {Opt_disable_ext_identify, "disable_ext_identify"},
-   {Opt_inline_xattr, "inline_xattr"},
-   {Opt_noinline_xattr, "noinline_xattr"},
-   {Opt_inline_xattr_size, "inline_xattr_size=%u"},
-   {Opt_inline_data, "inline_data"},
-   {Opt_inline_dentry, "inline_dentry"},
-   {Opt_noinline_dentry, "noinline_dentry"},
-   {Opt_flush_merge, "flush_merge"},
-   {Opt_noflush_merge, "noflush_merge"},
-   {Opt_barrier, "barrier"},
-   {Opt_nobarrier, "nobarrier"},
-   {Opt_fastboot, "fastboot"},
-   {Opt_extent_cache, "extent_cache"},
-   {Opt_noextent_cache, "noextent_cache"},
-   {Opt_noinline_data, "noinline_data"},
-   {Opt_data_flush, "data_flush"},
-   {Opt_reserve_root, "reserve_root=%u"},
-   {Opt_resgid, "resgid=%u"},
-   {Opt_resuid, "resuid=%u"},
-   {Opt_mode, "mode=%s"},
-   {Opt_fault_injection, "fault_injection=%u"},
-   {Opt_fault_type, "fault_type=%u"},
-   {Opt_lazytime, "lazytime"},
-   {Opt_nolazytime, "nolazytime"},
-   {Opt_quota, "quota"},
-   {Opt_noquota, "noquota"

[f2fs-dev] [PATCH 4/7] f2fs: Add f2fs_fs_context to record the mount options

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

At the parsing phase of mouont in the new mount api, options
value will be recorded with the context, and then it will be
used in fill_super and other helpers.

Note that, this is a temporary status, we want remove the sb
and sbi usages in handle_mount_opt. So here the f2fs_fs_context
only records the mount options, it will be copied in sb/sbi in
later process. (At this point in the series, mount options are
temporarily not set during mount.)

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 419 
 1 file changed, 244 insertions(+), 175 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index aeb8e9a48bf6..11bf936b0d3c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -308,8 +308,65 @@ static match_table_t f2fs_checkpoint_tokens = {
{Opt_err, NULL},
 };
 
+#define F2FS_SPEC_background_gc(1 << 0)
+#define F2FS_SPEC_inline_xattr_size(1 << 1)
+#define F2FS_SPEC_active_logs  (1 << 2)
+#define F2FS_SPEC_reserve_root (1 << 3)
+#define F2FS_SPEC_resgid   (1 << 4)
+#define F2FS_SPEC_resuid   (1 << 5)
+#define F2FS_SPEC_mode (1 << 6)
+#define F2FS_SPEC_fault_injection  (1 << 7)
+#define F2FS_SPEC_fault_type   (1 << 8)
+#define F2FS_SPEC_jqfmt(1 << 9)
+#define F2FS_SPEC_alloc_mode   (1 << 10)
+#define F2FS_SPEC_fsync_mode   (1 << 11)
+#define F2FS_SPEC_checkpoint_disable_cap   (1 << 12)
+#define F2FS_SPEC_checkpoint_disable_cap_perc  (1 << 13)
+#define F2FS_SPEC_compress_level   (1 << 14)
+#define F2FS_SPEC_compress_algorithm   (1 << 15)
+#define F2FS_SPEC_compress_log_size(1 << 16)
+#define F2FS_SPEC_compress_extension   (1 << 17)
+#define F2FS_SPEC_nocompress_extension (1 << 18)
+#define F2FS_SPEC_compress_chksum  (1 << 19)
+#define F2FS_SPEC_compress_mode(1 << 20)
+#define F2FS_SPEC_discard_unit (1 << 21)
+#define F2FS_SPEC_memory_mode  (1 << 22)
+#define F2FS_SPEC_errors   (1 << 23)
+
+struct f2fs_fs_context {
+   struct f2fs_mount_info info;
+   unsigned intopt_mask;   /* Bits changed */
+   unsigned intspec_mask;
+   unsigned short  qname_mask;
+   unsigned long   sflags;
+   unsigned long   sflags_mask;
+};
+
+#define F2FS_CTX_INFO(ctx) ((ctx)->info)
+
+static inline void ctx_set_opt(struct f2fs_fs_context *ctx,
+  unsigned int flag)
+{
+   ctx->info.opt |= flag;
+   ctx->opt_mask |= flag;
+}
+
+static inline void ctx_clear_opt(struct f2fs_fs_context *ctx,
+unsigned int flag)
+{
+   ctx->info.opt &= ~flag;
+   ctx->opt_mask |= flag;
+}
+
+static inline void ctx_set_flags(struct f2fs_fs_context *ctx,
+unsigned int flag)
+{
+   ctx->sflags |= flag;
+   ctx->sflags_mask |= flag;
+}
+
 void f2fs_printk(struct f2fs_sb_info *sbi, bool limit_rate,
-   const char *fmt, ...)
+   const char *fmt, ...)
 {
struct va_format vaf;
va_list args;
@@ -427,57 +484,51 @@ static void init_once(void *foo)
 #ifdef CONFIG_QUOTA
 static const char * const quotatypes[] = INITQFNAMES;
 #define QTYPE2NAME(t) (quotatypes[t])
-static int f2fs_set_qf_name(struct f2fs_sb_info *sbi, int qtype,
-   struct fs_parameter *param)
+/*
+ * Note the name of the specified quota file.
+ */
+static int f2fs_note_qf_name(struct fs_context *fc, int qtype,
+struct fs_parameter *param)
 {
-   struct super_block *sb = sbi->sb;
+   struct f2fs_fs_context *ctx = fc->fs_private;
char *qname;
-   int ret = -EINVAL;
 
-   if (sb_any_quota_loaded(sb) && !F2FS_OPTION(sbi).s_qf_names[qtype]) {
-   f2fs_err(sbi, "Cannot change journaled quota options when quota 
turned on");
+   if (param->size < 1) {
+   f2fs_err(NULL, "Missing quota name");
return -EINVAL;
}
-   if (f2fs_sb_has_quota_ino(sbi)) {
-   f2fs_info(sbi, "QUOTA feature is enabled, so ignore qf_name");
+   if (strchr(param->string, '/')) {
+   f2fs_err(NULL, "quotafile must be on filesystem root");
+   return -EINVAL;
+   }
+   if (ctx->info.s_qf_names[qtype]) {
+   if (strcmp(ctx->info.s_qf_names[qtype

[f2fs-dev] [PATCH 5/7] f2fs: separate the options parsing and options checking

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

The new mount api separates option parsing and super block setup
into two distinct steps and so we need to separate the options
parsing out of the parse_options().

In order to achieve this, here we handle the mount options with
three steps:
  - Firstly, we move sb/sbi out of handle_mount_opt.
As the former patch introduced f2fs_fs_context, so we record
the changed mount options in this context. In handle_mount_opt,
sb/sbi is null, so we should move all relative code out of
handle_mount_opt (thus, some check case which use sb/sbi should
move out).
  - Secondly, we introduce the some check helpers to keep the option
consistent.
During filling superblock period, sb/sbi are ready. So we check
the f2fs_fs_context which holds the mount options base on sb/sbi.
  - Thirdly, we apply the new mount options to sb/sbi.
After checking the f2fs_fs_context, all changed on mount options
are valid. So we can apply them to sb/sbi directly.

After do these, option parsing and super block setting have been
decoupled. Also it should have retained the original execution
flow.

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 694 +++-
 1 file changed, 510 insertions(+), 184 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 11bf936b0d3c..818db1e9549b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -358,6 +358,12 @@ static inline void ctx_clear_opt(struct f2fs_fs_context 
*ctx,
ctx->opt_mask |= flag;
 }
 
+static inline bool ctx_test_opt(struct f2fs_fs_context *ctx,
+   unsigned int flag)
+{
+   return ctx->info.opt & flag;
+}
+
 static inline void ctx_set_flags(struct f2fs_fs_context *ctx,
 unsigned int flag)
 {
@@ -531,51 +537,6 @@ static int f2fs_unnote_qf_name(struct fs_context *fc, int 
qtype)
ctx->qname_mask |= 1 << qtype;
return 0;
 }
-
-static int f2fs_check_quota_options(struct f2fs_sb_info *sbi)
-{
-   /*
-* We do the test below only for project quotas. 'usrquota' and
-* 'grpquota' mount options are allowed even without quota feature
-* to support legacy quotas in quota files.
-*/
-   if (test_opt(sbi, PRJQUOTA) && !f2fs_sb_has_project_quota(sbi)) {
-   f2fs_err(sbi, "Project quota feature not enabled. Cannot enable 
project quota enforcement.");
-   return -1;
-   }
-   if (F2FS_OPTION(sbi).s_qf_names[USRQUOTA] ||
-   F2FS_OPTION(sbi).s_qf_names[GRPQUOTA] ||
-   F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]) {
-   if (test_opt(sbi, USRQUOTA) &&
-   F2FS_OPTION(sbi).s_qf_names[USRQUOTA])
-   clear_opt(sbi, USRQUOTA);
-
-   if (test_opt(sbi, GRPQUOTA) &&
-   F2FS_OPTION(sbi).s_qf_names[GRPQUOTA])
-   clear_opt(sbi, GRPQUOTA);
-
-   if (test_opt(sbi, PRJQUOTA) &&
-   F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
-   clear_opt(sbi, PRJQUOTA);
-
-   if (test_opt(sbi, GRPQUOTA) || test_opt(sbi, USRQUOTA) ||
-   test_opt(sbi, PRJQUOTA)) {
-   f2fs_err(sbi, "old and new quota format mixing");
-   return -1;
-   }
-
-   if (!F2FS_OPTION(sbi).s_jquota_fmt) {
-   f2fs_err(sbi, "journaled quota format not specified");
-   return -1;
-   }
-   }
-
-   if (f2fs_sb_has_quota_ino(sbi) && F2FS_OPTION(sbi).s_jquota_fmt) {
-   f2fs_info(sbi, "QUOTA feature is enabled, so ignore 
jquota_fmt");
-   F2FS_OPTION(sbi).s_jquota_fmt = 0;
-   }
-   return 0;
-}
 #endif
 
 static int f2fs_parse_test_dummy_encryption(const struct fs_parameter *param,
@@ -634,28 +595,28 @@ static bool is_compress_extension_exist(struct 
f2fs_mount_info *info,
  * extension will be treated as special cases and will not be compressed.
  * 3. Don't allow the non-compress extension specifies all files.
  */
-static int f2fs_test_compress_extension(struct f2fs_sb_info *sbi)
+static int f2fs_test_compress_extension(unsigned char 
(*noext)[F2FS_EXTENSION_LEN],
+   int noext_cnt,
+   unsigned char 
(*ext)[F2FS_EXTENSION_LEN],
+   int ext_cnt)
 {
-   unsigned char (*ext)[F2FS_EXTENSION_LEN];
-   unsigned char (*noext)[F2FS_EXTENSION_LEN];
-   int ext_cnt, noext_cnt, index = 0, no_index = 0;
-
-   ext = F2FS_OPTION(sbi).extensions;
-   ext_cnt = F2FS_OPTION(sbi).compress_ext_cn

[f2fs-dev] [PATCH 6/7] f2fs: introduce fs_context_operation structure

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

The handle_mount_opt() helper is used to parse mount parameters,
and so we can rename this function to f2fs_parse_param() and set
it as .param_param in fs_context_operations.

Signed-off-by: Hongbo Li 
[sandeen: forward port]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 818db1e9549b..21042a02459f 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -705,7 +705,7 @@ static int f2fs_set_zstd_level(struct f2fs_fs_context *ctx, 
const char *str)
 #endif
 #endif
 
-static int handle_mount_opt(struct fs_context *fc, struct fs_parameter *param)
+static int f2fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
struct f2fs_fs_context *ctx = fc->fs_private;
 #ifdef CONFIG_F2FS_FS_COMPRESSION
@@ -1171,7 +1171,7 @@ static int parse_options(struct fs_context *fc, char 
*options)
param.key = key;
param.size = v_len;
 
-   ret = handle_mount_opt(fc, ¶m);
+   ret = f2fs_parse_param(fc, ¶m);
kfree(param.string);
if (ret < 0)
return ret;
@@ -5273,6 +5273,10 @@ static struct dentry *f2fs_mount(struct file_system_type 
*fs_type, int flags,
return mount_bdev(fs_type, flags, dev_name, data, f2fs_fill_super);
 }
 
+static const struct fs_context_operations f2fs_context_ops = {
+   .parse_param= f2fs_parse_param,
+};
+
 static void kill_f2fs_super(struct super_block *sb)
 {
struct f2fs_sb_info *sbi = F2FS_SB(sb);
-- 
2.47.0



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 7/7] f2fs: switch to the new mount api

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

The new mount api will execute .parse_param, .init_fs_context, .get_tree
and will call .remount if remount happened. So we add the necessary
functions for the fs_context_operations. If .init_fs_context is added,
the old .mount should remove.

See Documentation/filesystems/mount_api.rst for more information.

Signed-off-by: Hongbo Li 
[sandeen: forward port]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 156 +++-
 1 file changed, 62 insertions(+), 94 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 21042a02459f..28a7aa01d009 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1139,47 +1139,6 @@ static int f2fs_parse_param(struct fs_context *fc, 
struct fs_parameter *param)
return 0;
 }
 
-static int parse_options(struct fs_context *fc, char *options)
-{
-   struct fs_parameter param;
-   char *key;
-   int ret;
-
-   if (!options)
-   return 0;
-
-   while ((key = strsep(&options, ",")) != NULL) {
-   if (*key) {
-   size_t v_len = 0;
-   char *value = strchr(key, '=');
-
-   param.type = fs_value_is_flag;
-   param.string = NULL;
-
-   if (value) {
-   if (value == key)
-   continue;
-
-   *value++ = 0;
-   v_len = strlen(value);
-   param.string = kmemdup_nul(value, v_len, 
GFP_KERNEL);
-   if (!param.string)
-   return -ENOMEM;
-   param.type = fs_value_is_string;
-   }
-
-   param.key = key;
-   param.size = v_len;
-
-   ret = f2fs_parse_param(fc, ¶m);
-   kfree(param.string);
-   if (ret < 0)
-   return ret;
-   }
-   }
-   return 0;
-}
-
 /*
  * Check quota settings consistency.
  */
@@ -2579,13 +2538,12 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info 
*sbi)
f2fs_flush_ckpt_thread(sbi);
 }
 
-static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+static int __f2fs_remount(struct fs_context *fc, struct super_block *sb)
 {
struct f2fs_sb_info *sbi = F2FS_SB(sb);
struct f2fs_mount_info org_mount_opt;
-   struct f2fs_fs_context ctx;
-   struct fs_context fc;
unsigned long old_sb_flags;
+   unsigned int flags = fc->sb_flags;
int err;
bool need_restart_gc = false, need_stop_gc = false;
bool need_restart_flush = false, need_stop_flush = false;
@@ -2631,7 +2589,7 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
 #endif
 
/* recover superblocks we couldn't write due to previous RO mount */
-   if (!(*flags & SB_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
+   if (!(flags & SB_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
err = f2fs_commit_super(sbi, false);
f2fs_info(sbi, "Try to recover all the superblocks, ret: %d",
  err);
@@ -2641,21 +2599,11 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
 
default_options(sbi, true);
 
-   memset(&fc, 0, sizeof(fc));
-   memset(&ctx, 0, sizeof(ctx));
-   fc.fs_private = &ctx;
-   fc.purpose = FS_CONTEXT_FOR_RECONFIGURE;
-
-   /* parse mount options */
-   err = parse_options(&fc, data);
-   if (err)
-   goto restore_opts;
-
-   err = f2fs_check_opt_consistency(&fc, sb);
+   err = f2fs_check_opt_consistency(fc, sb);
if (err < 0)
goto restore_opts;
 
-   f2fs_apply_options(&fc, sb);
+   f2fs_apply_options(fc, sb);
 
 #ifdef CONFIG_BLK_DEV_ZONED
if (f2fs_sb_has_blkzoned(sbi) &&
@@ -2674,20 +2622,20 @@ static int f2fs_remount(struct super_block *sb, int 
*flags, char *data)
 * Previous and new state of filesystem is RO,
 * so skip checking GC and FLUSH_MERGE conditions.
 */
-   if (f2fs_readonly(sb) && (*flags & SB_RDONLY))
+   if (f2fs_readonly(sb) && (flags & SB_RDONLY))
goto skip;
 
-   if (f2fs_dev_is_readonly(sbi) && !(*flags & SB_RDONLY)) {
+   if (f2fs_dev_is_readonly(sbi) && !(flags & SB_RDONLY)) {
err = -EROFS;
goto restore_opts;
}
 
 #ifdef CONFIG_QUOTA
-   if (!f2fs_readonly(sb) && (*flags & SB_RDONLY)) {
+   if (!f2fs_readonly(sb) && (flags & SB_RDONLY)) {
err = dquot_suspend(sb, -1);
if (

[f2fs-dev] [PATCH 0/7 V2] f2fs: new mount API conversion

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
This is a forward-port of Hongbo's original f2fs mount API conversion,
posted last August at 
https://lore.kernel.org/linux-f2fs-devel/20240814023912.3959299-1-lihongb...@huawei.com/

I had been trying to approach this with a little less complexity,
but in the end I realized that Hongbo's approach (which follows
the ext4 approach) was a good one, and I was not making any progrss
myself. ;)

In addition to the forward-port, I have also fixed a couple bugs I found
during testing, and some improvements / style choices as well. Hongbo and
I have discussed most of this off-list already, so I'm presenting the
net result here.

This does pass my typical testing which does a large number of random
mounts/remounts with valid and invalid option sets, on f2fs filesystem
images with various features in the on-disk superblock. (I was not able
to test all of this completely, as some options or features require
hardware I dn't have.)

Thanks,
-Eric

(A recap of Hongbo's original cover letter is below, edited slightly for
this series:)

Since many filesystems have done the new mount API conversion,
we introduce the new mount API conversion in f2fs.

The series can be applied on top of the current mainline tree
and the work is based on the patches from Lukas Czerner (has
done this in ext4[1]). His patch give me a lot of ideas.

Here is a high level description of the patchset:

1. Prepare the f2fs mount parameters required by the new mount
API and use it for parsing, while still using the old API to
get mount options string. Split the parameter parsing and
validation of the parse_options helper into two separate
helpers.

  f2fs: Add fs parameter specifications for mount options
  f2fs: move the option parser into handle_mount_opt

2. Remove the use of sb/sbi structure of f2fs from all the
parsing code, because with the new mount API the parsing is
going to be done before we even get the super block. In this
part, we introduce f2fs_fs_context to hold the temporary
options when parsing. For the simple options check, it has
to be done during parsing by using f2fs_fs_context structure.
For the check which needs sb/sbi, we do this during super
block filling.

  f2fs: Allow sbi to be NULL in f2fs_printk
  f2fs: Add f2fs_fs_context to record the mount options
  f2fs: separate the options parsing and options checking

3. Switch the f2fs to use the new mount API for mount and
remount.

  f2fs: introduce fs_context_operation structure
  f2fs: switch to the new mount api

[1] https://lore.kernel.org/all/20211021114508.21407-1-lczer...@redhat.com/




___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 3/7] f2fs: Allow sbi to be NULL in f2fs_printk

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

At the parsing phase of the new mount api, sbi will not be
available. So here allows sbi to be NULL in f2fs log helpers
and use that in handle_mount_opt().

Signed-off-by: Hongbo Li 
[sandeen: forward port]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 90 +++--
 1 file changed, 49 insertions(+), 41 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8343dc2a515d..aeb8e9a48bf6 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -321,11 +321,19 @@ void f2fs_printk(struct f2fs_sb_info *sbi, bool 
limit_rate,
vaf.fmt = printk_skip_level(fmt);
vaf.va = &args;
if (limit_rate)
-   printk_ratelimited("%c%cF2FS-fs (%s): %pV\n",
-   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   if (sbi)
+   printk_ratelimited("%c%cF2FS-fs (%s): %pV\n",
+   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   else
+   printk_ratelimited("%c%cF2FS-fs: %pV\n",
+   KERN_SOH_ASCII, level, &vaf);
else
-   printk("%c%cF2FS-fs (%s): %pV\n",
-   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   if (sbi)
+   printk("%c%cF2FS-fs (%s): %pV\n",
+   KERN_SOH_ASCII, level, sbi->sb->s_id, &vaf);
+   else
+   printk("%c%cF2FS-fs: %pV\n",
+   KERN_SOH_ASCII, level, &vaf);
 
va_end(args);
 }
@@ -735,13 +743,13 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
case Opt_discard:
if (result.negated) {
if (f2fs_hw_should_discard(sbi)) {
-   f2fs_warn(sbi, "discard is required for zoned 
block devices");
+   f2fs_warn(NULL, "discard is required for zoned 
block devices");
return -EINVAL;
}
clear_opt(sbi, DISCARD);
} else {
if (!f2fs_hw_support_discard(sbi)) {
-   f2fs_warn(sbi, "device does not support 
discard");
+   f2fs_warn(NULL, "device does not support 
discard");
break;
}
set_opt(sbi, DISCARD);
@@ -749,7 +757,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
break;
case Opt_noheap:
case Opt_heap:
-   f2fs_warn(sbi, "heap/no_heap options were deprecated");
+   f2fs_warn(NULL, "heap/no_heap options were deprecated");
break;
 #ifdef CONFIG_F2FS_FS_XATTR
case Opt_user_xattr:
@@ -772,7 +780,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
case Opt_user_xattr:
case Opt_inline_xattr:
case Opt_inline_xattr_size:
-   f2fs_info(sbi, "%s options not supported", param->key);
+   f2fs_info(NULL, "%s options not supported", param->key);
break;
 #endif
 #ifdef CONFIG_F2FS_FS_POSIX_ACL
@@ -784,7 +792,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
break;
 #else
case Opt_acl:
-   f2fs_info(sbi, "%s options not supported", param->key);
+   f2fs_info(NULL, "%s options not supported", param->key);
break;
 #endif
case Opt_active_logs:
@@ -838,7 +846,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
break;
case Opt_reserve_root:
if (test_opt(sbi, RESERVE_ROOT)) {
-   f2fs_info(sbi, "Preserve previous reserve_root=%u",
+   f2fs_info(NULL, "Preserve previous reserve_root=%u",
  F2FS_OPTION(sbi).root_reserved_blocks);
} else {
F2FS_OPTION(sbi).root_reserved_blocks = result.int_32;
@@ -870,7 +878,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
 #else
case Opt_fault_injection:
case Opt_fault_type:
-   f2fs_info(sbi, "%s options not supported", param->key);
+   f2fs_info(NULL, "%s options not supported", param->key);
break;
 #endif
case Opt_lazytime:
@@ -933,7 +941,7 @@ static int handle_mount_opt(struct fs_context *fc, struct 
fs_parameter *param)
case Opt_usrjquota:
case Opt_grpjquota:

[f2fs-dev] [PATCH 1/7] f2fs: Add fs parameter specifications for mount options

2025-04-21 Thread Eric Sandeen via Linux-f2fs-devel
From: Hongbo Li 

Use an array of `fs_parameter_spec` called f2fs_param_specs to
hold the mount option specifications for the new mount api.

Add constant_table structures for several options to facilitate
parsing.

Signed-off-by: Hongbo Li 
[sandeen: forward port, minor fixes and updates, more fsparam_enum]
Signed-off-by: Eric Sandeen 
---
 fs/f2fs/super.c | 122 
 1 file changed, 122 insertions(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index f087b2b71c89..c3623e052cde 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "f2fs.h"
 #include "node.h"
@@ -192,9 +193,130 @@ enum {
Opt_age_extent_cache,
Opt_errors,
Opt_nat_bits,
+   Opt_jqfmt,
+   Opt_checkpoint,
Opt_err,
 };
 
+static const struct constant_table f2fs_param_background_gc[] = {
+   {"on",  BGGC_MODE_ON},
+   {"off", BGGC_MODE_OFF},
+   {"sync",BGGC_MODE_SYNC},
+   {}
+};
+
+static const struct constant_table f2fs_param_mode[] = {
+   {"adaptive",FS_MODE_ADAPTIVE},
+   {"lfs", FS_MODE_LFS},
+   {"fragment:segment",FS_MODE_FRAGMENT_SEG},
+   {"fragment:block",  FS_MODE_FRAGMENT_BLK},
+   {}
+};
+
+static const struct constant_table f2fs_param_jqfmt[] = {
+   {"vfsold",  QFMT_VFS_OLD},
+   {"vfsv0",   QFMT_VFS_V0},
+   {"vfsv1",   QFMT_VFS_V1},
+   {}
+};
+
+static const struct constant_table f2fs_param_alloc_mode[] = {
+   {"default", ALLOC_MODE_DEFAULT},
+   {"reuse",   ALLOC_MODE_REUSE},
+   {}
+};
+static const struct constant_table f2fs_param_fsync_mode[] = {
+   {"posix",   FSYNC_MODE_POSIX},
+   {"strict",  FSYNC_MODE_STRICT},
+   {"nobarrier",   FSYNC_MODE_NOBARRIER},
+   {}
+};
+
+static const struct constant_table f2fs_param_compress_mode[] = {
+   {"fs",  COMPR_MODE_FS},
+   {"user",COMPR_MODE_USER},
+   {}
+};
+
+static const struct constant_table f2fs_param_discard_unit[] = {
+   {"block",   DISCARD_UNIT_BLOCK},
+   {"segment", DISCARD_UNIT_SEGMENT},
+   {"section", DISCARD_UNIT_SECTION},
+   {}
+};
+
+static const struct constant_table f2fs_param_memory_mode[] = {
+   {"normal",  MEMORY_MODE_NORMAL},
+   {"low", MEMORY_MODE_LOW},
+   {}
+};
+
+static const struct constant_table f2fs_param_errors[] = {
+   {"remount-ro",  MOUNT_ERRORS_READONLY},
+   {"continue",MOUNT_ERRORS_CONTINUE},
+   {"panic",   MOUNT_ERRORS_PANIC},
+   {}
+};
+
+static const struct fs_parameter_spec f2fs_param_specs[] = {
+   fsparam_enum("background_gc", Opt_gc_background, 
f2fs_param_background_gc),
+   fsparam_flag("disable_roll_forward", Opt_disable_roll_forward),
+   fsparam_flag("norecovery", Opt_norecovery),
+   fsparam_flag_no("discard", Opt_discard),
+   fsparam_flag("no_heap", Opt_noheap),
+   fsparam_flag("heap", Opt_heap),
+   fsparam_flag_no("user_xattr", Opt_user_xattr),
+   fsparam_flag_no("acl", Opt_acl),
+   fsparam_s32("active_logs", Opt_active_logs),
+   fsparam_flag("disable_ext_identify", Opt_disable_ext_identify),
+   fsparam_flag_no("inline_xattr", Opt_inline_xattr),
+   fsparam_s32("inline_xattr_size", Opt_inline_xattr_size),
+   fsparam_flag_no("inline_data", Opt_inline_data),
+   fsparam_flag_no("inline_dentry", Opt_inline_dentry),
+   fsparam_flag_no("flush_merge", Opt_flush_merge),
+   fsparam_flag_no("barrier", Opt_barrier),
+   fsparam_flag("fastboot", Opt_fastboot),
+   fsparam_flag_no("extent_cache", Opt_extent_cache),
+   fsparam_flag("data_flush", Opt_data_flush),
+   fsparam_u32("reserve_root", Opt_reserve_root),
+   fsparam_gid("resgid", Opt_resgid),
+   fsparam_uid("resuid", Opt_resuid),
+   fsparam_enum("mode", Opt_mode, f2fs_param_mode),
+   fsparam_s32("fault_injection", Opt_fault_injection),
+   fsparam_u32("fault_type", Opt_fault_type),
+   fsparam_flag_no("lazytime", Opt_lazytime),
+   fsparam_flag_no("quota", Opt_quota),
+   fsparam_flag("usrquota", Opt_usrquota),
+   fsparam_flag("grpquota", Opt_grpquota),
+   fsparam_flag("prjquota", Opt_prjquota),
+   fsparam_string_empty("usrjquota", O

Re: [f2fs-dev] [PATCH 2/7] f2fs: move the option parser into handle_mount_opt

2025-05-07 Thread Eric Sandeen via Linux-f2fs-devel
On 5/7/25 6:26 AM, Chao Yu wrote:
> On 4/20/25 23:25, Eric Sandeen wrote:
>> From: Hongbo Li 
>>
>> In handle_mount_opt, we use fs_parameter to parse each option.
>> However we're still using the old API to get the options string.
>> Using fsparams parse_options allows us to remove many of the Opt_
>> enums, so remove them.
>>
>> The checkpoint disable cap (or percent) involves rather complex
>> parsing; we retain the old match_table mechanism for this, which
>> handles it well.
>>
>> There are some changes about parsing options:
>>   1. For `active_logs`, `inline_xattr_size` and `fault_injection`,
>>  we use s32 type according the internal structure to record the
>>  option's value.
> 
> We'd better to use u32 type for these options, as they should never
> be negative.
> 
> Can you please update based on below patch?
> 
> https://lore.kernel.org/linux-f2fs-devel/20250507112425.939246-1-c...@kernel.org

Hi Chao - I agree that that patch makes sense, but maybe there is a timing
issue now? At the moment, there is a mix of signed and unsigned handling
for these options. I agree that the conversion series probably should have
left the parsing type as unsigned, but it was a mix internally, so it was
difficult to know for sure.

For your patch above, if it is to stand alone or be merged first, it 
should probably also change the current parsing to match_uint. (this would
also make it backportable to -stable kernels, if you want to).

Otherwise, I would suggest that if it is merged after the mount API series,
then your patch to clean up internal types could fix the (new mount API)
parsing from %s to %u at the same time?

Happy to do it either way but your patch should probably be internally
consistent, changing the parsing types at the same time.

(I suppose we could incorporate your patch into the mount API series too,
though it'd be a little strange to have a minor bugfix like this buried
in the series.)

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-07 Thread Eric Sandeen via Linux-f2fs-devel
On 5/7/25 9:46 AM, Jaegeuk Kim wrote:

> I meant:
> 
> # mkfs/mkfs.f2fs -c /dev/v...@vdc.file /dev/vdb
> # mount /dev/vdb mnt
> 
> It's supposed to be successful, since extent_cache is enabled by default.

I'm sorry, clearly I was too sleepy last night. This fixes it for me.

We have to test the mask to see if the option was explisitly set (either
extent_cache or noextent_cache) at mount time.

If it was not specified at all, it will be set by the default f'n and
remain in the sbi, and it will pass this consistency check.

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d89b9ede221e..e178796ce9a7 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1412,7 +1414,8 @@ static int f2fs_check_opt_consistency(struct fs_context 
*fc,
}
 
if (f2fs_sb_has_device_alias(sbi) &&
-   !ctx_test_opt(ctx, F2FS_MOUNT_READ_EXTENT_CACHE)) {
+   (ctx->opt_mask & F2FS_MOUNT_READ_EXTENT_CACHE) &&
+!ctx_test_opt(ctx, F2FS_MOUNT_READ_EXTENT_CACHE)) {
f2fs_err(sbi, "device aliasing requires extent cache");
return -EINVAL;
}



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 5/7] f2fs: separate the options parsing and options checking

2025-05-08 Thread Eric Sandeen via Linux-f2fs-devel
On 5/8/25 3:13 AM, Chao Yu wrote:
> On 4/24/25 01:08, Eric Sandeen wrote:
>> From: Hongbo Li 

...

>> +if (ctx->qname_mask) {
>> +for (i = 0; i < MAXQUOTAS; i++) {
>> +if (!(ctx->qname_mask & (1 << i)))
>> +continue;
>> +
>> +old_qname = F2FS_OPTION(sbi).s_qf_names[i];
>> +new_qname = F2FS_CTX_INFO(ctx).s_qf_names[i];
>> +if (quota_turnon &&
>> +!!old_qname != !!new_qname)
>> +goto err_jquota_change;
>> +
>> +if (old_qname) {
>> +if (strcmp(old_qname, new_qname) == 0) {
>> +ctx->qname_mask &= ~(1 << i);
> 
> Needs to free and nully F2FS_CTX_INFO(ctx).s_qf_names[i]?
> 

I will have to look into this. If s_qf_names are used/applied, they get
transferred to the sbi in f2fs_apply_quota_options and are freed in the
normal course of the fiesystem lifetime, i.e at unmount in f2fs_put_super.
That's the normal non-error lifecycle of the strings.

If they do not get transferred to the sbi in f2fs_apply_quota_options, they
remain on the ctx, and should get freed in f2fs_fc_free:

for (i = 0; i < MAXQUOTAS; i++)
kfree(F2FS_CTX_INFO(ctx).s_qf_names[i]);

It is possible to free them before f2fs_fc_free of course and that might
be an inconsistency in this function, because we do that in the other case
in the check_consistency function:

if (quota_feature) {
f2fs_info(sbi, "QUOTA feature is enabled, so 
ignore qf_name");
ctx->qname_mask &= ~(1 << i);
kfree(F2FS_CTX_INFO(ctx).s_qf_names[i]);
F2FS_CTX_INFO(ctx).s_qf_names[i] = NULL;
}

I'll have to look at it a bit more. But this is modeled on ext4's
ext4_check_quota_consistency(), and it does not do any freeing in that
function; it leaves freeing in error cases to when the fc / ctx gets freed.

But tl;dr: I think we can remove the kfree and "= NULL" in this function,
and defer the freeing in the error case.

>> +
>> +static inline void clear_compression_spec(struct f2fs_fs_context *ctx)
>> +{
>> +ctx->spec_mask &= ~(F2FS_SPEC_compress_algorithm
>> +| F2FS_SPEC_compress_log_size
>> +| F2FS_SPEC_compress_extension
>> +| F2FS_SPEC_nocompress_extension
>> +| F2FS_SPEC_compress_chksum
>> +| F2FS_SPEC_compress_mode);
> 
> How about add a macro to include all compression macros, and use it to clean
> up above codes?

That's a good idea and probably easy enough to do without rebase pain.
 
>> +
>> +if (f2fs_test_compress_extension(F2FS_CTX_INFO(ctx).noextensions,
>> +F2FS_CTX_INFO(ctx).nocompress_ext_cnt,
>> +F2FS_CTX_INFO(ctx).extensions,
>> +F2FS_CTX_INFO(ctx).compress_ext_cnt)) {
>> +f2fs_err(sbi, "invalid compress or nocompress extension");
> 
> Can you please describe what is detailed confliction in the log? e.g. new
> noext conflicts w/ new ext...

Hmm, let me think about this. I had not noticed it was calling 
f2fs_test_compress_extension 3 times, I wonder if there is a better option.
I need to understand this approach better. Maybe Hongbo has thoughts.

>> +return -EINVAL;
>> +}
>> +if (f2fs_test_compress_extension(F2FS_CTX_INFO(ctx).noextensions,
>> +F2FS_CTX_INFO(ctx).nocompress_ext_cnt,
>> +F2FS_OPTION(sbi).extensions,
>> +F2FS_OPTION(sbi).compress_ext_cnt)) {
>> +f2fs_err(sbi, "invalid compress or nocompress extension");
> 
> Ditto,
> 
>> +return -EINVAL;
>> +}
>> +if (f2fs_test_compress_extension(F2FS_OPTION(sbi).noextensions,
>> +F2FS_OPTION(sbi).nocompress_ext_cnt,
>> +F2FS_CTX_INFO(ctx).extensions,
>> +F2FS_CTX_INFO(ctx).compress_ext_cnt)) {
>> +f2fs_err(sbi, "invalid compress or nocompress extension");
> 
> Ditto,

thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 7/7] f2fs: switch to the new mount api

2025-05-08 Thread Eric Sandeen via Linux-f2fs-devel
On 5/8/25 4:19 AM, Chao Yu wrote:
>> @@ -2645,21 +2603,11 @@ static int f2fs_remount(struct super_block *sb, int 
>> *flags, char *data)
>>  
>>  default_options(sbi, true);
>>  
>> -memset(&fc, 0, sizeof(fc));
>> -memset(&ctx, 0, sizeof(ctx));
>> -fc.fs_private = &ctx;
>> -fc.purpose = FS_CONTEXT_FOR_RECONFIGURE;
>> -
>> -/* parse mount options */
>> -err = parse_options(&fc, data);
>> -if (err)
>> -goto restore_opts;
> There is a retry flow during f2fs_fill_super(), I intenionally inject a
> fault into f2fs_fill_super() to trigger the retry flow, it turns out that
> mount option may be missed w/ below testcase:

I never did understand that retry logic (introduced in ed2e621a95d long
ago). What errors does it expect to be able to retry, with success?

Anyway ...

Can you show me (as a patch) exactly what you did to trigger the retry,
just so we are looking at the same thing?

> - mkfs.f2fs -f -O encrypt /dev/vdb
> - mount -o test_dummy_encryption /dev/vdb /mnt/f2fs/
> : return success
> - dmesg -c
> 
> [   83.619982] f2fs_fill_super, retry_cnt:1
> [   83.620914] F2FS-fs (vdb): Test dummy encryption mode enabled
> [   83.668380] f2fs_fill_super, retry_cnt:0
> [   83.671601] F2FS-fs (vdb): Mounted with checkpoint version = 7a8dfca5
> 
> - mount|grep f2fs
> /dev/vdb on /mnt/f2fs type f2fs 
> (rw,relatime,lazytime,background_gc=on,nogc_merge,
> discard,discard_unit=block,user_xattr,inline_xattr,acl,inline_data,inline_dentry,
> flush_merge,barrier,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,
> checkpoint_merge,fsync_mode=posix,memory=normal,errors=continue)
> 
> The reason may be it has cleared F2FS_CTX_INFO(ctx).dummy_enc_policy in
> f2fs_apply_test_dummy_encryption().
> 
> static void f2fs_apply_test_dummy_encryption(struct fs_context *fc,
>struct super_block *sb)
> {
>   struct f2fs_fs_context *ctx = fc->fs_private;
>   struct f2fs_sb_info *sbi = F2FS_SB(sb);
> 
>   if (!fscrypt_is_dummy_policy_set(&F2FS_CTX_INFO(ctx).dummy_enc_policy) 
> ||
>   /* if already set, it was already verified to be the same */
>   fscrypt_is_dummy_policy_set(&F2FS_OPTION(sbi).dummy_enc_policy))
>   return;
>   F2FS_OPTION(sbi).dummy_enc_policy = F2FS_CTX_INFO(ctx).dummy_enc_policy;
>   memset(&F2FS_CTX_INFO(ctx).dummy_enc_policy, 0,
>   sizeof(F2FS_CTX_INFO(ctx).dummy_enc_policy));
>   f2fs_warn(sbi, "Test dummy encryption mode enabled");
> }
> 
> Can we save old mount_info from sbi or ctx from fc, and try to recover it
> before we retry mount flow?

I'll have to take more time to understand this concern. But thanks for pointing
it out.

-Eric

> Thanks,



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-07 Thread Eric Sandeen via Linux-f2fs-devel
On 5/7/25 2:48 PM, Jaegeuk Kim wrote:
> On 05/07, Eric Sandeen wrote:
>> On 5/7/25 9:46 AM, Jaegeuk Kim wrote:
>>
>>> I meant:
>>>
>>> # mkfs/mkfs.f2fs -c /dev/v...@vdc.file /dev/vdb
>>> # mount /dev/vdb mnt
>>>
>>> It's supposed to be successful, since extent_cache is enabled by default.
>>
>> I'm sorry, clearly I was too sleepy last night. This fixes it for me.
>>
>> We have to test the mask to see if the option was explisitly set (either
>> extent_cache or noextent_cache) at mount time.
>>
>> If it was not specified at all, it will be set by the default f'n and
>> remain in the sbi, and it will pass this consistency check.
>>
>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>> index d89b9ede221e..e178796ce9a7 100644
>> --- a/fs/f2fs/super.c
>> +++ b/fs/f2fs/super.c
>> @@ -1412,7 +1414,8 @@ static int f2fs_check_opt_consistency(struct 
>> fs_context *fc,
>>  }
>>  
>>  if (f2fs_sb_has_device_alias(sbi) &&
>> -!ctx_test_opt(ctx, F2FS_MOUNT_READ_EXTENT_CACHE)) {
>> +(ctx->opt_mask & F2FS_MOUNT_READ_EXTENT_CACHE) &&
>> + !ctx_test_opt(ctx, F2FS_MOUNT_READ_EXTENT_CACHE)) {
>>  f2fs_err(sbi, "device aliasing requires extent cache");
>>  return -EINVAL;
>>  }
> 
> I think that will cover the user-given options only, but we'd better check the
> final options as well. Can we apply like this?

I'm sorry, I'm not sure I understand what situation this additional
changes will cover...

It looks like this adds the f2fs_sanity_check_options() to the remount
path to explicitly (re-)check a few things.

But as far as I can tell, at least for the extent cache, remount is handled
properly already (with the hunk above):

# mkfs/mkfs.f2fs -c /dev/v...@vdc.file /dev/vdb
# mount /dev/vdb mnt
# mount -o remount,noextent_cache mnt
mount: /root/mnt: mount point not mounted or bad option.
   dmesg(1) may have more information after failed mount system call.
# dmesg | tail -n 1
[60012.364941] F2FS-fs (vdb): device aliasing requires extent cache
#

I haven't tested with i.e. blkzoned devices though, is there a testcase
that fails for you?

Thanks,
-Eric

> ---
>  fs/f2fs/super.c | 50 -
>  1 file changed, 33 insertions(+), 17 deletions(-)
> 
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index d89b9ede221e..270a9bf9773d 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -1412,6 +1412,7 @@ static int f2fs_check_opt_consistency(struct fs_context 
> *fc,
>   }
>  
>   if (f2fs_sb_has_device_alias(sbi) &&
> + (ctx->opt_mask & F2FS_MOUNT_READ_EXTENT_CACHE) &&
>   !ctx_test_opt(ctx, F2FS_MOUNT_READ_EXTENT_CACHE)) {
>   f2fs_err(sbi, "device aliasing requires extent cache");
>   return -EINVAL;
> @@ -1657,6 +1658,29 @@ static void f2fs_apply_options(struct fs_context *fc, 
> struct super_block *sb)
>   f2fs_apply_quota_options(fc, sb);
>  }
>  
> +static int f2fs_sanity_check_options(struct f2fs_sb_info *sbi)
> +{
> + if (f2fs_sb_has_device_alias(sbi) &&
> + !test_opt(sbi, READ_EXTENT_CACHE)) {
> + f2fs_err(sbi, "device aliasing requires extent cache");
> + return -EINVAL;
> + }
> +#ifdef CONFIG_BLK_DEV_ZONED
> + if (f2fs_sb_has_blkzoned(sbi) &&
> + sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) {
> + f2fs_err(sbi,
> + "zoned: max open zones %u is too small, need at least 
> %u open zones",
> +  sbi->max_open_zones, 
> F2FS_OPTION(sbi).active_logs);
> + return -EINVAL;
> + }
> +#endif
> + if (f2fs_lfs_mode(sbi) && !IS_F2FS_IPU_DISABLE(sbi)) {
> + f2fs_warn(sbi, "LFS is not compatible with IPU");
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
>  static struct inode *f2fs_alloc_inode(struct super_block *sb)
>  {
>   struct f2fs_inode_info *fi;
> @@ -2616,21 +2640,15 @@ static int __f2fs_remount(struct fs_context *fc, 
> struct super_block *sb)
>   default_options(sbi, true);
>  
>   err = f2fs_check_opt_consistency(fc, sb);
> - if (err < 0)
> + if (err)
>   goto restore_opts;
>  
>   f2fs_apply_options(fc, sb);
>  
> -#ifdef CONFIG_BLK_DEV_ZONED
> - if (f2fs_sb_has_blkzoned(sbi) &&
> - sbi->max_open_zones &

Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-07 Thread Eric Sandeen via Linux-f2fs-devel
On 5/7/25 3:28 PM, Jaegeuk Kim wrote:
>> But as far as I can tell, at least for the extent cache, remount is handled
>> properly already (with the hunk above):
>>
>> # mkfs/mkfs.f2fs -c /dev/v...@vdc.file /dev/vdb
>> # mount /dev/vdb mnt
>> # mount -o remount,noextent_cache mnt
>> mount: /root/mnt: mount point not mounted or bad option.
>>dmesg(1) may have more information after failed mount system call.
>> # dmesg | tail -n 1
>> [60012.364941] F2FS-fs (vdb): device aliasing requires extent cache
>> #
>>
>> I haven't tested with i.e. blkzoned devices though, is there a testcase
>> that fails for you?
> I'm worrying about any missing case to check options enabled by 
> default_options.
> For example, in the case of device_aliasing, we rely on enabling extent_cache
> by default_options, which was not caught by f2fs_check_opt_consistency.
> 
> I was thinking that we'd need a post sanity check.

I see. If you want a "belt and suspenders" approach and it works for
you, no argument from me :)

-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 5/7] f2fs: separate the options parsing and options checking

2025-05-08 Thread Eric Sandeen via Linux-f2fs-devel
On 5/8/25 10:52 AM, Eric Sandeen wrote:
>>> +
>>> +   if (f2fs_test_compress_extension(F2FS_CTX_INFO(ctx).noextensions,
>>> +   F2FS_CTX_INFO(ctx).nocompress_ext_cnt,
>>> +   F2FS_CTX_INFO(ctx).extensions,
>>> +   F2FS_CTX_INFO(ctx).compress_ext_cnt)) {
>>> +   f2fs_err(sbi, "invalid compress or nocompress extension");
>> Can you please describe what is detailed confliction in the log? e.g. new
>> noext conflicts w/ new ext...

> Hmm, let me think about this. I had not noticed it was calling 
> f2fs_test_compress_extension 3 times, I wonder if there is a better option.
> I need to understand this approach better. Maybe Hongbo has thoughts.

(taking linux-fsdevel off cc: to reduce noise)

Looking at this some more, I don't think any information is lost with this
change. The messages are exactly the same as they were before, in the error
cases.

(I don't love the "check 3 times" logic, but I guess we have to check internal
ctx consistency, as well as ctx vs. sbi, and sbi vs. ctx).

I think that if you would like to see clearer error messages, that's outside
the scope of the mount API conversion.

(If you have an example of a kernel message difference under this mount API
conversion vs current upstream, I'd be happy to look in more detail.)

Thanks,
-Eric

>>> +   return -EINVAL;
>>> +   }
>>> +   if (f2fs_test_compress_extension(F2FS_CTX_INFO(ctx).noextensions,
>>> +   F2FS_CTX_INFO(ctx).nocompress_ext_cnt,
>>> +   F2FS_OPTION(sbi).extensions,
>>> +   F2FS_OPTION(sbi).compress_ext_cnt)) {
>>> +   f2fs_err(sbi, "invalid compress or nocompress extension");
>> Ditto,
>>
>>> +   return -EINVAL;
>>> +   }
>>> +   if (f2fs_test_compress_extension(F2FS_OPTION(sbi).noextensions,
>>> +   F2FS_OPTION(sbi).nocompress_ext_cnt,
>>> +   F2FS_CTX_INFO(ctx).extensions,
>>> +   F2FS_CTX_INFO(ctx).compress_ext_cnt)) {
>>> +   f2fs_err(sbi, "invalid compress or nocompress extension");
>> Ditto,



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 5/7] f2fs: separate the options parsing and options checking

2025-05-06 Thread Eric Sandeen via Linux-f2fs-devel
On 5/6/25 5:01 PM, Jaegeuk Kim wrote:



>> +static int f2fs_check_opt_consistency(struct fs_context *fc,
>> +  struct super_block *sb)
>> +{
>> +struct f2fs_fs_context *ctx = fc->fs_private;
>> +struct f2fs_sb_info *sbi = F2FS_SB(sb);
>> +int err;
>> +
>> +if (ctx_test_opt(ctx, F2FS_MOUNT_NORECOVERY) && !f2fs_readonly(sb))
>> +return -EINVAL;
>> +
>> +if (f2fs_hw_should_discard(sbi) && (ctx->opt_mask & F2FS_MOUNT_DISCARD)
>> +&& !ctx_test_opt(ctx, F2FS_MOUNT_DISCARD)) {
> Applied.
> 
>if (f2fs_hw_should_discard(sbi) &&
>(ctx->opt_mask & F2FS_MOUNT_DISCARD) &&
>!ctx_test_opt(ctx, F2FS_MOUNT_DISCARD)) {
> 

yes that's nicer

>> +f2fs_warn(sbi, "discard is required for zoned block devices");
>> +return -EINVAL;
>> +}
>> +
>> +if (f2fs_sb_has_device_alias(sbi)) {
> Shouldn't this be?
> 
>   if (f2fs_sb_has_device_alias(sbi) &&
>   !ctx_test_opt(ctx, F2FS_MOUNT_READ_EXTENT_CACHE)) {
> 

Whoops, I don't know how I missed that, or how my testing missed it, sorry.
And maybe it should be later in the function so it doesn't interrupt the=
discard cases.
 
>> +f2fs_err(sbi, "device aliasing requires extent cache");
>> +return -EINVAL;
>> +}
>> +
>> +if (!f2fs_hw_support_discard(sbi) && (ctx->opt_mask & 
>> F2FS_MOUNT_DISCARD)
>> +&& ctx_test_opt(ctx, F2FS_MOUNT_DISCARD)) {
>if (!f2fs_hw_support_discard(sbi) &&
>(ctx->opt_mask & F2FS_MOUNT_DISCARD) &&
>ctx_test_opt(ctx, F2FS_MOUNT_DISCARD)) {
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-06 Thread Eric Sandeen via Linux-f2fs-devel
On 5/6/25 11:02 AM, Jaegeuk Kim wrote:
> On 05/05, Eric Sandeen wrote:
>> Hi all - it would be nice to get some review or feedback on this;
>> seems that these patches tend to go stale fairly quickly as f2fs
>> evolves. :)
> 
> Thank you so much for the work! Let me queue this series into dev-test for
> tests. If I find any issue, let me ping to the thread. So, you don't need
> to worry about rebasing it. :)

Thank you for queuing it, and Hongbo for the original series. Please reach
out if you encounter any problems.

-Eric

> Thanks,
> 
>>
>> Thanks,
>> -Eric
>>



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-06 Thread Eric Sandeen via Linux-f2fs-devel
On 5/6/25 9:56 PM, Eric Sandeen wrote:
> On 5/6/25 8:23 PM, Jaegeuk Kim wrote:

...

>> What about:
>> # mount -o loop,noextent_cache f2fsfile.img mnt
>>
>> In this case, 1) ctx_clear_opt(), 2) set_opt() in default_options,
>> 3) clear_opt since mask is set?
> 
> Not sure what I'm missing, it seems to work properly here but I haven't
> pulled your (slightly) modified patches yet:
> 
> # mount -o loop,extent_cache f2fsfile.img mnt
> # mount | grep -wo extent_cache
> extent_cache
> # umount mnt
> 
> # mount -o loop,noextent_cache f2fsfile.img mnt
> # mount | grep -wo noextent_cache
> noextent_cache
> #
> 
> this looks right?
> 
> I'll check your tree tomorrow, though it doesn't sound like you made many
> changes.

Hmm, I checked tonight and I see the same (correct?) behavior in your tree.

>> And, device_aliasing check is still failing, since it does not understand
>> test_opt(). Probably it's the only case?

Again, in your tree (I had to use a git version of f2fs-tools to make device
aliasing work - maybe time for a release?) ;) 

# mkfs.ext4 /dev/vdc
# mkfs/mkfs.f2fs -c /dev/v...@vdc.file /dev/vdb
# mount -o noextent_cache /dev/vdb mnt
# dmesg | tail -n 1
[  581.924604] F2FS-fs (vdb): device aliasing requires extent cache
# mount -o extent_cache /dev/vdb mnt
# mount | grep -wo extent_cache
extent_cache
# 

Maybe you can show me exactly what's not working for you?

-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-06 Thread Eric Sandeen via Linux-f2fs-devel
On 5/6/25 7:35 PM, Jaegeuk Kim wrote:
> Hmm, I had to drop the series at the moment, since it seems needing more
> work to deal with default_options(), which breaks my device setup.
> For example, set_opt(sbi, READ_EXTENT_CACHE) in default_options is not 
> propagating
> to the below logics. In this case, do we need ctx_set_opt() if user doesn't 
> set?

Hm, can you describe the test or environment that fails for you?
(I'm afraid that I may not have all the right hardware to test everything,
so may have missed some cases)

However, from a quick test here, a loopback mount of an f2fs image file does
set extent_cache properly, so maybe I don't understand the problem:

# mount -o loop f2fsfile.img mnt
# mount | grep -o extent_cache
extent_cache
#

I'm happy to try to look into it though. Maybe you can put the patches
back on a temporary branch for me to pull and test?

Thanks,
- Eric




___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 0/7] f2fs: new mount API conversion

2025-05-06 Thread Eric Sandeen via Linux-f2fs-devel
On 5/6/25 8:23 PM, Jaegeuk Kim wrote:
> On 05/06, Eric Sandeen wrote:
>> On 5/6/25 7:35 PM, Jaegeuk Kim wrote:
>>> Hmm, I had to drop the series at the moment, since it seems needing more
>>> work to deal with default_options(), which breaks my device setup.
>>> For example, set_opt(sbi, READ_EXTENT_CACHE) in default_options is not 
>>> propagating
>>> to the below logics. In this case, do we need ctx_set_opt() if user doesn't 
>>> set?
>>
>> Hm, can you describe the test or environment that fails for you?
>> (I'm afraid that I may not have all the right hardware to test everything,
>> so may have missed some cases)
>>
>> However, from a quick test here, a loopback mount of an f2fs image file does
>> set extent_cache properly, so maybe I don't understand the problem:
>>
>> # mount -o loop f2fsfile.img mnt
>> # mount | grep -o extent_cache
>> extent_cache
>> #
>>
>> I'm happy to try to look into it though. Maybe you can put the patches
>> back on a temporary branch for me to pull and test?
> 
> Thank you! I pushed here the last version.
> 
> https://github.com/jaegeuk/f2fs/commits/mount/
> 
> What about:
> # mount -o loop,noextent_cache f2fsfile.img mnt
> 
> In this case, 1) ctx_clear_opt(), 2) set_opt() in default_options,
> 3) clear_opt since mask is set?

Not sure what I'm missing, it seems to work properly here but I haven't
pulled your (slightly) modified patches yet:

# mount -o loop,extent_cache f2fsfile.img mnt
# mount | grep -wo extent_cache
extent_cache
# umount mnt

# mount -o loop,noextent_cache f2fsfile.img mnt
# mount | grep -wo noextent_cache
noextent_cache
#

this looks right?

I'll check your tree tomorrow, though it doesn't sound like you made many
changes.

> And, device_aliasing check is still failing, since it does not understand
> test_opt(). Probably it's the only case?

I think you can blame me, not Hongbo on that one ;) - I will look into it.

-Eric

>>
>> Thanks,
>> - Eric
>>
> 



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 7/7] f2fs: switch to the new mount api

2025-05-12 Thread Eric Sandeen via Linux-f2fs-devel
On 5/11/25 10:43 PM, Chao Yu wrote:
> On 5/8/25 23:59, Eric Sandeen wrote:
>> On 5/8/25 4:19 AM, Chao Yu wrote:
>>>> @@ -2645,21 +2603,11 @@ static int f2fs_remount(struct
>>>> super_block *sb, int *flags, char *data)
>>>> 
>>>> default_options(sbi, true);
>>>> 
>>>> -  memset(&fc, 0, sizeof(fc)); -   memset(&ctx, 0, sizeof(ctx)); 
>>>> -  fc.fs_private = &ctx; - fc.purpose =
>>>> FS_CONTEXT_FOR_RECONFIGURE; - -/* parse mount options */ -
>>>> err = parse_options(&fc, data); -  if (err) -  goto
>>>> restore_opts;
>>> There is a retry flow during f2fs_fill_super(), I intenionally
>>> inject a fault into f2fs_fill_super() to trigger the retry flow,
>>> it turns out that mount option may be missed w/ below testcase:
>> 
>> I never did understand that retry logic (introduced in ed2e621a95d
>> long ago). What errors does it expect to be able to retry, with
>> success?
> 
> IIRC, it will retry mount if there is recovery failure due to
> inconsistent metadata.

Sure, I just wonder what would cause inconsistent metadata to become consistent
after 1 retry ...

>> 
>> Anyway ...
>> 
>> Can you show me (as a patch) exactly what you did to trigger the
>> retry, just so we are looking at the same thing?
> 
> You can try this?

Ok, thanks!
-Eric

> --- fs/f2fs/super.c | 6 ++ 1 file changed, 6 insertions(+)
> 
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index
> 0ee783224953..10f0e66059f8 100644 --- a/fs/f2fs/super.c +++ b/fs/
> f2fs/super.c @@ -5066,6 +5066,12 @@ static int
> f2fs_fill_super(struct super_block *sb, struct fs_context *fc) goto
> reset_checkpoint; }
> 
> + if (retry_cnt) { +  err = -EIO; +   skip_recovery = 
> true; + goto
> free_meta; +  } + /* recover fsynced data */ if (!test_opt(sbi,
> DISABLE_ROLL_FORWARD) && !test_opt(sbi, NORECOVERY)) {



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH V3 7/7] f2fs: switch to the new mount api

2025-05-14 Thread Eric Sandeen via Linux-f2fs-devel
On 5/14/25 10:30 AM, Jaegeuk Kim wrote:
> Hi, Hongbo,
> 
> It seems we're getting more issues in the patch set. May I ask for some
> help sending the new patch series having all the fixes that I made as well
> as addressing the concerns? You can get the patches from [1].
> 
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/log/?h=dev-test

Apologies for being a little absent, some urgent things came up internally
for me at work and I've had less time for this. I'm planning to get
back to it!

It's been a long thread, perhaps we could summarize the remaining questions and
concerns?

And I'm sorry for the errors that got through, I really thought my testing was
fairly exhaustive, but it appears that I missed several cases.

(To be fair, f2fs has far more mount options than any other filesystem, and
combining that with on-disk feature variants, it is a very big test matrix.)

Thanks,
-Eric



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel