diff --git a/fs/smb/common/smbfsctl.h b/fs/smb/common/smbfsctl.h index 74e78bcb4618..9debdd709d1c 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 4b8e1a4f9e6b..975ca2ed84df 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 b2403db13558..82cfd0b2a4cb 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 ac6dda173b75..f6121207dbda 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__ */