[PATCH] btrfs: Accept and ignore compression level for lzo

Calvin Owens posted 1 patch 1 month, 1 week ago
fs/btrfs/super.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] btrfs: Accept and ignore compression level for lzo
Posted by Calvin Owens 1 month, 1 week ago
The compression level is meaningless for lzo, but before commit
3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
it was silently ignored if passed.

After that commit, passing a level with lzo fails to mount:

    BTRFS error: unrecognized compression value lzo:1

Restore the old behavior, in case any users were relying on it.

Fixes: 3f093ccb95f30 ("btrfs: harden parsing of compression mount options")
Signed-off-by: Calvin Owens <calvin@wbinvd.org>
---
 fs/btrfs/super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index a262b494a89f..7ee35038c7fb 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -299,7 +299,7 @@ static int btrfs_parse_compress(struct btrfs_fs_context *ctx,
 		btrfs_set_opt(ctx->mount_opt, COMPRESS);
 		btrfs_clear_opt(ctx->mount_opt, NODATACOW);
 		btrfs_clear_opt(ctx->mount_opt, NODATASUM);
-	} else if (btrfs_match_compress_type(string, "lzo", false)) {
+	} else if (btrfs_match_compress_type(string, "lzo", true)) {
 		ctx->compress_type = BTRFS_COMPRESS_LZO;
 		ctx->compress_level = 0;
 		btrfs_set_opt(ctx->mount_opt, COMPRESS);
-- 
2.47.2
Re: [PATCH] btrfs: Accept and ignore compression level for lzo
Posted by Qu Wenruo 1 month, 1 week ago

在 2025/8/22 17:15, Calvin Owens 写道:
> The compression level is meaningless for lzo, but before commit
> 3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
> it was silently ignored if passed.

Since LZO doesn't support compression level, why providing a level 
parameter in the first place?

I think it's time for those users to properly update their mount options.

> 
> After that commit, passing a level with lzo fails to mount:
> 
>      BTRFS error: unrecognized compression value lzo:1
> 
> Restore the old behavior, in case any users were relying on it.
> 
> Fixes: 3f093ccb95f30 ("btrfs: harden parsing of compression mount options")
> Signed-off-by: Calvin Owens <calvin@wbinvd.org>
> ---
>   fs/btrfs/super.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> index a262b494a89f..7ee35038c7fb 100644
> --- a/fs/btrfs/super.c
> +++ b/fs/btrfs/super.c
> @@ -299,7 +299,7 @@ static int btrfs_parse_compress(struct btrfs_fs_context *ctx,
>   		btrfs_set_opt(ctx->mount_opt, COMPRESS);
>   		btrfs_clear_opt(ctx->mount_opt, NODATACOW);
>   		btrfs_clear_opt(ctx->mount_opt, NODATASUM);
> -	} else if (btrfs_match_compress_type(string, "lzo", false)) {
> +	} else if (btrfs_match_compress_type(string, "lzo", true)) {
>   		ctx->compress_type = BTRFS_COMPRESS_LZO;
>   		ctx->compress_level = 0;
>   		btrfs_set_opt(ctx->mount_opt, COMPRESS);
Re: [PATCH] btrfs: Accept and ignore compression level for lzo
Posted by Calvin Owens 1 month, 1 week ago
On Friday 08/22 at 17:57 +0930, Qu Wenruo wrote:
> 在 2025/8/22 17:15, Calvin Owens 写道:
> > The compression level is meaningless for lzo, but before commit
> > 3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
> > it was silently ignored if passed.
> 
> Since LZO doesn't support compression level, why providing a level parameter
> in the first place?

Interpreting "no level" as "level is always one" doesn't seem that
unreasonable to me, especially since it has worked forever.

> I think it's time for those users to properly update their mount options.

It's a user visable regression, and fixing it has zero possible
downside. I think you should take my patch :)

Thanks,
Calvin

> > 
> > After that commit, passing a level with lzo fails to mount:
> > 
> >      BTRFS error: unrecognized compression value lzo:1
> > 
> > Restore the old behavior, in case any users were relying on it.
> > 
> > Fixes: 3f093ccb95f30 ("btrfs: harden parsing of compression mount options")
> > Signed-off-by: Calvin Owens <calvin@wbinvd.org>
> > ---
> >   fs/btrfs/super.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> > index a262b494a89f..7ee35038c7fb 100644
> > --- a/fs/btrfs/super.c
> > +++ b/fs/btrfs/super.c
> > @@ -299,7 +299,7 @@ static int btrfs_parse_compress(struct btrfs_fs_context *ctx,
> >   		btrfs_set_opt(ctx->mount_opt, COMPRESS);
> >   		btrfs_clear_opt(ctx->mount_opt, NODATACOW);
> >   		btrfs_clear_opt(ctx->mount_opt, NODATASUM);
> > -	} else if (btrfs_match_compress_type(string, "lzo", false)) {
> > +	} else if (btrfs_match_compress_type(string, "lzo", true)) {
> >   		ctx->compress_type = BTRFS_COMPRESS_LZO;
> >   		ctx->compress_level = 0;
> >   		btrfs_set_opt(ctx->mount_opt, COMPRESS);
> 
Re: [PATCH] btrfs: Accept and ignore compression level for lzo
Posted by David Sterba 1 month, 1 week ago
On Fri, Aug 22, 2025 at 02:28:29AM -0700, Calvin Owens wrote:
> On Friday 08/22 at 17:57 +0930, Qu Wenruo wrote:
> > 在 2025/8/22 17:15, Calvin Owens 写道:
> > > The compression level is meaningless for lzo, but before commit
> > > 3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
> > > it was silently ignored if passed.
> > 
> > Since LZO doesn't support compression level, why providing a level parameter
> > in the first place?
> 
> Interpreting "no level" as "level is always one" doesn't seem that
> unreasonable to me, especially since it has worked forever.

As it currently works, no level means use the default, which is defined
for all compression. For LZO it's implicit and 1.

> > I think it's time for those users to properly update their mount options.
> 
> It's a user visable regression, and fixing it has zero possible
> downside. I think you should take my patch :)

I tend to agree this is a usability regression, even if LZO is a bit odd
with levels, accepting the allowed values should work.

The mount options and level combinations that should work:

- compress=NAME   - use default level for NAME
- compress=NAME:0 - use default, while accepting the level setting
- compress=NAME:N - if N is in the allowed range for NAME then take it

The syntax is consistent for all three compressions.
Re: [PATCH] btrfs: Accept and ignore compression level for lzo
Posted by Calvin Owens 1 month, 1 week ago
On Friday 08/22 at 20:45 +0200, David Sterba wrote:
> On Fri, Aug 22, 2025 at 02:28:29AM -0700, Calvin Owens wrote:
> > On Friday 08/22 at 17:57 +0930, Qu Wenruo wrote:
> > > 在 2025/8/22 17:15, Calvin Owens 写道:
> > > > The compression level is meaningless for lzo, but before commit
> > > > 3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
> > > > it was silently ignored if passed.
> > > 
> > > Since LZO doesn't support compression level, why providing a level parameter
> > > in the first place?
> > 
> > Interpreting "no level" as "level is always one" doesn't seem that
> > unreasonable to me, especially since it has worked forever.
> 
> As it currently works, no level means use the default, which is defined
> for all compression. For LZO it's implicit and 1.
> 
> > > I think it's time for those users to properly update their mount options.
> > 
> > It's a user visable regression, and fixing it has zero possible
> > downside. I think you should take my patch :)
> 
> I tend to agree this is a usability regression, even if LZO is a bit odd
> with levels, accepting the allowed values should work.
> 
> The mount options and level combinations that should work:
> 
> - compress=NAME   - use default level for NAME
> - compress=NAME:0 - use default, while accepting the level setting
> - compress=NAME:N - if N is in the allowed range for NAME then take it
> 
> The syntax is consistent for all three compressions.

