mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
smb/server: implement FSCTL_SET_COMPRESSION ioctl handler
Example:
1. client: smbinfo setcompression no /mnt/file
2. client: smbinfo getcompression /mnt/file
Compression: 0 (NONE)
3. client: smbinfo setcompression lznt1 /mnt/file
4. client: smbinfo getcompression /mnt/file
Compression: 2 (LZNT1)
5. client: smbinfo setcompression default /mnt/file
6. 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:
parent
c91f4543dd
commit
7eeb7b6772
|
|
@ -62,7 +62,7 @@
|
|||
#define FSCTL_UNLOCK_VOLUME 0x0009001C
|
||||
#define FSCTL_IS_PATHNAME_VALID 0x0009002C /* BB add struct */
|
||||
#define FSCTL_GET_COMPRESSION 0x0009003C
|
||||
#define FSCTL_SET_COMPRESSION 0x0009C040 /* BB add struct */
|
||||
#define FSCTL_SET_COMPRESSION 0x0009C040
|
||||
#define FSCTL_QUERY_FAT_BPB 0x00090058 /* BB add struct */
|
||||
/* Verify the next FSCTL number, we had it as 0x00090090 before */
|
||||
#define FSCTL_FILESYSTEM_GET_STATS 0x00090060 /* BB add struct */
|
||||
|
|
|
|||
|
|
@ -8382,6 +8382,34 @@ int smb2_ioctl(struct ksmbd_work *work)
|
|||
rsp->VolatileFileId = req->VolatileFileId;
|
||||
break;
|
||||
}
|
||||
case FSCTL_SET_COMPRESSION: {
|
||||
struct compress_ioctl *cmpr_req;
|
||||
struct ksmbd_file *fp;
|
||||
|
||||
if (in_buf_len < sizeof(struct compress_ioctl)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
|
||||
ksmbd_debug(SMB, "User does not have write permission\n");
|
||||
ret = -EACCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmpr_req = (struct compress_ioctl *)buffer;
|
||||
fp = ksmbd_lookup_fd_fast(work, id);
|
||||
if (!fp) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ksmbd_vfs_set_compression(work, fp, le16_to_cpu(cmpr_req->CompressionState));
|
||||
ksmbd_fd_put(work, fp);
|
||||
if (ret)
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
case FSCTL_CREATE_OR_GET_OBJECT_ID:
|
||||
{
|
||||
struct file_object_buf_type1_ioctl_rsp *obj_buf;
|
||||
|
|
|
|||
|
|
@ -1922,3 +1922,73 @@ int ksmbd_vfs_get_compression(struct ksmbd_file *fp, u16 *fmt)
|
|||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ksmbd_vfs_set_compression(struct ksmbd_work *work, struct ksmbd_file *fp, u16 fmt)
|
||||
{
|
||||
struct file_kattr fa;
|
||||
struct dentry *dentry = fp->filp->f_path.dentry;
|
||||
struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
|
||||
u32 flags;
|
||||
__le32 old_fattr;
|
||||
int rc;
|
||||
|
||||
if (!(fp->daccess & FILE_WRITE_DATA_LE)) {
|
||||
rc = -EACCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = vfs_fileattr_get(dentry, &fa);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
flags = fa.flags;
|
||||
if (fmt == COMPRESSION_FORMAT_NONE) {
|
||||
flags &= ~FS_COMPR_FL;
|
||||
} else if (fmt == COMPRESSION_FORMAT_DEFAULT ||
|
||||
fmt == COMPRESSION_FORMAT_LZNT1) {
|
||||
flags |= FS_COMPR_FL;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (flags != fa.flags) {
|
||||
fileattr_fill_flags(&fa, flags);
|
||||
rc = mnt_want_write_file(fp->filp);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = vfs_fileattr_set(idmap, dentry, &fa);
|
||||
mnt_drop_write_file(fp->filp);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_fattr = fp->f_ci->m_fattr;
|
||||
if (fmt == COMPRESSION_FORMAT_NONE)
|
||||
fp->f_ci->m_fattr &= ~FILE_ATTRIBUTE_COMPRESSED_LE;
|
||||
else
|
||||
fp->f_ci->m_fattr |= FILE_ATTRIBUTE_COMPRESSED_LE;
|
||||
|
||||
if (fp->f_ci->m_fattr != old_fattr &&
|
||||
test_share_config_flag(work->tcon->share_conf,
|
||||
KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
|
||||
struct xattr_dos_attrib da;
|
||||
|
||||
rc = ksmbd_vfs_get_dos_attrib_xattr(idmap, dentry, &da);
|
||||
if (rc <= 0) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
da.attr = le32_to_cpu(fp->f_ci->m_fattr);
|
||||
rc = ksmbd_vfs_set_dos_attrib_xattr(idmap,
|
||||
&fp->filp->f_path,
|
||||
&da, true);
|
||||
if (rc)
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,4 +170,5 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
|||
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);
|
||||
int ksmbd_vfs_set_compression(struct ksmbd_work *work, struct ksmbd_file *fp, u16 fmt);
|
||||
#endif /* __KSMBD_VFS_H__ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user