aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/ioctl.c55
-rw-r--r--fs/cifs/smb2ops.c11
-rw-r--r--fs/cifs/smb2pdu.c27
-rw-r--r--fs/cifs/smb2pdu.h9
-rw-r--r--fs/cifs/smb2proto.h2
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
448static int 448static int
449smb2_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
456static int
449smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, 457smb2_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
1254int
1255SMB2_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
1250int 1277int
1251SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, 1278SMB2_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
572struct 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
572struct smb2_ioctl_req { 579struct 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
590struct smb2_ioctl_rsp { 597struct 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,
142extern int SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon, 142extern 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);
145extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
146 u64 persistent_fid, u64 volatile_fid);
145extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, 147extern 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);