]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
smb/client: allow FS_IOC_SETFLAGS to clear compression
authorHuiwen He <hehuiwen@kylinos.cn>
Mon, 8 Jun 2026 15:57:31 +0000 (23:57 +0800)
committerSteve French <stfrench@microsoft.com>
Sun, 14 Jun 2026 20:12:23 +0000 (15:12 -0500)
commit3ecad5de621ef538cbd63ae7075fddcc426dcd74
tree6b5f4f533cfb352543d82f25e37deb62867bda4d
parent5693347de107a26f68d1f43b25ff2e348c7229a9
smb/client: allow FS_IOC_SETFLAGS to clear compression

The CIFS FS_IOC_SETFLAGS path can set FS_COMPR_FL now, but it cannot
clear it again. This can be reproduced on a share backed by a filesystem
that supports compression, for example btrfs exported by Samba:

[compress_share]
vfs objects = btrfs

$ touch test.bin
$ chattr +c test.bin
$ lsattr test.bin
$ chattr -c test.bin

The final chattr -c fails with EOPNOTSUPP, and leaves the remote object
with the compressed attribute still set, because the client always sends
FSCTL_SET_COMPRESSION with COMPRESSION_FORMAT_DEFAULT. That is correct
for setting FS_COMPR_FL, but clearing FS_COMPR_FL requires sending
COMPRESSION_FORMAT_NONE.

Fix this by passing the requested compression state through the
set_compression operation.  The SMB1 and SMB2 helpers no longer hard-code
COMPRESSION_FORMAT_DEFAULT.

When FS_COMPR_FL is set, send COMPRESSION_FORMAT_DEFAULT.  When it is
cleared, send COMPRESSION_FORMAT_NONE.  If the server accepts the request,
update the cached FILE_ATTRIBUTE_COMPRESSED bit under i_lock so
FS_IOC_GETFLAGS reports the new state.

Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifsglob.h
fs/smb/client/cifssmb.c
fs/smb/client/ioctl.c
fs/smb/client/smb1ops.c
fs/smb/client/smb1proto.h
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c
fs/smb/client/smb2proto.h