aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/Kconfig9
-rw-r--r--fs/cifs/cifsglob.h13
-rw-r--r--fs/cifs/cifspdu.h12
-rw-r--r--fs/cifs/cifssmb.c5
-rw-r--r--fs/cifs/connect.c13
-rw-r--r--fs/cifs/ioctl.c27
-rw-r--r--fs/cifs/smb2ops.c180
-rw-r--r--fs/cifs/smb2pdu.c67
-rw-r--r--fs/cifs/smb2pdu.h81
-rw-r--r--fs/cifs/smbfsctl.h3
10 files changed, 392 insertions, 18 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index a2172f3f69e3..e7b478b49985 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -192,6 +192,15 @@ config CIFS_SMB2
192 options are also slightly simpler (compared to CIFS) due 192 options are also slightly simpler (compared to CIFS) due
193 to protocol improvements. 193 to protocol improvements.
194 194
195config CIFS_SMB311
196 bool "SMB3.1.1 network file system support (Experimental)"
197 depends on CIFS_SMB2 && INET
198
199 help
200 This enables experimental support for the newest, SMB3.1.1, dialect.
201 This dialect includes improved security negotiation features.
202 If unsure, say N
203
195config CIFS_FSCACHE 204config CIFS_FSCACHE
196 bool "Provide CIFS client caching support" 205 bool "Provide CIFS client caching support"
197 depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y 206 depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 22b289a3b1c4..b406a32deb1f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -171,6 +171,10 @@ enum smb_version {
171 Smb_21, 171 Smb_21,
172 Smb_30, 172 Smb_30,
173 Smb_302, 173 Smb_302,
174#ifdef CONFIG_CIFS_SMB311
175 Smb_311,
176#endif /* SMB311 */
177 Smb_version_err
174}; 178};
175 179
176struct mid_q_entry; 180struct mid_q_entry;
@@ -368,6 +372,8 @@ struct smb_version_operations {
368 void (*new_lease_key)(struct cifs_fid *); 372 void (*new_lease_key)(struct cifs_fid *);
369 int (*generate_signingkey)(struct cifs_ses *); 373 int (*generate_signingkey)(struct cifs_ses *);
370 int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *); 374 int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *);
375 int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon,
376 struct cifsFileInfo *src_file);
371 int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, 377 int (*query_mf_symlink)(unsigned int, struct cifs_tcon *,
372 struct cifs_sb_info *, const unsigned char *, 378 struct cifs_sb_info *, const unsigned char *,
373 char *, unsigned int *); 379 char *, unsigned int *);
@@ -386,6 +392,9 @@ struct smb_version_operations {
386 int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file, 392 int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file,
387 struct cifsFileInfo *target_file, u64 src_off, u64 len, 393 struct cifsFileInfo *target_file, u64 src_off, u64 len,
388 u64 dest_off); 394 u64 dest_off);
395 int (*duplicate_extents)(const unsigned int, struct cifsFileInfo *src,
396 struct cifsFileInfo *target_file, u64 src_off, u64 len,
397 u64 dest_off);
389 int (*validate_negotiate)(const unsigned int, struct cifs_tcon *); 398 int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
390 ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *, 399 ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *,
391 const unsigned char *, const unsigned char *, char *, 400 const unsigned char *, const unsigned char *, char *,
@@ -1617,4 +1626,8 @@ extern struct smb_version_values smb30_values;
1617#define SMB302_VERSION_STRING "3.02" 1626#define SMB302_VERSION_STRING "3.02"
1618/*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */ 1627/*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */
1619extern struct smb_version_values smb302_values; 1628extern struct smb_version_values smb302_values;
1629#define SMB311_VERSION_STRING "3.1.1"
1630#define ALT_SMB311_VERSION_STRING "3.11"
1631extern struct smb_version_operations smb311_operations;
1632extern struct smb_version_values smb311_values;
1620#endif /* _CIFS_GLOB_H */ 1633#endif /* _CIFS_GLOB_H */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 5f9822ac0245..47b030da0781 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -2255,6 +2255,8 @@ typedef struct {
2255 2255
2256 2256
2257/* List of FileSystemAttributes - see 2.5.1 of MS-FSCC */ 2257/* List of FileSystemAttributes - see 2.5.1 of MS-FSCC */
2258#define FILE_SUPPORTS_SPARSE_VDL 0x10000000 /* faster nonsparse extend */
2259#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 /* allow ioctl dup extents */
2258#define FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000 2260#define FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000
2259#define FILE_SUPPORTS_USN_JOURNAL 0x02000000 2261#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
2260#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000 2262#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
@@ -2310,6 +2312,16 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */
2310 char FileName[1]; 2312 char FileName[1];
2311} __attribute__((packed)) FILE_ALL_INFO; /* level 0x107 QPathInfo */ 2313} __attribute__((packed)) FILE_ALL_INFO; /* level 0x107 QPathInfo */
2312 2314
2315typedef struct {
2316 __le64 AllocationSize;
2317 __le64 EndOfFile; /* size ie offset to first free byte in file */
2318 __le32 NumberOfLinks; /* hard links */
2319 __u8 DeletePending;
2320 __u8 Directory;
2321 __u16 Pad;
2322} __attribute__((packed)) FILE_STANDARD_INFO; /* level 0x102 QPathInfo */
2323
2324
2313/* defines for enumerating possible values of the Unix type field below */ 2325/* defines for enumerating possible values of the Unix type field below */
2314#define UNIX_FILE 0 2326#define UNIX_FILE 0
2315#define UNIX_DIR 1 2327#define UNIX_DIR 1
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f26ffbfc64d8..672ef35c9f73 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -625,9 +625,8 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
625 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 625 server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
626 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, 626 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
627 CIFS_CRYPTO_KEY_SIZE); 627 CIFS_CRYPTO_KEY_SIZE);
628 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || 628 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
629 server->capabilities & CAP_EXTENDED_SECURITY) && 629 server->capabilities & CAP_EXTENDED_SECURITY) {
630 (pSMBr->EncryptionKeyLength == 0)) {
631 server->negflavor = CIFS_NEGFLAVOR_EXTENDED; 630 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
632 rc = decode_ext_sec_blob(ses, pSMBr); 631 rc = decode_ext_sec_blob(ses, pSMBr);
633 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { 632 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8383d5ea4202..773f4dc77630 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -280,6 +280,11 @@ static const match_table_t cifs_smb_version_tokens = {
280 { Smb_21, SMB21_VERSION_STRING }, 280 { Smb_21, SMB21_VERSION_STRING },
281 { Smb_30, SMB30_VERSION_STRING }, 281 { Smb_30, SMB30_VERSION_STRING },
282 { Smb_302, SMB302_VERSION_STRING }, 282 { Smb_302, SMB302_VERSION_STRING },
283#ifdef CONFIG_CIFS_SMB311
284 { Smb_311, SMB311_VERSION_STRING },
285 { Smb_311, ALT_SMB311_VERSION_STRING },
286#endif /* SMB311 */
287 { Smb_version_err, NULL }
283}; 288};
284 289
285static int ip_connect(struct TCP_Server_Info *server); 290static int ip_connect(struct TCP_Server_Info *server);
@@ -1133,6 +1138,12 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol)
1133 vol->ops = &smb30_operations; /* currently identical with 3.0 */ 1138 vol->ops = &smb30_operations; /* currently identical with 3.0 */
1134 vol->vals = &smb302_values; 1139 vol->vals = &smb302_values;
1135 break; 1140 break;
1141#ifdef CONFIG_CIFS_SMB311
1142 case Smb_311:
1143 vol->ops = &smb311_operations;
1144 vol->vals = &smb311_values;
1145 break;
1146#endif /* SMB311 */
1136#endif 1147#endif
1137 default: 1148 default:
1138 cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); 1149 cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
@@ -3461,6 +3472,8 @@ try_mount_again:
3461 else if (ses) 3472 else if (ses)
3462 cifs_put_smb_ses(ses); 3473 cifs_put_smb_ses(ses);
3463 3474
3475 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS;
3476
3464 free_xid(xid); 3477 free_xid(xid);
3465 } 3478 }
3466#endif 3479#endif
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 8b7898b7670f..49b8b6e41a18 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -31,12 +31,15 @@
31#include "cifsproto.h" 31#include "cifsproto.h"
32#include "cifs_debug.h" 32#include "cifs_debug.h"
33#include "cifsfs.h" 33#include "cifsfs.h"
34#include <linux/btrfs.h>
34 35
35#define CIFS_IOCTL_MAGIC 0xCF 36#define CIFS_IOCTL_MAGIC 0xCF
36#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) 37#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
38#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
37 39
38static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, 40static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
39 unsigned long srcfd, u64 off, u64 len, u64 destoff) 41 unsigned long srcfd, u64 off, u64 len, u64 destoff,
42 bool dup_extents)
40{ 43{
41 int rc; 44 int rc;
42 struct cifsFileInfo *smb_file_target = dst_file->private_data; 45 struct cifsFileInfo *smb_file_target = dst_file->private_data;
@@ -109,9 +112,14 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
109 truncate_inode_pages_range(&target_inode->i_data, destoff, 112 truncate_inode_pages_range(&target_inode->i_data, destoff,
110 PAGE_CACHE_ALIGN(destoff + len)-1); 113 PAGE_CACHE_ALIGN(destoff + len)-1);
111 114
112 if (target_tcon->ses->server->ops->clone_range) 115 if (dup_extents && target_tcon->ses->server->ops->duplicate_extents)
116 rc = target_tcon->ses->server->ops->duplicate_extents(xid,
117 smb_file_src, smb_file_target, off, len, destoff);
118 else if (!dup_extents && target_tcon->ses->server->ops->clone_range)
113 rc = target_tcon->ses->server->ops->clone_range(xid, 119 rc = target_tcon->ses->server->ops->clone_range(xid,
114 smb_file_src, smb_file_target, off, len, destoff); 120 smb_file_src, smb_file_target, off, len, destoff);
121 else
122 rc = -EOPNOTSUPP;
115 123
116 /* force revalidate of size and timestamps of target file now 124 /* force revalidate of size and timestamps of target file now
117 that target is updated on the server */ 125 that target is updated on the server */
@@ -205,7 +213,20 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
205 } 213 }
206 break; 214 break;
207 case CIFS_IOC_COPYCHUNK_FILE: 215 case CIFS_IOC_COPYCHUNK_FILE:
208 rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0); 216 rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0, false);
217 break;
218 case BTRFS_IOC_CLONE:
219 rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0, true);
220 break;
221 case CIFS_IOC_SET_INTEGRITY:
222 if (pSMBFile == NULL)
223 break;
224 tcon = tlink_tcon(pSMBFile->tlink);
225 if (tcon->ses->server->ops->set_integrity)
226 rc = tcon->ses->server->ops->set_integrity(xid,
227 tcon, pSMBFile);
228 else
229 rc = -EOPNOTSUPP;
209 break; 230 break;
210 default: 231 default:
211 cifs_dbg(FYI, "unsupported ioctl\n"); 232 cifs_dbg(FYI, "unsupported ioctl\n");
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 54daee5ad4c1..df91bcf56d67 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -806,6 +806,53 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
806 cfile->fid.volatile_fid, cfile->pid, &eof, false); 806 cfile->fid.volatile_fid, cfile->pid, &eof, false);
807} 807}
808 808
809#ifdef CONFIG_CIFS_SMB311
810static int
811smb2_duplicate_extents(const unsigned int xid,
812 struct cifsFileInfo *srcfile,
813 struct cifsFileInfo *trgtfile, u64 src_off,
814 u64 len, u64 dest_off)
815{
816 int rc;
817 unsigned int ret_data_len;
818 char *retbuf = NULL;
819 struct duplicate_extents_to_file dup_ext_buf;
820 struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
821
822 /* server fileays advertise duplicate extent support with this flag */
823 if ((le32_to_cpu(tcon->fsAttrInfo.Attributes) &
824 FILE_SUPPORTS_BLOCK_REFCOUNTING) == 0)
825 return -EOPNOTSUPP;
826
827 dup_ext_buf.VolatileFileHandle = srcfile->fid.volatile_fid;
828 dup_ext_buf.PersistentFileHandle = srcfile->fid.persistent_fid;
829 dup_ext_buf.SourceFileOffset = cpu_to_le64(src_off);
830 dup_ext_buf.TargetFileOffset = cpu_to_le64(dest_off);
831 dup_ext_buf.ByteCount = cpu_to_le64(len);
832 cifs_dbg(FYI, "duplicate extents: src off %lld dst off %lld len %lld",
833 src_off, dest_off, len);
834
835 rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
836 if (rc)
837 goto duplicate_extents_out;
838
839 rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
840 trgtfile->fid.volatile_fid,
841 FSCTL_DUPLICATE_EXTENTS_TO_FILE,
842 true /* is_fsctl */, (char *)&dup_ext_buf,
843 sizeof(struct duplicate_extents_to_file),
844 (char **)&retbuf,
845 &ret_data_len);
846
847 if (ret_data_len > 0)
848 cifs_dbg(FYI, "non-zero response length in duplicate extents");
849
850duplicate_extents_out:
851 return rc;
852}
853#endif /* CONFIG_CIFS_SMB311 */
854
855
809static int 856static int
810smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 857smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
811 struct cifsFileInfo *cfile) 858 struct cifsFileInfo *cfile)
@@ -815,6 +862,28 @@ smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
815} 862}
816 863
817static int 864static int
865smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
866 struct cifsFileInfo *cfile)
867{
868 struct fsctl_set_integrity_information_req integr_info;
869 char *retbuf = NULL;
870 unsigned int ret_data_len;
871
872 integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED);
873 integr_info.Flags = 0;
874 integr_info.Reserved = 0;
875
876 return SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
877 cfile->fid.volatile_fid,
878 FSCTL_SET_INTEGRITY_INFORMATION,
879 true /* is_fsctl */, (char *)&integr_info,
880 sizeof(struct fsctl_set_integrity_information_req),
881 (char **)&retbuf,
882 &ret_data_len);
883
884}
885
886static int
818smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, 887smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
819 const char *path, struct cifs_sb_info *cifs_sb, 888 const char *path, struct cifs_sb_info *cifs_sb,
820 struct cifs_fid *fid, __u16 search_flags, 889 struct cifs_fid *fid, __u16 search_flags,
@@ -1624,6 +1693,7 @@ struct smb_version_operations smb30_operations = {
1624 .new_lease_key = smb2_new_lease_key, 1693 .new_lease_key = smb2_new_lease_key,
1625 .generate_signingkey = generate_smb3signingkey, 1694 .generate_signingkey = generate_smb3signingkey,
1626 .calc_signature = smb3_calc_signature, 1695 .calc_signature = smb3_calc_signature,
1696 .set_integrity = smb3_set_integrity,
1627 .is_read_op = smb21_is_read_op, 1697 .is_read_op = smb21_is_read_op,
1628 .set_oplock_level = smb3_set_oplock_level, 1698 .set_oplock_level = smb3_set_oplock_level,
1629 .create_lease_buf = smb3_create_lease_buf, 1699 .create_lease_buf = smb3_create_lease_buf,
@@ -1635,6 +1705,94 @@ struct smb_version_operations smb30_operations = {
1635 .fallocate = smb3_fallocate, 1705 .fallocate = smb3_fallocate,
1636}; 1706};
1637 1707
1708#ifdef CONFIG_CIFS_SMB311
1709struct smb_version_operations smb311_operations = {
1710 .compare_fids = smb2_compare_fids,
1711 .setup_request = smb2_setup_request,
1712 .setup_async_request = smb2_setup_async_request,
1713 .check_receive = smb2_check_receive,
1714 .add_credits = smb2_add_credits,
1715 .set_credits = smb2_set_credits,
1716 .get_credits_field = smb2_get_credits_field,
1717 .get_credits = smb2_get_credits,
1718 .wait_mtu_credits = smb2_wait_mtu_credits,
1719 .get_next_mid = smb2_get_next_mid,
1720 .read_data_offset = smb2_read_data_offset,
1721 .read_data_length = smb2_read_data_length,
1722 .map_error = map_smb2_to_linux_error,
1723 .find_mid = smb2_find_mid,
1724 .check_message = smb2_check_message,
1725 .dump_detail = smb2_dump_detail,
1726 .clear_stats = smb2_clear_stats,
1727 .print_stats = smb2_print_stats,
1728 .dump_share_caps = smb2_dump_share_caps,
1729 .is_oplock_break = smb2_is_valid_oplock_break,
1730 .downgrade_oplock = smb2_downgrade_oplock,
1731 .need_neg = smb2_need_neg,
1732 .negotiate = smb2_negotiate,
1733 .negotiate_wsize = smb2_negotiate_wsize,
1734 .negotiate_rsize = smb2_negotiate_rsize,
1735 .sess_setup = SMB2_sess_setup,
1736 .logoff = SMB2_logoff,
1737 .tree_connect = SMB2_tcon,
1738 .tree_disconnect = SMB2_tdis,
1739 .qfs_tcon = smb3_qfs_tcon,
1740 .is_path_accessible = smb2_is_path_accessible,
1741 .can_echo = smb2_can_echo,
1742 .echo = SMB2_echo,
1743 .query_path_info = smb2_query_path_info,
1744 .get_srv_inum = smb2_get_srv_inum,
1745 .query_file_info = smb2_query_file_info,
1746 .set_path_size = smb2_set_path_size,
1747 .set_file_size = smb2_set_file_size,
1748 .set_file_info = smb2_set_file_info,
1749 .set_compression = smb2_set_compression,
1750 .mkdir = smb2_mkdir,
1751 .mkdir_setinfo = smb2_mkdir_setinfo,
1752 .rmdir = smb2_rmdir,
1753 .unlink = smb2_unlink,
1754 .rename = smb2_rename_path,
1755 .create_hardlink = smb2_create_hardlink,
1756 .query_symlink = smb2_query_symlink,
1757 .query_mf_symlink = smb3_query_mf_symlink,
1758 .create_mf_symlink = smb3_create_mf_symlink,
1759 .open = smb2_open_file,
1760 .set_fid = smb2_set_fid,
1761 .close = smb2_close_file,
1762 .flush = smb2_flush_file,
1763 .async_readv = smb2_async_readv,
1764 .async_writev = smb2_async_writev,
1765 .sync_read = smb2_sync_read,
1766 .sync_write = smb2_sync_write,
1767 .query_dir_first = smb2_query_dir_first,
1768 .query_dir_next = smb2_query_dir_next,
1769 .close_dir = smb2_close_dir,
1770 .calc_smb_size = smb2_calc_size,
1771 .is_status_pending = smb2_is_status_pending,
1772 .oplock_response = smb2_oplock_response,
1773 .queryfs = smb2_queryfs,
1774 .mand_lock = smb2_mand_lock,
1775 .mand_unlock_range = smb2_unlock_range,
1776 .push_mand_locks = smb2_push_mandatory_locks,
1777 .get_lease_key = smb2_get_lease_key,
1778 .set_lease_key = smb2_set_lease_key,
1779 .new_lease_key = smb2_new_lease_key,
1780 .generate_signingkey = generate_smb3signingkey,
1781 .calc_signature = smb3_calc_signature,
1782 .set_integrity = smb3_set_integrity,
1783 .is_read_op = smb21_is_read_op,
1784 .set_oplock_level = smb3_set_oplock_level,
1785 .create_lease_buf = smb3_create_lease_buf,
1786 .parse_lease_buf = smb3_parse_lease_buf,
1787 .clone_range = smb2_clone_range,
1788 .duplicate_extents = smb2_duplicate_extents,
1789/* .validate_negotiate = smb3_validate_negotiate, */ /* not used in 3.11 */
1790 .wp_retry_size = smb2_wp_retry_size,
1791 .dir_needs_close = smb2_dir_needs_close,
1792 .fallocate = smb3_fallocate,
1793};
1794#endif /* CIFS_SMB311 */
1795
1638struct smb_version_values smb20_values = { 1796struct smb_version_values smb20_values = {
1639 .version_string = SMB20_VERSION_STRING, 1797 .version_string = SMB20_VERSION_STRING,
1640 .protocol_id = SMB20_PROT_ID, 1798 .protocol_id = SMB20_PROT_ID,
@@ -1714,3 +1872,25 @@ struct smb_version_values smb302_values = {
1714 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, 1872 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1715 .create_lease_size = sizeof(struct create_lease_v2), 1873 .create_lease_size = sizeof(struct create_lease_v2),
1716}; 1874};
1875
1876#ifdef CONFIG_CIFS_SMB311
1877struct smb_version_values smb311_values = {
1878 .version_string = SMB311_VERSION_STRING,
1879 .protocol_id = SMB311_PROT_ID,
1880 .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1881 .large_lock_type = 0,
1882 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1883 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1884 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1885 .header_size = sizeof(struct smb2_hdr),
1886 .max_header_size = MAX_SMB2_HDR_SIZE,
1887 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1888 .lock_cmd = SMB2_LOCK,
1889 .cap_unix = 0,
1890 .cap_nt_find = SMB2_NT_FIND,
1891 .cap_large_files = SMB2_LARGE_FILES,
1892 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1893 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1894 .create_lease_size = sizeof(struct create_lease_v2),
1895};
1896#endif /* SMB311 */
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 54cbe19d9c08..b8b4f08ee094 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -304,6 +304,59 @@ small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon,
304 return rc; 304 return rc;
305} 305}
306 306
307#ifdef CONFIG_CIFS_SMB311
308/* offset is sizeof smb2_negotiate_req - 4 but rounded up to 8 bytes */
309#define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) - 4 */
310
311
312#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
313#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
314
315static void
316build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
317{
318 pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
319 pneg_ctxt->DataLength = cpu_to_le16(38);
320 pneg_ctxt->HashAlgorithmCount = cpu_to_le16(1);
321 pneg_ctxt->SaltLength = cpu_to_le16(SMB311_SALT_SIZE);
322 get_random_bytes(pneg_ctxt->Salt, SMB311_SALT_SIZE);
323 pneg_ctxt->HashAlgorithms = SMB2_PREAUTH_INTEGRITY_SHA512;
324}
325
326static void
327build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
328{
329 pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
330 pneg_ctxt->DataLength = cpu_to_le16(6);
331 pneg_ctxt->CipherCount = cpu_to_le16(2);
332 pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
333 pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
334}
335
336static void
337assemble_neg_contexts(struct smb2_negotiate_req *req)
338{
339
340 /* +4 is to account for the RFC1001 len field */
341 char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT + 4;
342
343 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
344 /* Add 2 to size to round to 8 byte boundary */
345 pneg_ctxt += 2 + sizeof(struct smb2_preauth_neg_context);
346 build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt);
347 req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
348 req->NegotiateContextCount = cpu_to_le16(2);
349 inc_rfc1001_len(req, 4 + sizeof(struct smb2_preauth_neg_context) + 2
350 + sizeof(struct smb2_encryption_neg_context)); /* calculate hash */
351}
352#else
353static void assemble_neg_contexts(struct smb2_negotiate_req *req)
354{
355 return;
356}
357#endif /* SMB311 */
358
359
307/* 360/*
308 * 361 *
309 * SMB2 Worker functions follow: 362 * SMB2 Worker functions follow:
@@ -363,10 +416,12 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
363 /* ClientGUID must be zero for SMB2.02 dialect */ 416 /* ClientGUID must be zero for SMB2.02 dialect */
364 if (ses->server->vals->protocol_id == SMB20_PROT_ID) 417 if (ses->server->vals->protocol_id == SMB20_PROT_ID)
365 memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE); 418 memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE);
366 else 419 else {
367 memcpy(req->ClientGUID, server->client_guid, 420 memcpy(req->ClientGUID, server->client_guid,
368 SMB2_CLIENT_GUID_SIZE); 421 SMB2_CLIENT_GUID_SIZE);
369 422 if (ses->server->vals->protocol_id == SMB311_PROT_ID)
423 assemble_neg_contexts(req);
424 }
370 iov[0].iov_base = (char *)req; 425 iov[0].iov_base = (char *)req;
371 /* 4 for rfc1002 length field */ 426 /* 4 for rfc1002 length field */
372 iov[0].iov_len = get_rfc1002_length(req) + 4; 427 iov[0].iov_len = get_rfc1002_length(req) + 4;
@@ -393,8 +448,12 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
393 cifs_dbg(FYI, "negotiated smb3.0 dialect\n"); 448 cifs_dbg(FYI, "negotiated smb3.0 dialect\n");
394 else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID)) 449 else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID))
395 cifs_dbg(FYI, "negotiated smb3.02 dialect\n"); 450 cifs_dbg(FYI, "negotiated smb3.02 dialect\n");
451#ifdef CONFIG_CIFS_SMB311
452 else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
453 cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n");
454#endif /* SMB311 */
396 else { 455 else {
397 cifs_dbg(VFS, "Illegal dialect returned by server %d\n", 456 cifs_dbg(VFS, "Illegal dialect returned by server 0x%x\n",
398 le16_to_cpu(rsp->DialectRevision)); 457 le16_to_cpu(rsp->DialectRevision));
399 rc = -EIO; 458 rc = -EIO;
400 goto neg_exit; 459 goto neg_exit;
@@ -572,7 +631,7 @@ ssetup_ntlmssp_authenticate:
572 return rc; 631 return rc;
573 632
574 req->hdr.SessionId = 0; /* First session, not a reauthenticate */ 633 req->hdr.SessionId = 0; /* First session, not a reauthenticate */
575 req->VcNumber = 0; /* MBZ */ 634 req->Flags = 0; /* MBZ */
576 /* to enable echos and oplocks */ 635 /* to enable echos and oplocks */
577 req->hdr.CreditRequest = cpu_to_le16(3); 636 req->hdr.CreditRequest = cpu_to_le16(3);
578 637
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 70867d54fb8b..451108284a2f 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -136,9 +136,6 @@ struct smb2_transform_hdr {
136 __u64 SessionId; 136 __u64 SessionId;
137} __packed; 137} __packed;
138 138
139/* Encryption Algorithms */
140#define SMB2_ENCRYPTION_AES128_CCM cpu_to_le16(0x0001)
141
142/* 139/*
143 * SMB2 flag definitions 140 * SMB2 flag definitions
144 */ 141 */
@@ -191,7 +188,10 @@ struct smb2_negotiate_req {
191 __le16 Reserved; /* MBZ */ 188 __le16 Reserved; /* MBZ */
192 __le32 Capabilities; 189 __le32 Capabilities;
193 __u8 ClientGUID[SMB2_CLIENT_GUID_SIZE]; 190 __u8 ClientGUID[SMB2_CLIENT_GUID_SIZE];
194 __le64 ClientStartTime; /* MBZ */ 191 /* In SMB3.02 and earlier next three were MBZ le64 ClientStartTime */
192 __le32 NegotiateContextOffset; /* SMB3.1.1 only. MBZ earlier */
193 __le16 NegotiateContextCount; /* SMB3.1.1 only. MBZ earlier */
194 __le16 Reserved2;
195 __le16 Dialects[1]; /* One dialect (vers=) at a time for now */ 195 __le16 Dialects[1]; /* One dialect (vers=) at a time for now */
196} __packed; 196} __packed;
197 197
@@ -200,6 +200,7 @@ struct smb2_negotiate_req {
200#define SMB21_PROT_ID 0x0210 200#define SMB21_PROT_ID 0x0210
201#define SMB30_PROT_ID 0x0300 201#define SMB30_PROT_ID 0x0300
202#define SMB302_PROT_ID 0x0302 202#define SMB302_PROT_ID 0x0302
203#define SMB311_PROT_ID 0x0311
203#define BAD_PROT_ID 0xFFFF 204#define BAD_PROT_ID 0xFFFF
204 205
205/* SecurityMode flags */ 206/* SecurityMode flags */
@@ -217,12 +218,38 @@ struct smb2_negotiate_req {
217#define SMB2_NT_FIND 0x00100000 218#define SMB2_NT_FIND 0x00100000
218#define SMB2_LARGE_FILES 0x00200000 219#define SMB2_LARGE_FILES 0x00200000
219 220
221#define SMB311_SALT_SIZE 32
222/* Hash Algorithm Types */
223#define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001)
224
225struct smb2_preauth_neg_context {
226 __le16 ContextType; /* 1 */
227 __le16 DataLength;
228 __le32 Reserved;
229 __le16 HashAlgorithmCount; /* 1 */
230 __le16 SaltLength;
231 __le16 HashAlgorithms; /* HashAlgorithms[0] since only one defined */
232 __u8 Salt[SMB311_SALT_SIZE];
233} __packed;
234
235/* Encryption Algorithms Ciphers */
236#define SMB2_ENCRYPTION_AES128_CCM cpu_to_le16(0x0001)
237#define SMB2_ENCRYPTION_AES128_GCM cpu_to_le16(0x0002)
238
239struct smb2_encryption_neg_context {
240 __le16 ContextType; /* 2 */
241 __le16 DataLength;
242 __le32 Reserved;
243 __le16 CipherCount; /* AES-128-GCM and AES-128-CCM */
244 __le16 Ciphers[2]; /* Ciphers[0] since only one used now */
245} __packed;
246
220struct smb2_negotiate_rsp { 247struct smb2_negotiate_rsp {
221 struct smb2_hdr hdr; 248 struct smb2_hdr hdr;
222 __le16 StructureSize; /* Must be 65 */ 249 __le16 StructureSize; /* Must be 65 */
223 __le16 SecurityMode; 250 __le16 SecurityMode;
224 __le16 DialectRevision; 251 __le16 DialectRevision;
225 __le16 Reserved; /* MBZ */ 252 __le16 NegotiateContextCount; /* Prior to SMB3.1.1 was Reserved & MBZ */
226 __u8 ServerGUID[16]; 253 __u8 ServerGUID[16];
227 __le32 Capabilities; 254 __le32 Capabilities;
228 __le32 MaxTransactSize; 255 __le32 MaxTransactSize;
@@ -232,14 +259,18 @@ struct smb2_negotiate_rsp {
232 __le64 ServerStartTime; 259 __le64 ServerStartTime;
233 __le16 SecurityBufferOffset; 260 __le16 SecurityBufferOffset;
234 __le16 SecurityBufferLength; 261 __le16 SecurityBufferLength;
235 __le32 Reserved2; /* may be any value, ignore */ 262 __le32 NegotiateContextOffset; /* Pre:SMB3.1.1 was reserved/ignored */
236 __u8 Buffer[1]; /* variable length GSS security buffer */ 263 __u8 Buffer[1]; /* variable length GSS security buffer */
237} __packed; 264} __packed;
238 265
266/* Flags */
267#define SMB2_SESSION_REQ_FLAG_BINDING 0x01
268#define SMB2_SESSION_REQ_FLAG_ENCRYPT_DATA 0x04
269
239struct smb2_sess_setup_req { 270struct smb2_sess_setup_req {
240 struct smb2_hdr hdr; 271 struct smb2_hdr hdr;
241 __le16 StructureSize; /* Must be 25 */ 272 __le16 StructureSize; /* Must be 25 */
242 __u8 VcNumber; 273 __u8 Flags;
243 __u8 SecurityMode; 274 __u8 SecurityMode;
244 __le32 Capabilities; 275 __le32 Capabilities;
245 __le32 Channel; 276 __le32 Channel;
@@ -274,10 +305,13 @@ struct smb2_logoff_rsp {
274 __le16 Reserved; 305 __le16 Reserved;
275} __packed; 306} __packed;
276 307
308/* Flags/Reserved for SMB3.1.1 */
309#define SMB2_SHAREFLAG_CLUSTER_RECONNECT 0x0001
310
277struct smb2_tree_connect_req { 311struct smb2_tree_connect_req {
278 struct smb2_hdr hdr; 312 struct smb2_hdr hdr;
279 __le16 StructureSize; /* Must be 9 */ 313 __le16 StructureSize; /* Must be 9 */
280 __le16 Reserved; 314 __le16 Reserved; /* Flags in SMB3.1.1 */
281 __le16 PathOffset; 315 __le16 PathOffset;
282 __le16 PathLength; 316 __le16 PathLength;
283 __u8 Buffer[1]; /* variable length */ 317 __u8 Buffer[1]; /* variable length */
@@ -587,6 +621,29 @@ struct copychunk_ioctl_rsp {
587 __le32 TotalBytesWritten; 621 __le32 TotalBytesWritten;
588} __packed; 622} __packed;
589 623
624struct fsctl_set_integrity_information_req {
625 __le16 ChecksumAlgorithm;
626 __le16 Reserved;
627 __le32 Flags;
628} __packed;
629
630struct fsctl_get_integrity_information_rsp {
631 __le16 ChecksumAlgorithm;
632 __le16 Reserved;
633 __le32 Flags;
634 __le32 ChecksumChunkSizeInBytes;
635 __le32 ClusterSizeInBytes;
636} __packed;
637
638/* Integrity ChecksumAlgorithm choices for above */
639#define CHECKSUM_TYPE_NONE 0x0000
640#define CHECKSUM_TYPE_CRC64 0x0002
641#define CHECKSUM_TYPE_UNCHANGED 0xFFFF /* set only */
642
643/* Integrity flags for above */
644#define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001
645
646
590struct validate_negotiate_info_req { 647struct validate_negotiate_info_req {
591 __le32 Capabilities; 648 __le32 Capabilities;
592 __u8 Guid[SMB2_CLIENT_GUID_SIZE]; 649 __u8 Guid[SMB2_CLIENT_GUID_SIZE];
@@ -620,6 +677,14 @@ struct compress_ioctl {
620 __le16 CompressionState; /* See cifspdu.h for possible flag values */ 677 __le16 CompressionState; /* See cifspdu.h for possible flag values */
621} __packed; 678} __packed;
622 679
680struct duplicate_extents_to_file {
681 __u64 PersistentFileHandle; /* source file handle, opaque endianness */
682 __u64 VolatileFileHandle;
683 __le64 SourceFileOffset;
684 __le64 TargetFileOffset;
685 __le64 ByteCount; /* Bytes to be copied */
686} __packed;
687
623struct smb2_ioctl_req { 688struct smb2_ioctl_req {
624 struct smb2_hdr hdr; 689 struct smb2_hdr hdr;
625 __le16 StructureSize; /* Must be 57 */ 690 __le16 StructureSize; /* Must be 57 */
diff --git a/fs/cifs/smbfsctl.h b/fs/cifs/smbfsctl.h
index 83efa59535be..a639d0dab453 100644
--- a/fs/cifs/smbfsctl.h
+++ b/fs/cifs/smbfsctl.h
@@ -75,10 +75,13 @@
75#define FSCTL_QUERY_SPARING_INFO 0x00090138 /* BB add struct */ 75#define FSCTL_QUERY_SPARING_INFO 0x00090138 /* BB add struct */
76#define FSCTL_SET_ZERO_ON_DEALLOC 0x00090194 /* BB add struct */ 76#define FSCTL_SET_ZERO_ON_DEALLOC 0x00090194 /* BB add struct */
77#define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */ 77#define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */
78#define FSCTL_GET_INTEGRITY_INFORMATION 0x0009027C
78#define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF /* BB add struct */ 79#define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF /* BB add struct */
79#define FSCTL_SET_DEFECT_MANAGEMENT 0x00098134 /* BB add struct */ 80#define FSCTL_SET_DEFECT_MANAGEMENT 0x00098134 /* BB add struct */
80#define FSCTL_FILE_LEVEL_TRIM 0x00098208 /* BB add struct */ 81#define FSCTL_FILE_LEVEL_TRIM 0x00098208 /* BB add struct */
82#define FSCTL_DUPLICATE_EXTENTS_TO_FILE 0x00098344
81#define FSCTL_SIS_LINK_FILES 0x0009C104 83#define FSCTL_SIS_LINK_FILES 0x0009C104
84#define FSCTL_SET_INTEGRITY_INFORMATION 0x0009C280
82#define FSCTL_PIPE_PEEK 0x0011400C /* BB add struct */ 85#define FSCTL_PIPE_PEEK 0x0011400C /* BB add struct */
83#define FSCTL_PIPE_TRANSCEIVE 0x0011C017 /* BB add struct */ 86#define FSCTL_PIPE_TRANSCEIVE 0x0011C017 /* BB add struct */
84/* strange that the number for this op is not sequential with previous op */ 87/* strange that the number for this op is not sequential with previous op */