Thanks David.

Maybe the below is a little more palatable? Letting the single level be
a detail so the branches in btrfs_parse_compress() all match?

But, the compression level ends up being printk'd as '1', where it has
always been '0' in the past (and still is in 6.17-rc):

    - BTRFS info (device vda state M): use lzo compression, level 0
    + BTRFS info (device vda state M): use lzo compression, level 1

With my v1 it's still always printed as zero, if that's preferable.

-----8<-----
From: Calvin Owens <calvin@wbinvd.org>
Subject: [PATCH v2] btrfs: Accept and ignore compression level for lzo

The compression level is meaningless for lzo, but before commit
3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
it was silently ignored if passed.

After that commit, passing a level with lzo fails to mount:

    BTRFS error: unrecognized compression value lzo:1

Restore the old behavior, in case any users were relying on it.

Fixes: 3f093ccb95f30 ("btrfs: harden parsing of compression mount options")
Signed-off-by: Calvin Owens <calvin@wbinvd.org>
---
 fs/btrfs/super.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index a262b494a89f..bbcaac7022b0 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -299,9 +299,10 @@ static int btrfs_parse_compress(struct btrfs_fs_context *ctx,
 		btrfs_set_opt(ctx->mount_opt, COMPRESS);
 		btrfs_clear_opt(ctx->mount_opt, NODATACOW);
 		btrfs_clear_opt(ctx->mount_opt, NODATASUM);
-	} else if (btrfs_match_compress_type(string, "lzo", false)) {
+	} else if (btrfs_match_compress_type(string, "lzo", true)) {
 		ctx->compress_type = BTRFS_COMPRESS_LZO;
-		ctx->compress_level = 0;
+		ctx->compress_level = btrfs_compress_str2level(BTRFS_COMPRESS_LZO,
+							       string + 4);
 		btrfs_set_opt(ctx->mount_opt, COMPRESS);
 		btrfs_clear_opt(ctx->mount_opt, NODATACOW);
 		btrfs_clear_opt(ctx->mount_opt, NODATASUM);
-- 
2.47.2

Re: [PATCH] btrfs: Accept and ignore compression level for lzo
Posted by Qu Wenruo 1 month, 1 week ago

在 2025/8/22 18:58, Calvin Owens 写道:
> On Friday 08/22 at 17:57 +0930, Qu Wenruo wrote:
>> 在 2025/8/22 17:15, Calvin Owens 写道:
>>> The compression level is meaningless for lzo, but before commit
>>> 3f093ccb95f30 ("btrfs: harden parsing of compression mount options"),
>>> it was silently ignored if passed.
>>
>> Since LZO doesn't support compression level, why providing a level parameter
>> in the first place?
> 
> Interpreting "no level" as "level is always one" doesn't seem that
> unreasonable to me, especially since it has worked forever.

No means no, period.

> 
>> I think it's time for those users to properly update their mount options.
> 
> It's a user visable regression, and fixing it has zero possible
> downside. I think you should take my patch :)

