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 <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
ChenXiaoSong 2026-06-08 14:01:25 +00:00 committed by Steve French
parent e48b687221
commit c91f4543dd
4 changed files with 53 additions and 1 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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__ */