]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smb/server: implement FSCTL_GET_COMPRESSION ioctl handler
authorChenXiaoSong <chenxiaosong@kylinos.cn>
Mon, 8 Jun 2026 14:01:25 +0000 (14:01 +0000)
committerSteve French <stfrench@microsoft.com>
Tue, 16 Jun 2026 23:57:21 +0000 (18:57 -0500)
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>
fs/smb/common/smbfsctl.h
fs/smb/server/smb2pdu.c
fs/smb/server/vfs.c
fs/smb/server/vfs.h

index 74e78bcb4618de90fb2dbce2ea641958875fefd3..9debdd709d1c139feabbb1c41430c350a50e74b9 100644 (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 */
index 4b8e1a4f9e6bfc093f2e1f452b8529a764b30832..975ca2ed84df6a7e0d69a2ea38c92a39f60b3a6f 100644 (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;
index b2403db1355847303ec23da783659d2ca8d73e66..82cfd0b2a4cb70f29bf09ca32e13e017dcfbd1da 100644 (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;
+}
index ac6dda173b752f365984b4211f106f703ee67226..f6121207dbda431f9b1945c46292d9a7b23304a8 100644 (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__ */