Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bb37da5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '4.19-smb3' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs updates from Steve French:
 "smb3/cifs fixes (including 8 for stable).

  Other improvements include:

   - improved tracing, improved stats

   - snapshots (previous version mounts work now over SMB3)

   - performance (compounding enabled for statfs, ~40% faster).

   - security (make it possible to build cifs.ko with insecure vers=1.0
     disabled in Kconfig)"

* tag '4.19-smb3' of git://git.samba.org/sfrench/cifs-2.6: (43 commits)
  smb3: create smb3 equivalent alias for cifs pseudo-xattrs
  smb3: allow previous versions to be mounted with snapshot= mount parm
  cifs: don't show domain= in mount output when domain is empty
  cifs: add missing support for ACLs in SMB 3.11
  smb3: enumerating snapshots was leaving part of the data off end
  cifs: update smb2_queryfs() to use compounding
  cifs: update receive_encrypted_standard to handle compounded responses
  cifs: create SMB2_open_init()/SMB2_open_free() helpers.
  cifs: add SMB2_query_info_[init|free]()
  cifs: add SMB2_close_init()/SMB2_close_free()
  smb3: display stats counters for number of slow commands
  CIFS: fix uninitialized ptr deref in smb2 signing
  smb3: Do not send SMB3 SET_INFO if nothing changed
  smb3: fix minor debug output for CONFIG_CIFS_STATS
  smb3: add tracepoint for slow responses
  cifs: add compound_send_recv()
  cifs: make smb_send_rqst take an array of requests
  cifs: update init_sg, crypt_message to take an array of rqst
  smb3: update readme to correct information about /proc/fs/cifs/Stats
  smb3: fix reset of bytes read and written stats
  ...
parents 161fa27f c4f7173a
Loading
Loading
Loading
Loading
+4 −1068

File changed.

Preview size limit exceeded, changes collapsed.

+10 −12
Original line number Original line Diff line number Diff line
@@ -603,8 +603,7 @@ DebugData Displays information about active CIFS sessions and
			shares, features enabled as well as the cifs.ko
			shares, features enabled as well as the cifs.ko
			version.
			version.
Stats			Lists summary resource usage information as well as per
Stats			Lists summary resource usage information as well as per
			share statistics, if CONFIG_CIFS_STATS in enabled
			share statistics.
			in the kernel configuration.


Configuration pseudo-files:
Configuration pseudo-files:
SecurityFlags		Flags which control security negotiation and
SecurityFlags		Flags which control security negotiation and
@@ -687,23 +686,22 @@ cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
logging of various informational messages.  2 enables logging of non-zero
logging of various informational messages.  2 enables logging of non-zero
SMB return codes while 4 enables logging of requests that take longer
SMB return codes while 4 enables logging of requests that take longer
than one second to complete (except for byte range lock requests). 
than one second to complete (except for byte range lock requests). 
Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
Setting it to 4 requires CONFIG_CIFS_STATS2 to be set in kernel configuration
source code (typically by setting it in the beginning of cifsglob.h),
(.config). Setting it to seven enables all three.  Finally, tracing
and setting it to seven enables all three.  Finally, tracing
the start of smb requests and responses can be enabled via:
the start of smb requests and responses can be enabled via:


	echo 1 > /proc/fs/cifs/traceSMB
	echo 1 > /proc/fs/cifs/traceSMB


