diff options
-rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
-rw-r--r-- | fs/cifs/ioctl.c | 55 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 11 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 27 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 9 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 2 |
6 files changed, 87 insertions, 19 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 52b6f6c26bfc..06e8947fc370 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -278,6 +278,8 @@ struct smb_version_operations { | |||
278 | /* set attributes */ | 278 | /* set attributes */ |
279 | int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *, | 279 | int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *, |
280 | const unsigned int); | 280 | const unsigned int); |
281 | int (*set_compression)(const unsigned int, struct cifs_tcon *, | ||
282 | struct cifsFileInfo *); | ||
281 | /* check if we can send an echo or nor */ | 283 | /* check if we can send an echo or nor */ |
282 | bool (*can_echo)(struct TCP_Server_Info *); | 284 | bool (*can_echo)(struct TCP_Server_Info *); |
283 | /* send echo request */ | 285 | /* send echo request */ |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 3e0845585853..029867078aff 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * vfs operations that deal with io control | 4 | * vfs operations that deal with io control |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2005,2007 | 6 | * Copyright (C) International Business Machines Corp., 2005,2013 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * | 8 | * |
9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
@@ -34,13 +34,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
34 | int rc = -ENOTTY; /* strange error - but the precedent */ | 34 | int rc = -ENOTTY; /* strange error - but the precedent */ |
35 | unsigned int xid; | 35 | unsigned int xid; |
36 | struct cifs_sb_info *cifs_sb; | 36 | struct cifs_sb_info *cifs_sb; |
37 | #ifdef CONFIG_CIFS_POSIX | ||
38 | struct cifsFileInfo *pSMBFile = filep->private_data; | 37 | struct cifsFileInfo *pSMBFile = filep->private_data; |
39 | struct cifs_tcon *tcon; | 38 | struct cifs_tcon *tcon; |
40 | __u64 ExtAttrBits = 0; | 39 | __u64 ExtAttrBits = 0; |
41 | __u64 ExtAttrMask = 0; | 40 | __u64 ExtAttrMask = 0; |
42 | __u64 caps; | 41 | __u64 caps; |
43 | #endif /* CONFIG_CIFS_POSIX */ | ||
44 | 42 | ||
45 | xid = get_xid(); | 43 | xid = get_xid(); |
46 | 44 | ||
@@ -49,12 +47,12 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
49 | cifs_sb = CIFS_SB(inode->i_sb); | 47 | cifs_sb = CIFS_SB(inode->i_sb); |
50 | 48 | ||
51 | switch (command) { | 49 | switch (command) { |
52 | #ifdef CONFIG_CIFS_POSIX | ||
53 | case FS_IOC_GETFLAGS: | 50 | case FS_IOC_GETFLAGS: |
54 | if (pSMBFile == NULL) | 51 | if (pSMBFile == NULL) |
55 | break; | 52 | break; |
56 | tcon = tlink_tcon(pSMBFile->tlink); | 53 | tcon = tlink_tcon(pSMBFile->tlink); |
57 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | 54 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); |
55 | #ifdef CONFIG_CIFS_POSIX | ||
58 | if (CIFS_UNIX_EXTATTR_CAP & caps) { | 56 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
59 | rc = CIFSGetExtAttr(xid, tcon, | 57 | rc = CIFSGetExtAttr(xid, tcon, |
60 | pSMBFile->fid.netfid, | 58 | pSMBFile->fid.netfid, |
@@ -63,29 +61,50 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
63 | rc = put_user(ExtAttrBits & | 61 | rc = put_user(ExtAttrBits & |
64 | FS_FL_USER_VISIBLE, | 62 | FS_FL_USER_VISIBLE, |
65 | (int __user *)arg); | 63 | (int __user *)arg); |
64 | if (rc != EOPNOTSUPP) | ||
65 | break; | ||
66 | } | ||
67 | #endif /* CONFIG_CIFS_POSIX */ | ||
68 | rc = 0; | ||
69 | if (CIFS_I(inode)->cifsAttrs & ATTR_COMPRESSED) { | ||
70 | /* add in the compressed bit */ | ||
71 | ExtAttrBits = FS_COMPR_FL; | ||
72 | rc = put_user(ExtAttrBits & FS_FL_USER_VISIBLE, | ||
73 | (int __user *)arg); | ||
66 | } | 74 | } |
67 | break; | 75 | break; |
68 | |||
69 | case FS_IOC_SETFLAGS: | 76 | case FS_IOC_SETFLAGS: |
70 | if (pSMBFile == NULL) | 77 | if (pSMBFile == NULL) |
71 | break; | 78 | break; |
72 | tcon = tlink_tcon(pSMBFile->tlink); | 79 | tcon = tlink_tcon(pSMBFile->tlink); |
73 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | 80 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); |
74 | if (CIFS_UNIX_EXTATTR_CAP & caps) { | 81 | |
75 | if (get_user(ExtAttrBits, (int __user *)arg)) { | 82 | if (get_user(ExtAttrBits, (int __user *)arg)) { |
76 | rc = -EFAULT; | 83 | rc = -EFAULT; |
77 | break; | 84 | break; |
78 | } | 85 | } |
79 | /* | 86 | |
80 | * rc = CIFSGetExtAttr(xid, tcon, | 87 | /* |
81 | * pSMBFile->fid.netfid, | 88 | * if (CIFS_UNIX_EXTATTR_CAP & caps) |
82 | * extAttrBits, | 89 | * rc = CIFSSetExtAttr(xid, tcon, |
83 | * &ExtAttrMask); | 90 | * pSMBFile->fid.netfid, |
84 | */ | 91 | * extAttrBits, |
92 | * &ExtAttrMask); | ||
93 | * if (rc != EOPNOTSUPP) | ||
94 | * break; | ||
95 | */ | ||
96 | |||
97 | /* Currently only flag we can set is compressed flag */ | ||
98 | if ((ExtAttrBits & FS_COMPR_FL) == 0) | ||
99 | break; | ||
100 | |||
101 | /* Try to set compress flag */ | ||
102 | if (tcon->ses->server->ops->set_compression) { | ||
103 | rc = tcon->ses->server->ops->set_compression( | ||
104 | xid, tcon, pSMBFile); | ||
105 | cifs_dbg(FYI, "set compress flag rc %d\n", rc); | ||
85 | } | 106 | } |
86 | cifs_dbg(FYI, "set flags not implemented yet\n"); | ||
87 | break; | 107 | break; |
88 | #endif /* CONFIG_CIFS_POSIX */ | ||
89 | default: | 108 | default: |
90 | cifs_dbg(FYI, "unsupported ioctl\n"); | 109 | cifs_dbg(FYI, "unsupported ioctl\n"); |
91 | break; | 110 | break; |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 861b33214144..b96bacce955a 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -446,6 +446,14 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, | |||
446 | } | 446 | } |
447 | 447 | ||
448 | static int | 448 | static int |
449 | smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | ||
450 | struct cifsFileInfo *cfile) | ||
451 | { | ||
452 | return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid, | ||
453 | cfile->fid.volatile_fid); | ||
454 | } | ||
455 | |||
456 | static int | ||
449 | smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, | 457 | smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, |
450 | const char *path, struct cifs_sb_info *cifs_sb, | 458 | const char *path, struct cifs_sb_info *cifs_sb, |
451 | struct cifs_fid *fid, __u16 search_flags, | 459 | struct cifs_fid *fid, __u16 search_flags, |
@@ -874,6 +882,7 @@ struct smb_version_operations smb20_operations = { | |||
874 | .set_path_size = smb2_set_path_size, | 882 | .set_path_size = smb2_set_path_size, |
875 | .set_file_size = smb2_set_file_size, | 883 | .set_file_size = smb2_set_file_size, |
876 | .set_file_info = smb2_set_file_info, | 884 | .set_file_info = smb2_set_file_info, |
885 | .set_compression = smb2_set_compression, | ||
877 | .mkdir = smb2_mkdir, | 886 | .mkdir = smb2_mkdir, |
878 | .mkdir_setinfo = smb2_mkdir_setinfo, | 887 | .mkdir_setinfo = smb2_mkdir_setinfo, |
879 | .rmdir = smb2_rmdir, | 888 | .rmdir = smb2_rmdir, |
@@ -945,6 +954,7 @@ struct smb_version_operations smb21_operations = { | |||
945 | .set_path_size = smb2_set_path_size, | 954 | .set_path_size = smb2_set_path_size, |
946 | .set_file_size = smb2_set_file_size, | 955 | .set_file_size = smb2_set_file_size, |
947 | .set_file_info = smb2_set_file_info, | 956 | .set_file_info = smb2_set_file_info, |
957 | .set_compression = smb2_set_compression, | ||
948 | .mkdir = smb2_mkdir, | 958 | .mkdir = smb2_mkdir, |
949 | .mkdir_setinfo = smb2_mkdir_setinfo, | 959 | .mkdir_setinfo = smb2_mkdir_setinfo, |
950 | .rmdir = smb2_rmdir, | 960 | .rmdir = smb2_rmdir, |
@@ -1017,6 +1027,7 @@ struct smb_version_operations smb30_operations = { | |||
1017 | .set_path_size = smb2_set_path_size, | 1027 | .set_path_size = smb2_set_path_size, |
1018 | .set_file_size = smb2_set_file_size, | 1028 | .set_file_size = smb2_set_file_size, |
1019 | .set_file_info = smb2_set_file_info, | 1029 | .set_file_info = smb2_set_file_info, |
1030 | .set_compression = smb2_set_compression, | ||
1020 | .mkdir = smb2_mkdir, | 1031 | .mkdir = smb2_mkdir, |
1021 | .mkdir_setinfo = smb2_mkdir_setinfo, | 1032 | .mkdir_setinfo = smb2_mkdir_setinfo, |
1022 | .rmdir = smb2_rmdir, | 1033 | .rmdir = smb2_rmdir, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 6e1868611233..bbafa12e83b2 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1247,6 +1247,33 @@ ioctl_exit: | |||
1247 | return rc; | 1247 | return rc; |
1248 | } | 1248 | } |
1249 | 1249 | ||
1250 | /* | ||
1251 | * Individual callers to ioctl worker function follow | ||
1252 | */ | ||
1253 | |||
1254 | int | ||
1255 | SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | ||
1256 | u64 persistent_fid, u64 volatile_fid) | ||
1257 | { | ||
1258 | int rc; | ||
1259 | char *res_key = NULL; | ||
1260 | struct compress_ioctl fsctl_input; | ||
1261 | char *ret_data = NULL; | ||
1262 | |||
1263 | fsctl_input.CompressionState = | ||
1264 | __constant_cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); | ||
1265 | |||
1266 | rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid, | ||
1267 | FSCTL_SET_COMPRESSION, true /* is_fsctl */, | ||
1268 | (char *)&fsctl_input /* data input */, | ||
1269 | 2 /* in data len */, &ret_data /* out data */, NULL); | ||
1270 | |||
1271 | cifs_dbg(FYI, "set compression rc %d\n", rc); | ||
1272 | kfree(res_key); | ||
1273 | |||
1274 | return rc; | ||
1275 | } | ||
1276 | |||
1250 | int | 1277 | int |
1251 | SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, | 1278 | SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, |
1252 | u64 persistent_fid, u64 volatile_fid) | 1279 | u64 persistent_fid, u64 volatile_fid) |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index b83d0118a757..c7c3c8294d1a 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -569,6 +569,13 @@ struct network_interface_info_ioctl_rsp { | |||
569 | 569 | ||
570 | #define NO_FILE_ID 0xFFFFFFFFFFFFFFFFULL /* general ioctls to srv not to file */ | 570 | #define NO_FILE_ID 0xFFFFFFFFFFFFFFFFULL /* general ioctls to srv not to file */ |
571 | 571 | ||
572 | struct compress_ioctl { | ||
573 | __le16 CompressionState; | ||
574 | } __packed; | ||
575 | |||
576 | #define COMPRESSION_FORMAT_NONE 0x0000 | ||
577 | #define COMPRESSION_FORMAT_DEFAULT 0x0001 | ||
578 | #define COMPRESSION_FORMAT_LZNT1 0x0002 | ||
572 | struct smb2_ioctl_req { | 579 | struct smb2_ioctl_req { |
573 | struct smb2_hdr hdr; | 580 | struct smb2_hdr hdr; |
574 | __le16 StructureSize; /* Must be 57 */ | 581 | __le16 StructureSize; /* Must be 57 */ |
@@ -584,7 +591,7 @@ struct smb2_ioctl_req { | |||
584 | __le32 MaxOutputResponse; | 591 | __le32 MaxOutputResponse; |
585 | __le32 Flags; | 592 | __le32 Flags; |
586 | __u32 Reserved2; | 593 | __u32 Reserved2; |
587 | char Buffer[0]; | 594 | __u8 Buffer[0]; |
588 | } __packed; | 595 | } __packed; |
589 | 596 | ||
590 | struct smb2_ioctl_rsp { | 597 | struct smb2_ioctl_rsp { |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index e3fb4801ee96..3cf22e39420d 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -142,6 +142,8 @@ extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, | |||
142 | extern int SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon, | 142 | extern int SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon, |
143 | u64 persistent_fid, u64 volatile_fid, | 143 | u64 persistent_fid, u64 volatile_fid, |
144 | FILE_BASIC_INFO *buf); | 144 | FILE_BASIC_INFO *buf); |
145 | extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | ||
146 | u64 persistent_fid, u64 volatile_fid); | ||
145 | extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, | 147 | extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, |
146 | const u64 persistent_fid, const u64 volatile_fid, | 148 | const u64 persistent_fid, const u64 volatile_fid, |
147 | const __u8 oplock_level); | 149 | const __u8 oplock_level); |