I do not want to encourage such usage.

Sanity overrides "regression". If it shouldn't work in the first place, 
it's not a regression.

> 
> Thanks,
> Calvin
> 
>>>
>>> After that commit, passing a level with lzo fails to mount:
>>>
>>>       BTRFS error: unrecognized compression value lzo:1
>>>
>>> Restore the old behavior, in case any users were relying on it.
>>>
>>> Fixes: 3f093ccb95f30 ("btrfs: harden parsing of compression mount options")
>>> Signed-off-by: Calvin Owens <calvin@wbinvd.org>
>>> ---
>>>    fs/btrfs/super.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
>>> index a262b494a89f..7ee35038c7fb 100644
>>> --- a/fs/btrfs/super.c
>>> +++ b/fs/btrfs/super.c
>>> @@ -299,7 +299,7 @@ static int btrfs_parse_compress(struct btrfs_fs_context *ctx,
>>>    		btrfs_set_opt(ctx->mount_opt, COMPRESS);
>>>    		btrfs_clear_opt(ctx->mount_opt, NODATACOW);
>>>    		btrfs_clear_opt(ctx->mount_opt, NODATASUM);
>>> -	} else if (btrfs_match_compress_type(string, "lzo", false)) {
>>> +	} else if (btrfs_match_compress_type(string, "lzo", true)) {
>>>    		ctx->compress_type = BTRFS_COMPRESS_LZO;
>>>    		ctx->compress_level = 0;
>>>    		btrfs_set_opt(ctx->mount_opt, COMPRESS);
>>
>