Per share (per client mount) statistics are available in /proc/fs/cifs/Stats
Per share (per client mount) statistics are available in /proc/fs/cifs/Stats.
if the kernel was configured with cifs statistics enabled.  The statistics
Additional information is available if CONFIG_CIFS_STATS2 is enabled in the
represent the number of successful (ie non-zero return code from the server) 
kernel configuration (.config).  The statistics returned include counters which
SMB responses to some of the more common commands (open, delete, mkdir etc.).
represent the number of attempted and failed (ie non-zero return code from the
server) SMB3 (or cifs) requests grouped by request type (read, write, close etc.).
Also recorded is the total bytes read and bytes written to the server for
Also recorded is the total bytes read and bytes written to the server for
that share.  Note that due to client caching effects this can be less than the
that share.  Note that due to client caching effects this can be less than the
number of bytes read and written by the application running on the client.
number of bytes read and written by the application running on the client.
The statistics for the number of total SMBs and oplock breaks are different in
Statistics can be reset to zero by "echo 0 > /proc/fs/cifs/Stats" which may be
that they represent all for that share, not just those for which the server
useful if comparing performance of two different scenarios.
returned success.
	
	
Also note that "cat /proc/fs/cifs/DebugData" will display information about
Also note that "cat /proc/fs/cifs/DebugData" will display information about
the active sessions and the shares that are mounted.
the active sessions and the shares that are mounted.
+31 −28
Original line number Original line Diff line number Diff line
@@ -16,24 +16,28 @@ config CIFS
	select CRYPTO_DES
	select CRYPTO_DES
	help
	help
	  This is the client VFS module for the SMB3 family of NAS protocols,
	  This is the client VFS module for the SMB3 family of NAS protocols,
	  as well as for earlier dialects such as SMB2.1, SMB2 and the
	  (including support for the most recent, most secure dialect SMB3.1.1)
	  as well as for earlier dialects such as SMB2.1, SMB2 and the older
	  Common Internet File System (CIFS) protocol.  CIFS was the successor
	  Common Internet File System (CIFS) protocol.  CIFS was the successor
	  to the original dialect, the Server Message Block (SMB) protocol, the
	  to the original dialect, the Server Message Block (SMB) protocol, the
	  native file sharing mechanism for most early PC operating systems.
	  native file sharing mechanism for most early PC operating systems.


	  The SMB3 protocol is supported by most modern operating systems and
	  The SMB3 protocol is supported by most modern operating systems
	  NAS appliances (e.g. Samba, Windows 8, Windows 2012, MacOS).
	  and NAS appliances (e.g. Samba, Windows 10, Windows Server 2016,
	  MacOS) and even in the cloud (e.g. Microsoft Azure).
	  The older CIFS protocol was included in Windows NT4, 2000 and XP (and
	  The older CIFS protocol was included in Windows NT4, 2000 and XP (and
	  later) as well by Samba (which provides excellent CIFS and SMB3
	  later) as well by Samba (which provides excellent CIFS and SMB3
	  server support for Linux and many other operating systems). Limited
	  server support for Linux and many other operating systems). Use of
	  support for OS/2 and Windows ME and similar very old servers is
	  dialects older than SMB2.1 is often discouraged on public networks.
	  provided as well.
	  This module also provides limited support for OS/2 and Windows ME
	  and similar very old servers.


	  The cifs module provides an advanced network file system client
	  This module provides an advanced network file system client
	  for mounting to SMB3 (and CIFS) compliant servers.  It includes
	  for mounting to SMB3 (and CIFS) compliant servers.  It includes
	  support for DFS (hierarchical name space), secure per-user
	  support for DFS (hierarchical name space), secure per-user
	  session establishment via Kerberos or NTLM or NTLMv2,
	  session establishment via Kerberos or NTLM or NTLMv2, RDMA
	  safe distributed caching (oplock), optional packet
	  (smbdirect), advanced security features, per-share encryption,
	  directory leases, safe distributed caching (oplock), optional packet
	  signing, Unicode and other internationalization improvements.
	  signing, Unicode and other internationalization improvements.


	  In general, the default dialects, SMB3 and later, enable better
	  In general, the default dialects, SMB3 and later, enable better
@@ -43,18 +47,11 @@ config CIFS
	  than SMB3 mounts. SMB2/SMB3 mount options are also
	  than SMB3 mounts. SMB2/SMB3 mount options are also
	  slightly simpler (compared to CIFS) due to protocol improvements.
	  slightly simpler (compared to CIFS) due to protocol improvements.


	  If you need to mount to Samba, Macs or Windows from this machine, say Y.
	  If you need to mount to Samba, Azure, Macs or Windows from this machine, say Y.

config CIFS_STATS
        bool "CIFS statistics"
        depends on CIFS
        help
          Enabling this option will cause statistics for each server share
	  mounted by the cifs client to be displayed in /proc/fs/cifs/Stats


config CIFS_STATS2
config CIFS_STATS2
	bool "Extended statistics"
	bool "Extended statistics"
	depends on CIFS_STATS
	depends on CIFS
	help
	help
	  Enabling this option will allow more detailed statistics on SMB
	  Enabling this option will allow more detailed statistics on SMB
	  request timing to be displayed in /proc/fs/cifs/DebugData and also
	  request timing to be displayed in /proc/fs/cifs/DebugData and also
