mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
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
...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -603,8 +603,7 @@ DebugData Displays information about active CIFS sessions and
|
||||
shares, features enabled as well as the cifs.ko
|
||||
version.
|
||||
Stats Lists summary resource usage information as well as per
|
||||
share statistics, if CONFIG_CIFS_STATS in enabled
|
||||
in the kernel configuration.
|
||||
share statistics.
|
||||
|
||||
Configuration pseudo-files:
|
||||
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
|
||||
SMB return codes while 4 enables logging of requests that take longer
|
||||
than one second to complete (except for byte range lock requests).
|
||||
Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
|
||||
source code (typically by setting it in the beginning of cifsglob.h),
|
||||
and setting it to seven enables all three. Finally, tracing
|
||||
Setting it to 4 requires CONFIG_CIFS_STATS2 to be set in kernel configuration
|
||||
(.config). Setting it to seven enables all three. Finally, tracing
|
||||
the start of smb requests and responses can be enabled via:
|
||||
|
||||
echo 1 > /proc/fs/cifs/traceSMB
|
||||
|
||||
Per share (per client mount) statistics are available in /proc/fs/cifs/Stats
|
||||
if the kernel was configured with cifs statistics enabled. The statistics
|
||||
represent the number of successful (ie non-zero return code from the server)
|
||||
SMB responses to some of the more common commands (open, delete, mkdir etc.).
|
||||
Per share (per client mount) statistics are available in /proc/fs/cifs/Stats.
|
||||
Additional information is available if CONFIG_CIFS_STATS2 is enabled in the
|
||||
kernel configuration (.config). The statistics returned include counters which
|
||||
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
|
||||
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.
|
||||
The statistics for the number of total SMBs and oplock breaks are different in
|
||||
that they represent all for that share, not just those for which the server
|
||||
returned success.
|
||||
Statistics can be reset to zero by "echo 0 > /proc/fs/cifs/Stats" which may be
|
||||
useful if comparing performance of two different scenarios.
|
||||
|
||||
Also note that "cat /proc/fs/cifs/DebugData" will display information about
|
||||
the active sessions and the shares that are mounted.
|
||||
|
||||
+31
-28
@@ -16,24 +16,28 @@ config CIFS
|
||||
select CRYPTO_DES
|
||||
help
|
||||
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
|
||||
to the original dialect, the Server Message Block (SMB) protocol, the
|
||||
native file sharing mechanism for most early PC operating systems.
|
||||
|
||||
The SMB3 protocol is supported by most modern operating systems and
|
||||
NAS appliances (e.g. Samba, Windows 8, Windows 2012, MacOS).
|
||||
The SMB3 protocol is supported by most modern operating systems
|
||||
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
|
||||
later) as well by Samba (which provides excellent CIFS and SMB3
|
||||
server support for Linux and many other operating systems). Limited
|
||||
support for OS/2 and Windows ME and similar very old servers is
|
||||
provided as well.
|
||||
server support for Linux and many other operating systems). Use of
|
||||
dialects older than SMB2.1 is often discouraged on public networks.
|
||||
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
|
||||
support for DFS (hierarchical name space), secure per-user
|
||||
session establishment via Kerberos or NTLM or NTLMv2,
|
||||
safe distributed caching (oplock), optional packet
|
||||
session establishment via Kerberos or NTLM or NTLMv2, RDMA
|
||||
(smbdirect), advanced security features, per-share encryption,
|
||||
directory leases, safe distributed caching (oplock), optional packet
|
||||
signing, Unicode and other internationalization improvements.
|
||||
|
||||
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
|
||||
slightly simpler (compared to CIFS) due to protocol improvements.
|
||||
|
||||
If you need to mount to Samba, 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
|
||||
If you need to mount to Samba, Azure, Macs or Windows from this machine, say Y.
|
||||
|
||||
config CIFS_STATS2
|
||||
bool "Extended statistics"
|
||||
depends on CIFS_STATS
|
||||
depends on CIFS
|
||||
help
|
||||
Enabling this option will allow more detailed statistics on SMB
|
||||
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
|
||||
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
|
||||
bool "Support legacy servers which use weaker LANMAN security"
|
||||
depends on CIFS
|
||||
depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY
|
||||
help
|
||||
Modern CIFS servers including Samba and most Windows versions
|
||||
(since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
|
||||
@@ -186,15 +198,6 @@ config CIFS_NFSD_EXPORT
|
||||
help
|
||||
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
|
||||
bool "SMB Direct support (Experimental)"
|
||||
depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y
|
||||
|
||||
+4
-2
@@ -128,8 +128,10 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
|
||||
|
||||
memset(&auxdata, 0, sizeof(auxdata));
|
||||
auxdata.eof = cifsi->server_eof;
|
||||
auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime);
|
||||
auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime);
|
||||
auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
|
||||
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)
|
||||
return FSCACHE_CHECKAUX_OBSOLETE;
|
||||
|
||||
+49
-17
@@ -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, "Features:");
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
seq_printf(m, " dfs");
|
||||
seq_printf(m, " DFS");
|
||||
#endif
|
||||
#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
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
seq_printf(m, " lanman");
|
||||
seq_printf(m, ",WEAK_PW_HASH");
|
||||
#endif
|
||||
#ifdef CONFIG_CIFS_POSIX
|
||||
seq_printf(m, " posix");
|
||||
seq_printf(m, ",CIFS_POSIX");
|
||||
#endif
|
||||
#ifdef CONFIG_CIFS_UPCALL
|
||||
seq_printf(m, " spnego");
|
||||
seq_printf(m, ",UPCALL(SPNEGO)");
|
||||
#endif
|
||||
#ifdef CONFIG_CIFS_XATTR
|
||||
seq_printf(m, " xattr");
|
||||
seq_printf(m, ",XATTR");
|
||||
#endif
|
||||
#ifdef CONFIG_CIFS_ACL
|
||||
seq_printf(m, " acl");
|
||||
seq_printf(m, ",ACL");
|
||||
#endif
|
||||
seq_putc(m, '\n');
|
||||
seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
|
||||
@@ -259,10 +275,9 @@ skip_rdma:
|
||||
server->credits, server->dialect);
|
||||
if (server->sign)
|
||||
seq_printf(m, " signed");
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
if (server->posix_ext_supported)
|
||||
seq_printf(m, " posix");
|
||||
#endif /* 3.1.1 */
|
||||
|
||||
i++;
|
||||
list_for_each(tmp2, &server->smb_ses_list) {
|
||||
ses = list_entry(tmp2, struct cifs_ses,
|
||||
@@ -350,7 +365,6 @@ skip_rdma:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
static ssize_t cifs_stats_proc_write(struct file *file,
|
||||
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);
|
||||
if (rc == 0) {
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
int i;
|
||||
|
||||
atomic_set(&totBufAllocCount, 0);
|
||||
atomic_set(&totSmBufAllocCount, 0);
|
||||
#endif /* CONFIG_CIFS_STATS2 */
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
GlobalMaxActiveXid = 0;
|
||||
GlobalCurrentXid = 0;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each(tmp1, &cifs_tcp_ses_list) {
|
||||
server = list_entry(tmp1, struct TCP_Server_Info,
|
||||
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) {
|
||||
ses = list_entry(tmp2, struct cifs_ses,
|
||||
smb_ses_list);
|
||||
@@ -379,6 +403,10 @@ static ssize_t cifs_stats_proc_write(struct file *file,
|
||||
struct cifs_tcon,
|
||||
tcon_list);
|
||||
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)
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
int j;
|
||||
#endif /* STATS2 */
|
||||
struct list_head *tmp1, *tmp2, *tmp3;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
seq_printf(m,
|
||||
"Resources in use\nCIFS Session: %d\n",
|
||||
seq_printf(m, "Resources in use\nCIFS Session: %d\n",
|
||||
sesInfoAllocCount.counter);
|
||||
seq_printf(m, "Share (unique mount targets): %d\n",
|
||||
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) {
|
||||
server = list_entry(tmp1, struct TCP_Server_Info,
|
||||
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) {
|
||||
ses = list_entry(tmp2, struct cifs_ses,
|
||||
smb_ses_list);
|
||||
@@ -466,7 +503,6 @@ static const struct file_operations cifs_stats_proc_fops = {
|
||||
.release = single_release,
|
||||
.write = cifs_stats_proc_write,
|
||||
};
|
||||
#endif /* STATS */
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
#define PROC_FILE_DEFINE(name) \
|
||||
@@ -524,9 +560,7 @@ cifs_proc_init(void)
|
||||
proc_create_single("DebugData", 0, proc_fs_cifs,
|
||||
cifs_debug_data_proc_show);
|
||||
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
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("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_fops);
|
||||
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("cifsFYI", proc_fs_cifs);
|
||||
remove_proc_entry("traceSMB", proc_fs_cifs);
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
remove_proc_entry("Stats", proc_fs_cifs);
|
||||
#endif
|
||||
remove_proc_entry("SecurityFlags", proc_fs_cifs);
|
||||
remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
|
||||
remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
|
||||
|
||||
@@ -83,7 +83,13 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
|
||||
|
||||
kaddr = (char *) kmap(rqst->rq_pages[i]) + offset;
|
||||
|
||||
crypto_shash_update(shash, kaddr, len);
|
||||
rc = crypto_shash_update(shash, kaddr, len);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: Could not update with payload\n",
|
||||
__func__);
|
||||
kunmap(rqst->rq_pages[i]);
|
||||
return rc;
|
||||
}
|
||||
|
||||
kunmap(rqst->rq_pages[i]);
|
||||
}
|
||||
@@ -452,7 +458,7 @@ find_timestamp(struct cifs_ses *ses)
|
||||
unsigned char *blobptr;
|
||||
unsigned char *blobend;
|
||||
struct ntlmssp2_name *attrptr;
|
||||
struct timespec ts;
|
||||
struct timespec64 ts;
|
||||
|
||||
if (!ses->auth_key.len || !ses->auth_key.response)
|
||||
return 0;
|
||||
@@ -477,7 +483,7 @@ find_timestamp(struct cifs_ses *ses)
|
||||
blobptr += attrsize; /* advance attr value */
|
||||
}
|
||||
|
||||
ktime_get_real_ts(&ts);
|
||||
ktime_get_real_ts64(&ts);
|
||||
return cpu_to_le64(cifs_UnixTimeToNT(ts));
|
||||
}
|
||||
|
||||
|
||||
+16
-17
@@ -139,6 +139,9 @@ cifs_read_super(struct super_block *sb)
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
|
||||
sb->s_flags |= SB_POSIXACL;
|
||||
|
||||
if (tcon->snapshot_time)
|
||||
sb->s_flags |= SB_RDONLY;
|
||||
|
||||
if (tcon->ses->capabilities & tcon->ses->server->vals->cap_large_files)
|
||||
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
||||
else
|
||||
@@ -209,14 +212,16 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
/*
|
||||
* PATH_MAX may be too long - it would presumably be total path,
|
||||
* but note that some servers (includinng Samba 3) have a shorter
|
||||
* maximum path.
|
||||
*
|
||||
* Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO.
|
||||
*/
|
||||
buf->f_namelen = PATH_MAX;
|
||||
if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
|
||||
buf->f_namelen =
|
||||
le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength);
|
||||
else
|
||||
buf->f_namelen = PATH_MAX;
|
||||
|
||||
buf->f_fsid.val[0] = tcon->vol_serial_number;
|
||||
/* are using part of create time for more randomness, see man statfs */
|
||||
buf->f_fsid.val[1] = (int)le64_to_cpu(tcon->vol_create_time);
|
||||
|
||||
buf->f_files = 0; /* undefined */
|
||||
buf->f_ffree = 0; /* unlimited */
|
||||
|
||||
@@ -427,7 +432,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
else if (tcon->ses->user_name)
|
||||
seq_show_option(s, "username", tcon->ses->user_name);
|
||||
|
||||
if (tcon->ses->domainName)
|
||||
if (tcon->ses->domainName && tcon->ses->domainName[0] != 0)
|
||||
seq_show_option(s, "domain", tcon->ses->domainName);
|
||||
|
||||
if (srcaddr->sa_family != AF_UNSPEC) {
|
||||
@@ -481,20 +486,12 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
seq_puts(s, ",persistenthandles");
|
||||
else if (tcon->use_resilient)
|
||||
seq_puts(s, ",resilienthandles");
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
if (tcon->posix_extensions)
|
||||
seq_puts(s, ",posix");
|
||||
else if (tcon->unix_ext)
|
||||
seq_puts(s, ",unix");
|
||||
else
|
||||
seq_puts(s, ",nounix");
|
||||
#else
|
||||
if (tcon->unix_ext)
|
||||
seq_puts(s, ",unix");
|
||||
else
|
||||
seq_puts(s, ",nounix");
|
||||
#endif /* SMB311 */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_puts(s, ",posixpaths");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
|
||||
@@ -546,6 +543,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
seq_printf(s, ",wsize=%u", cifs_sb->wsize);
|
||||
seq_printf(s, ",echo_interval=%lu",
|
||||
tcon->ses->server->echo_interval / HZ);
|
||||
if (tcon->snapshot_time)
|
||||
seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
|
||||
/* convert actimeo and display it in seconds */
|
||||
seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
|
||||
|
||||
|
||||
+13
-41
@@ -76,6 +76,9 @@
|
||||
#define SMB_ECHO_INTERVAL_MAX 600
|
||||
#define SMB_ECHO_INTERVAL_DEFAULT 60
|
||||
|
||||
/* maximum number of PDUs in one compound */
|
||||
#define MAX_COMPOUND 5
|
||||
|
||||
/*
|
||||
* Default number of credits to keep available for SMB3.
|
||||
* This value is chosen somewhat arbitrarily. The Windows client
|
||||
@@ -191,9 +194,7 @@ enum smb_version {
|
||||
Smb_21,
|
||||
Smb_30,
|
||||
Smb_302,
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
Smb_311,
|
||||
#endif /* SMB311 */
|
||||
Smb_3any,
|
||||
Smb_default,
|
||||
Smb_version_err
|
||||
@@ -456,13 +457,11 @@ struct smb_version_operations {
|
||||
long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
|
||||
loff_t);
|
||||
/* init transform request - used for encryption for now */
|
||||
int (*init_transform_rq)(struct TCP_Server_Info *, struct smb_rqst *,
|
||||
struct smb_rqst *);
|
||||
/* free transform request */
|
||||
void (*free_transform_rq)(struct smb_rqst *);
|
||||
int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst,
|
||||
struct smb_rqst *, struct smb_rqst *);
|
||||
int (*is_transform_hdr)(void *buf);
|
||||
int (*receive_transform)(struct TCP_Server_Info *,
|
||||
struct mid_q_entry **);
|
||||
struct mid_q_entry **, char **, int *);
|
||||
enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
|
||||
enum securityEnum);
|
||||
int (*next_header)(char *);
|
||||
@@ -684,15 +683,14 @@ struct TCP_Server_Info {
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_t in_send; /* requests trying to send */
|
||||
atomic_t num_waiters; /* blocked waiting to get in sendrecv */
|
||||
#endif
|
||||
atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */
|
||||
#endif /* STATS2 */
|
||||
unsigned int max_read;
|
||||
unsigned int max_write;
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
__le16 cipher_type;
|
||||
/* save initital negprot hash */
|
||||
__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
|
||||
bool posix_ext_supported;
|
||||
#endif /* 3.1.1 */
|
||||
struct delayed_work reconnect; /* reconnect workqueue job */
|
||||
struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
|
||||
unsigned long echo_interval;
|
||||
@@ -886,9 +884,7 @@ struct cifs_ses {
|
||||
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
|
||||
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
|
||||
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
|
||||
#endif /* 3.1.1 */
|
||||
|
||||
/*
|
||||
* Network interfaces available on the server this session is
|
||||
@@ -913,6 +909,7 @@ cap_unix(struct cifs_ses *ses)
|
||||
|
||||
struct cached_fid {
|
||||
bool is_valid:1; /* Do we have a useable root fid */
|
||||
struct kref refcount;
|
||||
struct cifs_fid *fid;
|
||||
struct mutex fid_mutex;
|
||||
struct cifs_tcon *tcon;
|
||||
@@ -936,7 +933,6 @@ struct cifs_tcon {
|
||||
__u32 tid; /* The 4 byte tree id */
|
||||
__u16 Flags; /* optional support bits */
|
||||
enum statusEnum tidStatus;
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
atomic_t num_smbs_sent;
|
||||
union {
|
||||
struct {
|
||||
@@ -967,24 +963,9 @@ struct cifs_tcon {
|
||||
atomic_t smb2_com_failed[NUMBER_OF_SMB2_COMMANDS];
|
||||
} smb2_stats;
|
||||
} stats;
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
unsigned long long time_writes;
|
||||
unsigned long long time_reads;
|
||||
unsigned long long time_opens;
|
||||
unsigned long long time_deletes;
|
||||
unsigned long long time_closes;
|
||||
unsigned long long time_mkdirs;
|
||||
unsigned long long time_rmdirs;
|
||||
unsigned long long time_renames;
|
||||
unsigned long long time_t2renames;
|
||||
unsigned long long time_ffirst;
|
||||
unsigned long long time_fnext;
|
||||
unsigned long long time_fclose;
|
||||
#endif /* CONFIG_CIFS_STATS2 */
|
||||
__u64 bytes_read;
|
||||
__u64 bytes_written;
|
||||
spinlock_t stat_lock; /* protects the two fields above */
|
||||
#endif /* CONFIG_CIFS_STATS */
|
||||
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
|
||||
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
|
||||
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
|
||||
@@ -997,9 +978,7 @@ struct cifs_tcon {
|
||||
bool seal:1; /* transport encryption for this mounted share */
|
||||
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
|
||||
for this mount even if server would support */
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
bool posix_extensions; /* if true SMB3.11 posix extensions enabled */
|
||||
#endif /* CIFS_311 */
|
||||
bool local_lease:1; /* check leases (only) on local system not remote */
|
||||
bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
|
||||
bool broken_sparse_sup; /* if server or share does not support sparse */
|
||||
@@ -1046,6 +1025,7 @@ struct tcon_link {
|
||||
};
|
||||
|
||||
extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
|
||||
extern void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst);
|
||||
|
||||
static inline struct cifs_tcon *
|
||||
tlink_tcon(struct tcon_link *tlink)
|
||||
@@ -1352,7 +1332,6 @@ convert_delimiter(char *path, char delim)
|
||||
*pos = delim;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
#define cifs_stats_inc atomic_inc
|
||||
|
||||
static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
|
||||
@@ -1372,13 +1351,6 @@ static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
|
||||
tcon->bytes_read += bytes;
|
||||
spin_unlock(&tcon->stat_lock);
|
||||
}
|
||||
#else
|
||||
|
||||
#define cifs_stats_inc(field) do {} while (0)
|
||||
#define cifs_stats_bytes_written(tcon, bytes) do {} while (0)
|
||||
#define cifs_stats_bytes_read(tcon, bytes) do {} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -1544,9 +1516,9 @@ struct cifs_fattr {
|
||||
dev_t cf_rdev;
|
||||
unsigned int cf_nlink;
|
||||
unsigned int cf_dtype;
|
||||
struct timespec cf_atime;
|
||||
struct timespec cf_mtime;
|
||||
struct timespec cf_ctime;
|
||||
struct timespec64 cf_atime;
|
||||
struct timespec64 cf_mtime;
|
||||
struct timespec64 cf_ctime;
|
||||
};
|
||||
|
||||
static inline void free_dfs_info_param(struct dfs_info3_param *param)
|
||||
|
||||
+7
-3
@@ -94,6 +94,10 @@ extern int cifs_call_async(struct TCP_Server_Info *server,
|
||||
extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
||||
struct smb_rqst *rqst, int *resp_buf_type,
|
||||
const int flags, struct kvec *resp_iov);
|
||||
extern int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
||||
const int flags, const int num_rqst,
|
||||
struct smb_rqst *rqst, int *resp_buf_type,
|
||||
struct kvec *resp_iov);
|
||||
extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
|
||||
struct smb_hdr * /* input */ ,
|
||||
struct smb_hdr * /* out */ ,
|
||||
@@ -143,9 +147,9 @@ extern enum securityEnum select_sectype(struct TCP_Server_Info *server,
|
||||
enum securityEnum requested);
|
||||
extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
|
||||
const struct nls_table *nls_cp);
|
||||
extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
|
||||
extern u64 cifs_UnixTimeToNT(struct timespec);
|
||||
extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
|
||||
extern struct timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
|
||||
extern u64 cifs_UnixTimeToNT(struct timespec64);
|
||||
extern struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
|
||||
int offset);
|
||||
extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
|
||||
extern int cifs_get_writer(struct cifsInodeInfo *cinode);
|
||||
|
||||
+6
-6
@@ -508,13 +508,13 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
|
||||
* this requirement.
|
||||
*/
|
||||
int val, seconds, remain, result;
|
||||
struct timespec ts;
|
||||
unsigned long utc = ktime_get_real_seconds();
|
||||
struct timespec64 ts;
|
||||
time64_t utc = ktime_get_real_seconds();
|
||||
ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
|
||||
rsp->SrvTime.Time, 0);
|
||||
cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
|
||||
(int)ts.tv_sec, (int)utc,
|
||||
(int)(utc - ts.tv_sec));
|
||||
cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
|
||||
ts.tv_sec, utc,
|
||||
utc - ts.tv_sec);
|
||||
val = (int)(utc - ts.tv_sec);
|
||||
seconds = abs(val);
|
||||
result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
|
||||
@@ -4082,7 +4082,7 @@ QInfRetry:
|
||||
if (rc) {
|
||||
cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
|
||||
} else if (data) {
|
||||
struct timespec ts;
|
||||
struct timespec64 ts;
|
||||
__u32 time = le32_to_cpu(pSMBr->last_write_time);
|
||||
|
||||
/* decode response */
|
||||
|
||||
+66
-43
@@ -303,10 +303,8 @@ static const match_table_t cifs_smb_version_tokens = {
|
||||
{ Smb_21, SMB21_VERSION_STRING },
|
||||
{ Smb_30, SMB30_VERSION_STRING },
|
||||
{ Smb_302, SMB302_VERSION_STRING },
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
{ Smb_311, SMB311_VERSION_STRING },
|
||||
{ Smb_311, ALT_SMB311_VERSION_STRING },
|
||||
#endif /* SMB311 */
|
||||
{ Smb_3any, SMB3ANY_VERSION_STRING },
|
||||
{ Smb_default, SMBDEFAULT_VERSION_STRING },
|
||||
{ Smb_version_err, NULL }
|
||||
@@ -350,6 +348,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
|
||||
server->max_read = 0;
|
||||
|
||||
cifs_dbg(FYI, "Reconnecting tcp session\n");
|
||||
trace_smb3_reconnect(server->CurrentMid, server->hostname);
|
||||
|
||||
/* before reconnecting the tcp session, mark the smb session (uid)
|
||||
and the tid bad so they are not used until reconnected */
|
||||
@@ -851,13 +850,14 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
static int
|
||||
cifs_demultiplex_thread(void *p)
|
||||
{
|
||||
int length;
|
||||
int i, num_mids, length;
|
||||
struct TCP_Server_Info *server = p;
|
||||
unsigned int pdu_length;
|
||||
unsigned int next_offset;
|
||||
char *buf = NULL;
|
||||
struct task_struct *task_to_wake = NULL;
|
||||
struct mid_q_entry *mid_entry;
|
||||
struct mid_q_entry *mids[MAX_COMPOUND];
|
||||
char *bufs[MAX_COMPOUND];
|
||||
|
||||
current->flags |= PF_MEMALLOC;
|
||||
cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
|
||||
@@ -924,58 +924,75 @@ next_pdu:
|
||||
server->pdu_size = next_offset;
|
||||
}
|
||||
|
||||
mid_entry = NULL;
|
||||
memset(mids, 0, sizeof(mids));
|
||||
memset(bufs, 0, sizeof(bufs));
|
||||
num_mids = 0;
|
||||
|
||||
if (server->ops->is_transform_hdr &&
|
||||
server->ops->receive_transform &&
|
||||
server->ops->is_transform_hdr(buf)) {
|
||||
length = server->ops->receive_transform(server,
|
||||
&mid_entry);
|
||||
mids,
|
||||
bufs,
|
||||
&num_mids);
|
||||
} else {
|
||||
mid_entry = server->ops->find_mid(server, buf);
|
||||
mids[0] = server->ops->find_mid(server, buf);
|
||||
bufs[0] = buf;
|
||||
if (mids[0])
|
||||
num_mids = 1;
|
||||
|
||||
if (!mid_entry || !mid_entry->receive)
|
||||
length = standard_receive3(server, mid_entry);
|
||||
if (!mids[0] || !mids[0]->receive)
|
||||
length = standard_receive3(server, mids[0]);
|
||||
else
|
||||
length = mid_entry->receive(server, mid_entry);
|
||||
length = mids[0]->receive(server, mids[0]);
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
if (mid_entry)
|
||||
cifs_mid_q_entry_release(mid_entry);
|
||||
for (i = 0; i < num_mids; i++)
|
||||
if (mids[i])
|
||||
cifs_mid_q_entry_release(mids[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (server->large_buf)
|
||||
buf = server->bigbuf;
|
||||
|
||||
|
||||
server->lstrp = jiffies;
|
||||
if (mid_entry != NULL) {
|
||||
mid_entry->resp_buf_size = server->pdu_size;
|
||||
if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) &&
|
||||
mid_entry->mid_state == MID_RESPONSE_RECEIVED &&
|
||||
server->ops->handle_cancelled_mid)
|
||||
server->ops->handle_cancelled_mid(
|
||||
mid_entry->resp_buf,
|
||||
|
||||
for (i = 0; i < num_mids; i++) {
|
||||
if (mids[i] != NULL) {
|
||||
mids[i]->resp_buf_size = server->pdu_size;
|
||||
if ((mids[i]->mid_flags & MID_WAIT_CANCELLED) &&
|
||||
mids[i]->mid_state == MID_RESPONSE_RECEIVED &&
|
||||
server->ops->handle_cancelled_mid)
|
||||
server->ops->handle_cancelled_mid(
|
||||
mids[i]->resp_buf,
|
||||
server);
|
||||
|
||||
if (!mid_entry->multiRsp || mid_entry->multiEnd)
|
||||
mid_entry->callback(mid_entry);
|
||||
if (!mids[i]->multiRsp || mids[i]->multiEnd)
|
||||
mids[i]->callback(mids[i]);
|
||||
|
||||
cifs_mid_q_entry_release(mid_entry);
|
||||
} else if (server->ops->is_oplock_break &&
|
||||
server->ops->is_oplock_break(buf, server)) {
|
||||
cifs_dbg(FYI, "Received oplock break\n");
|
||||
} else {
|
||||
cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
|
||||
atomic_read(&midCount));
|
||||
cifs_dump_mem("Received Data is: ", buf,
|
||||
HEADER_SIZE(server));
|
||||
cifs_mid_q_entry_release(mids[i]);
|
||||
} else if (server->ops->is_oplock_break &&
|
||||
server->ops->is_oplock_break(bufs[i],
|
||||
server)) {
|
||||
cifs_dbg(FYI, "Received oplock break\n");
|
||||
} else {
|
||||
cifs_dbg(VFS, "No task to wake, unknown frame "
|
||||
"received! NumMids %d\n",
|
||||
atomic_read(&midCount));
|
||||
cifs_dump_mem("Received Data is: ", bufs[i],
|
||||
HEADER_SIZE(server));
|
||||
#ifdef CONFIG_CIFS_DEBUG2
|
||||
if (server->ops->dump_detail)
|
||||
server->ops->dump_detail(buf, server);
|
||||
cifs_dump_mids(server);
|
||||
if (server->ops->dump_detail)
|
||||
server->ops->dump_detail(bufs[i],
|
||||
server);
|
||||
cifs_dump_mids(server);
|
||||
#endif /* CIFS_DEBUG2 */
|
||||
}
|
||||
}
|
||||
|
||||
if (pdu_length > server->pdu_size) {
|
||||
if (!allocate_buffers(server))
|
||||
continue;
|
||||
@@ -1174,6 +1191,7 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
|
||||
switch (match_token(value, cifs_smb_version_tokens, args)) {
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
case Smb_1:
|
||||
if (disable_legacy_dialects) {
|
||||
cifs_dbg(VFS, "mount with legacy dialect disabled\n");
|
||||
@@ -1198,6 +1216,14 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
|
||||
vol->ops = &smb20_operations;
|
||||
vol->vals = &smb20_values;
|
||||
break;
|
||||
#else
|
||||
case Smb_1:
|
||||
cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n");
|
||||
return 1;
|
||||
case Smb_20:
|
||||
cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n");
|
||||
return 1;
|
||||
#endif /* CIFS_ALLOW_INSECURE_LEGACY */
|
||||
case Smb_21:
|
||||
vol->ops = &smb21_operations;
|
||||
vol->vals = &smb21_values;
|
||||
@@ -1210,12 +1236,10 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
|
||||
vol->ops = &smb30_operations; /* currently identical with 3.0 */
|
||||
vol->vals = &smb302_values;
|
||||
break;
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
case Smb_311:
|
||||
vol->ops = &smb311_operations;
|
||||
vol->vals = &smb311_values;
|
||||
break;
|
||||
#endif /* SMB311 */
|
||||
case Smb_3any:
|
||||
vol->ops = &smb30_operations; /* currently identical with 3.0 */
|
||||
vol->vals = &smb3any_values;
|
||||
@@ -3030,15 +3054,17 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
if ((volume_info->linux_ext) && (ses->server->posix_ext_supported)) {
|
||||
if (ses->server->vals->protocol_id == SMB311_PROT_ID) {
|
||||
if (volume_info->linux_ext) {
|
||||
if (ses->server->posix_ext_supported) {
|
||||
tcon->posix_extensions = true;
|
||||
printk_once(KERN_WARNING
|
||||
"SMB3.11 POSIX Extensions are experimental\n");
|
||||
} else {
|
||||
cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions.\n");
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out_fail;
|
||||
}
|
||||
}
|
||||
#endif /* 311 */
|
||||
|
||||
/*
|
||||
* BB Do we need to wrap session_mutex around this TCon call and Unix
|
||||
@@ -3992,11 +4018,9 @@ try_mount_again:
|
||||
goto remote_path_check;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
/* if new SMB3.11 POSIX extensions are supported do not remap / and \ */
|
||||
if (tcon->posix_extensions)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
|
||||
#endif /* SMB3.11 */
|
||||
|
||||
/* tell server which Unix caps we support */
|
||||
if (cap_unix(tcon->ses)) {
|
||||
@@ -4459,11 +4483,10 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
/* if new SMB3.11 POSIX extensions are supported do not remap / and \ */
|
||||
if (tcon->posix_extensions)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
|
||||
#endif /* SMB3.11 */
|
||||
|
||||
if (cap_unix(ses))
|
||||
reset_cifs_unix_caps(0, tcon, NULL, vol_info);
|
||||
|
||||
|
||||
+8
-4
@@ -129,8 +129,10 @@ static void cifs_fscache_acquire_inode_cookie(struct cifsInodeInfo *cifsi,
|
||||
|
||||
memset(&auxdata, 0, sizeof(auxdata));
|
||||
auxdata.eof = cifsi->server_eof;
|
||||
auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime);
|
||||
auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime);
|
||||
auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
|
||||
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;
|
||||
|
||||
cifsi->fscache =
|
||||
fscache_acquire_cookie(tcon->fscache,
|
||||
@@ -166,8 +168,10 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
|
||||
if (cifsi->fscache) {
|
||||
memset(&auxdata, 0, sizeof(auxdata));
|
||||
auxdata.eof = cifsi->server_eof;
|
||||
auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime);
|
||||
auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime);
|
||||
auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
|
||||
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;
|
||||
|
||||
cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
|
||||
fscache_relinquish_cookie(cifsi->fscache, &auxdata, false);
|
||||
|
||||
+5
-3
@@ -31,9 +31,11 @@
|
||||
* Auxiliary data attached to CIFS inode within the cache
|
||||
*/
|
||||
struct cifs_fscache_inode_auxdata {
|
||||
struct timespec last_write_time;
|
||||
struct timespec last_change_time;
|
||||
u64 eof;
|
||||
u64 last_write_time_sec;
|
||||
u64 last_change_time_sec;
|
||||
u32 last_write_time_nsec;
|
||||
u32 last_change_time_nsec;
|
||||
u64 eof;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+18
-20
@@ -95,7 +95,6 @@ static void
|
||||
cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
|
||||
{
|
||||
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
|
||||
struct timespec ts;
|
||||
|
||||
cifs_dbg(FYI, "%s: revalidating inode %llu\n",
|
||||
__func__, cifs_i->uniqueid);
|
||||
@@ -114,8 +113,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
|
||||
}
|
||||
|
||||
/* revalidate if mtime or size have changed */
|
||||
ts = timespec64_to_timespec(inode->i_mtime);
|
||||
if (timespec_equal(&ts, &fattr->cf_mtime) &&
|
||||
if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) &&
|
||||
cifs_i->server_eof == fattr->cf_eof) {
|
||||
cifs_dbg(FYI, "%s: inode %llu is unchanged\n",
|
||||
__func__, cifs_i->uniqueid);
|
||||
@@ -164,9 +162,9 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
|
||||
cifs_revalidate_cache(inode, fattr);
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_atime = timespec_to_timespec64(fattr->cf_atime);
|
||||
inode->i_mtime = timespec_to_timespec64(fattr->cf_mtime);
|
||||
inode->i_ctime = timespec_to_timespec64(fattr->cf_ctime);
|
||||
inode->i_atime = fattr->cf_atime;
|
||||
inode->i_mtime = fattr->cf_mtime;
|
||||
inode->i_ctime = fattr->cf_ctime;
|
||||
inode->i_rdev = fattr->cf_rdev;
|
||||
cifs_nlink_fattr_to_inode(inode, fattr);
|
||||
inode->i_uid = fattr->cf_uid;
|
||||
@@ -327,8 +325,8 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
|
||||
fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
|
||||
fattr->cf_uid = cifs_sb->mnt_uid;
|
||||
fattr->cf_gid = cifs_sb->mnt_gid;
|
||||
ktime_get_real_ts(&fattr->cf_mtime);
|
||||
fattr->cf_mtime = timespec_trunc(fattr->cf_mtime, sb->s_time_gran);
|
||||
ktime_get_real_ts64(&fattr->cf_mtime);
|
||||
fattr->cf_mtime = timespec64_trunc(fattr->cf_mtime, sb->s_time_gran);
|
||||
fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
|
||||
fattr->cf_nlink = 2;
|
||||
fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
|
||||
@@ -604,8 +602,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
|
||||
if (info->LastAccessTime)
|
||||
fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
|
||||
else {
|
||||
ktime_get_real_ts(&fattr->cf_atime);
|
||||
fattr->cf_atime = timespec_trunc(fattr->cf_atime, sb->s_time_gran);
|
||||
ktime_get_real_ts64(&fattr->cf_atime);
|
||||
fattr->cf_atime = timespec64_trunc(fattr->cf_atime, sb->s_time_gran);
|
||||
}
|
||||
|
||||
fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
|
||||
@@ -1122,17 +1120,19 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
|
||||
if (!server->ops->set_file_info)
|
||||
return -ENOSYS;
|
||||
|
||||
info_buf.Pad = 0;
|
||||
|
||||
if (attrs->ia_valid & ATTR_ATIME) {
|
||||
set_time = true;
|
||||
info_buf.LastAccessTime =
|
||||
cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime)));
|
||||
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
|
||||
} else
|
||||
info_buf.LastAccessTime = 0;
|
||||
|
||||
if (attrs->ia_valid & ATTR_MTIME) {
|
||||
set_time = true;
|
||||
info_buf.LastWriteTime =
|
||||
cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime)));
|
||||
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
|
||||
} else
|
||||
info_buf.LastWriteTime = 0;
|
||||
|
||||
@@ -1145,7 +1145,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
|
||||
if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
|
||||
cifs_dbg(FYI, "CIFS - CTIME changed\n");
|
||||
info_buf.ChangeTime =
|
||||
cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime)));
|
||||
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
|
||||
} else
|
||||
info_buf.ChangeTime = 0;
|
||||
|
||||
@@ -1577,14 +1577,12 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
|
||||
|
||||
server = tcon->ses->server;
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
if ((server->ops->posix_mkdir) && (tcon->posix_extensions)) {
|
||||
rc = server->ops->posix_mkdir(xid, inode, mode, tcon, full_path,
|
||||
cifs_sb);
|
||||
d_drop(direntry); /* for time being always refresh inode info */
|
||||
goto mkdir_out;
|
||||
}
|
||||
#endif /* SMB311 */
|
||||
|
||||
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
||||
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
||||
@@ -2071,8 +2069,8 @@ int cifs_getattr(const struct path *path, struct kstat *stat,
|
||||
/* old CIFS Unix Extensions doesn't return create time */
|
||||
if (CIFS_I(inode)->createtime) {
|
||||
stat->result_mask |= STATX_BTIME;
|
||||
stat->btime = timespec_to_timespec64(
|
||||
cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime)));
|
||||
stat->btime =
|
||||
cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime));
|
||||
}
|
||||
|
||||
stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED);
|
||||
@@ -2278,17 +2276,17 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
||||
args->gid = INVALID_GID; /* no change */
|
||||
|
||||
if (attrs->ia_valid & ATTR_ATIME)
|
||||
args->atime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime));
|
||||
args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
|
||||
else
|
||||
args->atime = NO_CHANGE_64;
|
||||
|
||||
if (attrs->ia_valid & ATTR_MTIME)
|
||||
args->mtime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime));
|
||||
args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
|
||||
else
|
||||
args->mtime = NO_CHANGE_64;
|
||||
|
||||
if (attrs->ia_valid & ATTR_CTIME)
|
||||
args->ctime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime));
|
||||
args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
|
||||
else
|
||||
args->ctime = NO_CHANGE_64;
|
||||
|
||||
|
||||
+2
-2
@@ -396,7 +396,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_io_parms io_parms;
|
||||
int buf_type = CIFS_NO_BUFFER;
|
||||
__le16 *utf16_path;
|
||||
__u8 oplock = SMB2_OPLOCK_LEVEL_II;
|
||||
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
struct smb2_file_all_info *pfile_info = NULL;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
@@ -459,7 +459,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_io_parms io_parms;
|
||||
int create_options = CREATE_NOT_DIR;
|
||||
__le16 *utf16_path;
|
||||
__u8 oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
|
||||
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
struct kvec iov[2];
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
|
||||
@@ -122,9 +122,7 @@ tconInfoAlloc(void)
|
||||
mutex_init(&ret_buf->crfid.fid_mutex);
|
||||
ret_buf->crfid.fid = kzalloc(sizeof(struct cifs_fid),
|
||||
GFP_KERNEL);
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
spin_lock_init(&ret_buf->stat_lock);
|
||||
#endif
|
||||
}
|
||||
return ret_buf;
|
||||
}
|
||||
|
||||
+10
-9
@@ -918,10 +918,10 @@ smbCalcSize(void *buf, struct TCP_Server_Info *server)
|
||||
* Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
|
||||
* into Unix UTC (based 1970-01-01, in seconds).
|
||||
*/
|
||||
struct timespec
|
||||
struct timespec64
|
||||
cifs_NTtimeToUnix(__le64 ntutc)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct timespec64 ts;
|
||||
/* BB what about the timezone? BB */
|
||||
|
||||
/* Subtract the NTFS time offset, then convert to 1s intervals. */
|
||||
@@ -935,12 +935,12 @@ cifs_NTtimeToUnix(__le64 ntutc)
|
||||
*/
|
||||
if (t < 0) {
|
||||
abs_t = -t;
|
||||
ts.tv_nsec = (long)(do_div(abs_t, 10000000) * 100);
|
||||
ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
|
||||
ts.tv_nsec = -ts.tv_nsec;
|
||||
ts.tv_sec = -abs_t;
|
||||
} else {
|
||||
abs_t = t;
|
||||
ts.tv_nsec = (long)do_div(abs_t, 10000000) * 100;
|
||||
ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
|
||||
ts.tv_sec = abs_t;
|
||||
}
|
||||
|
||||
@@ -949,7 +949,7 @@ cifs_NTtimeToUnix(__le64 ntutc)
|
||||
|
||||
/* Convert the Unix UTC into NT UTC. */
|
||||
u64
|
||||
cifs_UnixTimeToNT(struct timespec t)
|
||||
cifs_UnixTimeToNT(struct timespec64 t)
|
||||
{
|
||||
/* Convert to 100ns intervals and then add the NTFS time offset. */
|
||||
return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
|
||||
@@ -959,10 +959,11 @@ static const int total_days_of_prev_months[] = {
|
||||
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
||||
};
|
||||
|
||||
struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
|
||||
struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
|
||||
{
|
||||
struct timespec ts;
|
||||
int sec, min, days, month, year;
|
||||
struct timespec64 ts;
|
||||
time64_t sec;
|
||||
int min, days, month, year;
|
||||
u16 date = le16_to_cpu(le_date);
|
||||
u16 time = le16_to_cpu(le_time);
|
||||
SMB_TIME *st = (SMB_TIME *)&time;
|
||||
@@ -973,7 +974,7 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
|
||||
sec = 2 * st->TwoSeconds;
|
||||
min = st->Minutes;
|
||||
if ((sec > 59) || (min > 59))
|
||||
cifs_dbg(VFS, "illegal time min %d sec %d\n", min, sec);
|
||||
cifs_dbg(VFS, "illegal time min %d sec %lld\n", min, sec);
|
||||
sec += (min * 60);
|
||||
sec += 60 * 60 * st->Hours;
|
||||
if (st->Hours > 24)
|
||||
|
||||
@@ -624,7 +624,6 @@ cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
static void
|
||||
cifs_clear_stats(struct cifs_tcon *tcon)
|
||||
{
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
atomic_set(&tcon->stats.cifs_stats.num_writes, 0);
|
||||
atomic_set(&tcon->stats.cifs_stats.num_reads, 0);
|
||||
atomic_set(&tcon->stats.cifs_stats.num_flushes, 0);
|
||||
@@ -646,13 +645,11 @@ cifs_clear_stats(struct cifs_tcon *tcon)
|
||||
atomic_set(&tcon->stats.cifs_stats.num_locks, 0);
|
||||
atomic_set(&tcon->stats.cifs_stats.num_acl_get, 0);
|
||||
atomic_set(&tcon->stats.cifs_stats.num_acl_set, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
|
||||
{
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
seq_printf(m, " Oplocks breaks: %d",
|
||||
atomic_read(&tcon->stats.cifs_stats.num_oplock_brks));
|
||||
seq_printf(m, "\nReads: %d Bytes: %llu",
|
||||
@@ -684,7 +681,6 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
|
||||
atomic_read(&tcon->stats.cifs_stats.num_ffirst),
|
||||
atomic_read(&tcon->stats.cifs_stats.num_fnext),
|
||||
atomic_read(&tcon->stats.cifs_stats.num_fclose));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+4
-2
@@ -120,7 +120,9 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
break;
|
||||
}
|
||||
|
||||
if (use_cached_root_handle == false)
|
||||
if (use_cached_root_handle)
|
||||
close_shroot(&tcon->crfid);
|
||||
else
|
||||
rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
|
||||
if (tmprc)
|
||||
rc = tmprc;
|
||||
@@ -281,7 +283,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
|
||||
int rc;
|
||||
|
||||
if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
|
||||
(buf->LastWriteTime == 0) && (buf->ChangeTime) &&
|
||||
(buf->LastWriteTime == 0) && (buf->ChangeTime == 0) &&
|
||||
(buf->Attributes == 0))
|
||||
return 0; /* would be a no op, no sense sending this */
|
||||
|
||||
|
||||
+3
-10
@@ -93,7 +93,6 @@ static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
|
||||
/* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
|
||||
__u32 non_ctxlen)
|
||||
{
|
||||
@@ -127,7 +126,6 @@ static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
|
||||
/* length of negcontexts including pad from end of sec blob to them */
|
||||
return (len - nc_offset) + size_of_pad_before_neg_ctxts;
|
||||
}
|
||||
#endif /* CIFS_SMB311 */
|
||||
|
||||
int
|
||||
smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
|
||||
@@ -222,10 +220,9 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
|
||||
|
||||
clc_len = smb2_calc_size(buf, srvr);
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
if (shdr->Command == SMB2_NEGOTIATE)
|
||||
clc_len += get_neg_ctxt_len(shdr, len, clc_len);
|
||||
#endif /* SMB311 */
|
||||
|
||||
if (len != clc_len) {
|
||||
cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
|
||||
clc_len, len, mid);
|
||||
@@ -451,15 +448,13 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
|
||||
/* Windows doesn't allow paths beginning with \ */
|
||||
if (from[0] == '\\')
|
||||
start_of_path = from + 1;
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
|
||||
/* SMB311 POSIX extensions paths do not include leading slash */
|
||||
else if (cifs_sb_master_tlink(cifs_sb) &&
|
||||
cifs_sb_master_tcon(cifs_sb)->posix_extensions &&
|
||||
(from[0] == '/')) {
|
||||
start_of_path = from + 1;
|
||||
}
|
||||
#endif /* 311 */
|
||||
else
|
||||
} else
|
||||
start_of_path = from;
|
||||
|
||||
to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
|
||||
@@ -759,7 +754,6 @@ smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB311
|
||||
/**
|
||||
* smb311_update_preauth_hash - update @ses hash with the packet data in @iov
|
||||
*
|
||||
@@ -821,4 +815,3 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user