From: ChenXiaoSong Date: Mon, 8 Jun 2026 14:01:25 +0000 (+0000) Subject: smb/server: implement FSCTL_GET_COMPRESSION ioctl handler X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c91f4543ddecc49c96c175a90f51c991957f72e3;p=thirdparty%2Fkernel%2Flinux.git smb/server: implement FSCTL_GET_COMPRESSION ioctl handler Example: 1. server: chattr +c /export/file 2. client: smbinfo getcompression /mnt/file Compression: 2 (LZNT1) Signed-off-by: ChenXiaoSong Acked-by: Namjae Jeon Signed-off-by: Steve French --- diff --git a/fs/smb/common/smbfsctl.h b/fs/smb/common/smbfsctl.h index 74e78bcb4618d..9debdd709d1c1 100644 --- a/fs/smb/common/smbfsctl.h +++ b/fs/smb/common/smbfsctl.h @@ -61,7 +61,7 @@ #define FSCTL_LOCK_VOLUME 0x00090018 #define FSCTL_UNLOCK_VOLUME 0x0009001C #define FSCTL_IS_PATHNAME_VALID 0x0009002C /* BB add struct */ -#define FSCTL_GET_COMPRESSION 0x0009003C /* BB add struct */ +#define FSCTL_GET_COMPRESSION 0x0009003C #define FSCTL_SET_COMPRESSION 0x0009C040 /* BB add struct */ #define FSCTL_QUERY_FAT_BPB 0x00090058 /* BB add struct */ /* Verify the next FSCTL number, we had it as 0x00090090 before */ diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 4b8e1a4f9e6bf..975ca2ed84df6 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -8354,6 +8354,34 @@ int smb2_ioctl(struct ksmbd_work *work) ret = -EOPNOTSUPP; rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; goto out2; + case FSCTL_GET_COMPRESSION: { + struct compress_ioctl *cmpr_rsp; + struct ksmbd_file *fp; + u16 fmt; + + if (out_buf_len < sizeof(struct compress_ioctl)) { + ret = -EINVAL; + goto out; + } + + fp = ksmbd_lookup_fd_fast(work, id); + if (!fp) { + ret = -ENOENT; + goto out; + } + + ret = ksmbd_vfs_get_compression(fp, &fmt); + ksmbd_fd_put(work, fp); + if (ret < 0) + goto out; + + cmpr_rsp = (struct compress_ioctl *)&rsp->Buffer[0]; + cmpr_rsp->CompressionState = cpu_to_le16(fmt); + nbytes = sizeof(struct compress_ioctl); + rsp->PersistentFileId = req->PersistentFileId; + rsp->VolatileFileId = req->VolatileFileId; + break; + } case FSCTL_CREATE_OR_GET_OBJECT_ID: { struct file_object_buf_type1_ioctl_rsp *obj_buf; diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index b2403db135584..82cfd0b2a4cb7 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -1899,3 +1899,26 @@ void ksmbd_vfs_update_compressed_fattr(struct dentry *dentry, __le32 *fattr) else *fattr &= ~FILE_ATTRIBUTE_COMPRESSED_LE; } + +int ksmbd_vfs_get_compression(struct ksmbd_file *fp, u16 *fmt) +{ + struct file_kattr fa = { .flags_valid = true }; + int rc; + + rc = vfs_fileattr_get(fp->filp->f_path.dentry, &fa); + if (rc == -ENOIOCTLCMD) { + *fmt = COMPRESSION_FORMAT_NONE; + rc = 0; + goto out; + } + if (rc) + goto out; + + if (fa.flags & FS_COMPR_FL) + *fmt = COMPRESSION_FORMAT_LZNT1; + else + *fmt = COMPRESSION_FORMAT_NONE; + +out: + return rc; +} diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h index ac6dda173b752..f6121207dbda4 100644 --- a/fs/smb/server/vfs.h +++ b/fs/smb/server/vfs.h @@ -169,4 +169,5 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap, const struct path *path, struct inode *parent_inode); void ksmbd_vfs_update_compressed_fattr(struct dentry *dentry, __le32 *fattr); +int ksmbd_vfs_get_compression(struct ksmbd_file *fp, u16 *fmt); #endif /* __KSMBD_VFS_H__ */