@@ -66,9 +63,24 @@ config CIFS_STATS2
	  Unless you are a developer or are doing network performance analysis
	  Unless you are a developer or are doing network performance analysis
	  or tuning, say N.
	  or tuning, say N.


config CIFS_ALLOW_INSECURE_LEGACY
	bool "Support legacy servers which use less secure dialects"
	depends on CIFS
	default y
	help
	  Modern dialects, SMB2.1 and later (including SMB3 and 3.1.1), have
	  additional security features, including protection against
	  man-in-the-middle attacks and stronger crypto hashes, so the use
	  of legacy dialects (SMB1/CIFS and SMB2.0) is discouraged.

	  Disabling this option prevents users from using vers=1.0 or vers=2.0
	  on mounts with cifs.ko

	  If unsure, say Y.

config CIFS_WEAK_PW_HASH
config CIFS_WEAK_PW_HASH
	bool "Support legacy servers which use weaker LANMAN security"
	bool "Support legacy servers which use weaker LANMAN security"
	depends on CIFS
	depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY
	help
	help
	  Modern CIFS servers including Samba and most Windows versions
	  Modern CIFS servers including Samba and most Windows versions
	  (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
	  (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
@@ -186,15 +198,6 @@ config CIFS_NFSD_EXPORT
	  help
	  help
	   Allows NFS server to export a CIFS mounted share (nfsd over cifs)
	   Allows NFS server to export a CIFS mounted share (nfsd over cifs)


config CIFS_SMB311
	bool "SMB3.1.1 network file system support"
	depends on CIFS
	select CRYPTO_SHA512

	help
	  This enables support for the newest, and most secure dialect, SMB3.11.
	  If unsure, say Y

config CIFS_SMB_DIRECT
config CIFS_SMB_DIRECT
	bool "SMB Direct support (Experimental)"
	bool "SMB Direct support (Experimental)"
	depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y
	depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y
+4 −2
Original line number Original line Diff line number Diff line
@@ -128,8 +128,10 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,


	memset(&auxdata, 0, sizeof(auxdata));
	memset(&auxdata, 0, sizeof(auxdata));
	auxdata.eof = cifsi->server_eof;
	auxdata.eof = cifsi->server_eof;
	auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime);
	auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
	auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime);
	auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec;
	auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec;
	auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;


	if (memcmp(data, &auxdata, datalen) != 0)
	if (memcmp(data, &auxdata, datalen) != 0)
		return FSCACHE_CHECKAUX_OBSOLETE;
		return FSCACHE_CHECKAUX_OBSOLETE;
+49 −17
Original line number Original line Diff line number Diff line
@@ -160,25 +160,41 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
	seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
	seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
	seq_printf(m, "Features:");
	seq_printf(m, "Features:");
#ifdef CONFIG_CIFS_DFS_UPCALL
#ifdef CONFIG_CIFS_DFS_UPCALL
	seq_printf(m, " dfs");
	seq_printf(m, " DFS");
#endif
#endif
#ifdef CONFIG_CIFS_FSCACHE
#ifdef CONFIG_CIFS_FSCACHE
	seq_printf(m, " fscache");
	seq_printf(m, ",FSCACHE");
#endif
#ifdef CONFIG_CIFS_SMB_DIRECT
	seq_printf(m, ",SMB_DIRECT");
#endif
#ifdef CONFIG_CIFS_STATS2
	seq_printf(m, ",STATS2");
#else
	seq_printf(m, ",STATS");
#endif
#ifdef CONFIG_CIFS_DEBUG2
	seq_printf(m, ",DEBUG2");
#elif defined(CONFIG_CIFS_DEBUG)
	seq_printf(m, ",DEBUG");
#endif
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
	seq_printf(m, ",ALLOW_INSECURE_LEGACY");
#endif
#endif
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#ifdef CONFIG_CIFS_WEAK_PW_HASH
	seq_printf(m, " lanman");
	seq_printf(m, ",WEAK_PW_HASH");
#endif
#endif
#ifdef CONFIG_CIFS_POSIX
#ifdef CONFIG_CIFS_POSIX
	seq_printf(m, " posix");
	seq_printf(m, ",CIFS_POSIX");
#endif
#endif
#ifdef CONFIG_CIFS_UPCALL
#ifdef CONFIG_CIFS_UPCALL
	seq_printf(m, " spnego");
	seq_printf(m, ",UPCALL(SPNEGO)");
#endif
#endif
#ifdef CONFIG_CIFS_XATTR
#ifdef CONFIG_CIFS_XATTR
	seq_printf(m, " xattr");
	seq_printf(m, ",XATTR");
#endif
#endif
#ifdef CONFIG_CIFS_ACL
#ifdef CONFIG_CIFS_ACL
	seq_printf(m, " acl");
	seq_printf(m, ",ACL");
#endif
#endif
	seq_putc(m, '\n');
	seq_putc(m, '\n');
	seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
	seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
@@ -259,10 +275,9 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
			server->credits,  server->dialect);
			server->credits,  server->dialect);
		if (server->sign)
		if (server->sign)
			seq_printf(m, " signed");
			seq_printf(m, " signed");
#ifdef CONFIG_CIFS_SMB311
		if (server->posix_ext_supported)
		if (server->posix_ext_supported)
			seq_printf(m, " posix");
			seq_printf(m, " posix");
#endif /* 3.1.1 */

		i++;
		i++;
		list_for_each(tmp2, &server->smb_ses_list) {
		list_for_each(tmp2, &server->smb_ses_list) {
			ses = list_entry(tmp2, struct cifs_ses,
			ses = list_entry(tmp2, struct cifs_ses,
@@ -350,7 +365,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
	return 0;
	return 0;
}
}


#ifdef CONFIG_CIFS_STATS
static ssize_t cifs_stats_proc_write(struct file *file,
static ssize_t cifs_stats_proc_write(struct file *file,
		const char __user *buffer, size_t count, loff_t *ppos)
		const char __user *buffer, size_t count, loff_t *ppos)
{
{
@@ -364,13 +378,23 @@ static ssize_t cifs_stats_proc_write(struct file *file,
	rc = kstrtobool_from_user(buffer, count, &bv);
	rc = kstrtobool_from_user(buffer, count, &bv);
	if (rc == 0) {
	if (rc == 0) {
#ifdef CONFIG_CIFS_STATS2
#ifdef CONFIG_CIFS_STATS2
		int i;

		atomic_set(&totBufAllocCount, 0);
		atomic_set(&totBufAllocCount, 0);
		atomic_set(&totSmBufAllocCount, 0);
		atomic_set(&totSmBufAllocCount, 0);
#endif /* CONFIG_CIFS_STATS2 */
#endif /* CONFIG_CIFS_STATS2 */
		spin_lock(&GlobalMid_Lock);
		GlobalMaxActiveXid = 0;
		GlobalCurrentXid = 0;
		spin_unlock(&GlobalMid_Lock);
		spin_lock(&cifs_tcp_ses_lock);
		spin_lock(&cifs_tcp_ses_lock);
		list_for_each(tmp1, &cifs_tcp_ses_list) {
		list_for_each(tmp1, &cifs_tcp_ses_list) {
			server = list_entry(tmp1, struct TCP_Server_Info,
			server = list_entry(tmp1, struct TCP_Server_Info,
					    tcp_ses_list);
					    tcp_ses_list);
#ifdef CONFIG_CIFS_STATS2
			for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++)
				atomic_set(&server->smb2slowcmd[i], 0);
#endif /* CONFIG_CIFS_STATS2 */
			list_for_each(tmp2, &server->smb_ses_list) {
			list_for_each(tmp2, &server->smb_ses_list) {
				ses = list_entry(tmp2, struct cifs_ses,
				ses = list_entry(tmp2, struct cifs_ses,
						 smb_ses_list);
						 smb_ses_list);
@@ -379,6 +403,10 @@ static ssize_t cifs_stats_proc_write(struct file *file,
							  struct cifs_tcon,
							  struct cifs_tcon,
							  tcon_list);
							  tcon_list);
					atomic_set(&tcon->num_smbs_sent, 0);
					atomic_set(&tcon->num_smbs_sent, 0);
					spin_lock(&tcon->stat_lock);
					tcon->bytes_read = 0;
					tcon->bytes_written = 0;
					spin_unlock(&tcon->stat_lock);
					if (server->ops->clear_stats)
					if (server->ops->clear_stats)
						server->ops->clear_stats(tcon);
						server->ops->clear_stats(tcon);
				}
				}
@@ -395,13 +423,15 @@ static ssize_t cifs_stats_proc_write(struct file *file,
static int cifs_stats_proc_show(struct seq_file *m, void *v)
static int cifs_stats_proc_show(struct seq_file *m, void *v)
{
{
	int i;
	int i;
#ifdef CONFIG_CIFS_STATS2
	int j;
#endif /* STATS2 */
	struct list_head *tmp1, *tmp2, *tmp3;
	struct list_head *tmp1, *tmp2, *tmp3;
	struct TCP_Server_Info *server;
	struct TCP_Server_Info *server;
	struct cifs_ses *ses;
	struct cifs_ses *ses;
	struct cifs_tcon *tcon;
	struct cifs_tcon *tcon;


	seq_printf(m,
	seq_printf(m, "Resources in use\nCIFS Session: %d\n",
			"Resources in use\nCIFS Session: %d\n",
			sesInfoAllocCount.counter);
			sesInfoAllocCount.counter);
	seq_printf(m, "Share (unique mount targets): %d\n",
	seq_printf(m, "Share (unique mount targets): %d\n",
			tconInfoAllocCount.counter);
			tconInfoAllocCount.counter);
@@ -430,6 +460,13 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
	list_for_each(tmp1, &cifs_tcp_ses_list) {
	list_for_each(tmp1, &cifs_tcp_ses_list) {
		server = list_entry(tmp1, struct TCP_Server_Info,
		server = list_entry(tmp1, struct TCP_Server_Info,
				    tcp_ses_list);
				    tcp_ses_list);
#ifdef CONFIG_CIFS_STATS2
		for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
			if (atomic_read(&server->smb2slowcmd[j]))
				seq_printf(m, "%d slow responses from %s for command %d\n",
					atomic_read(&server->smb2slowcmd[j]),
					server->hostname, j);
#endif /* STATS2 */
		list_for_each(tmp2, &server->smb_ses_list) {
		list_for_each(tmp2, &server->smb_ses_list) {
			ses = list_entry(tmp2, struct cifs_ses,
			ses = list_entry(tmp2, struct cifs_ses,
					 smb_ses_list);
					 smb_ses_list);
@@ -466,7 +503,6 @@ static const struct file_operations cifs_stats_proc_fops = {
	.release	= single_release,
	.release	= single_release,
	.write		= cifs_stats_proc_write,
	.write		= cifs_stats_proc_write,
};
};
#endif /* STATS */


#ifdef CONFIG_CIFS_SMB_DIRECT
#ifdef CONFIG_CIFS_SMB_DIRECT
#define PROC_FILE_DEFINE(name) \
#define PROC_FILE_DEFINE(name) \
@@ -524,9 +560,7 @@ cifs_proc_init(void)
	proc_create_single("DebugData", 0, proc_fs_cifs,
	proc_create_single("DebugData", 0, proc_fs_cifs,
			cifs_debug_data_proc_show);
			cifs_debug_data_proc_show);


#ifdef CONFIG_CIFS_STATS
	proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_fops);
	proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_fops);
#endif /* STATS */
	proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_fops);
	proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_fops);
	proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_fops);
	proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_fops);
	proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
	proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
@@ -564,9 +598,7 @@ cifs_proc_clean(void)
	remove_proc_entry("DebugData", proc_fs_cifs);
	remove_proc_entry("DebugData", proc_fs_cifs);
	remove_proc_entry("cifsFYI", proc_fs_cifs);
	remove_proc_entry("cifsFYI", proc_fs_cifs);
	remove_proc_entry("traceSMB", proc_fs_cifs);
	remove_proc_entry("traceSMB", proc_fs_cifs);
#ifdef CONFIG_CIFS_STATS
	remove_proc_entry("Stats", proc_fs_cifs);
	remove_proc_entry("Stats", proc_fs_cifs);
#endif
	remove_proc_entry("SecurityFlags", proc_fs_cifs);
	remove_proc_entry("SecurityFlags", proc_fs_cifs);
	remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
	remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
	remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
	remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
Loading