summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-05 16:40:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-05 16:40:53 -0700
commit3803d5e4d3ce2600ffddc16a1999798bc719042d (patch)
tree4bd971c4931a8f11d9608548bdd7fd304d07881d /fs
parent9daa0a27a0bce6596be287fb1df372ff80bb1087 (diff)
parent331cc667a99c633abbbebeab4675beae713fb331 (diff)
Merge tag '5.8-rc-smb3-fixes-part-1' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French: "22 changesets, 2 for stable. Includes big performance improvement for large i/o when using multichannel, also includes DFS fixes" * tag '5.8-rc-smb3-fixes-part-1' of git://git.samba.org/sfrench/cifs-2.6: (22 commits) cifs: update internal module version number cifs: multichannel: try to rebind when reconnecting a channel cifs: multichannel: use pointer for binding channel smb3: remove static checker warning cifs: multichannel: move channel selection above transport layer cifs: multichannel: always zero struct cifs_io_parms cifs: dump Security Type info in DebugData smb3: fix incorrect number of credits when ioctl MaxOutputResponse > 64K smb3: default to minimum of two channels when multichannel specified cifs: multichannel: move channel selection in function cifs: fix minor typos in comments and log messages smb3: minor update to compression header definitions cifs: minor fix to two debug messages cifs: Standardize logging output smb3: Add new parm "nodelete" cifs: move some variables off the stack in smb2_ioctl_query_info cifs: reduce stack use in smb2_compound_op cifs: get rid of unused parameter in reconn_setup_dfs_targets() cifs: handle hostnames that resolve to same ip in failover cifs: set up next DFS target before generic_ip_connect() ...
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifs_debug.c6
-rw-r--r--fs/cifs/cifs_debug.h145
-rw-r--r--fs/cifs/cifsencrypt.c8
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h20
-rw-r--r--fs/cifs/cifsproto.h36
-rw-r--r--fs/cifs/cifsroot.c6
-rw-r--r--fs/cifs/cifssmb.c81
-rw-r--r--fs/cifs/connect.c130
-rw-r--r--fs/cifs/dfs_cache.c14
-rw-r--r--fs/cifs/file.c60
-rw-r--r--fs/cifs/inode.c17
-rw-r--r--fs/cifs/link.c8
-rw-r--r--fs/cifs/misc.c60
-rw-r--r--fs/cifs/netmisc.c6
-rw-r--r--fs/cifs/readdir.c10
-rw-r--r--fs/cifs/sess.c55
-rw-r--r--fs/cifs/smb1ops.c2
-rw-r--r--fs/cifs/smb2inode.c137
-rw-r--r--fs/cifs/smb2misc.c20
-rw-r--r--fs/cifs/smb2ops.c168
-rw-r--r--fs/cifs/smb2pdu.c499
-rw-r--r--fs/cifs/smb2pdu.h13
-rw-r--r--fs/cifs/smb2proto.h25
-rw-r--r--fs/cifs/smbdirect.c165
-rw-r--r--fs/cifs/transport.c75
27 files changed, 1041 insertions, 729 deletions
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 916567d770f5..3ad1a98fd567 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -221,6 +221,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
struct cifs_ses *ses;
struct cifs_tcon *tcon;
int i, j;
+ const char *security_types[] = {"Unspecified", "LANMAN", "NTLM",
+ "NTLMv2", "RawNTLMSSP", "Kerberos"};
seq_puts(m,
"Display Internal CIFS Data Structures for Debugging\n"
@@ -375,6 +377,10 @@ skip_rdma:
ses->ses_count, ses->serverOS, ses->serverNOS,
ses->capabilities, ses->status);
}
+
+ seq_printf(m,"Security type: %s\n",
+ security_types[server->ops->select_sectype(server, ses->sectype)]);
+
if (server->rdma)
seq_printf(m, "RDMA\n\t");
seq_printf(m, "TCP status: %d Instance: %d\n\tLocal Users To "
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index 100b0056a369..5e66dab712d0 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -8,6 +8,12 @@
#ifndef _H_CIFS_DEBUG
#define _H_CIFS_DEBUG
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+
+#define pr_fmt(fmt) "CIFS: " fmt
+
void cifs_dump_mem(char *label, void *data, int length);
void cifs_dump_detail(void *buf, struct TCP_Server_Info *ptcp_info);
void cifs_dump_mids(struct TCP_Server_Info *);
@@ -46,92 +52,81 @@ extern int cifsFYI;
*/
/* Information level messages, minor events */
-#define cifs_info_func(ratefunc, fmt, ...) \
-do { \
- pr_info_ ## ratefunc("CIFS: " fmt, ##__VA_ARGS__); \
-} while (0)
+#define cifs_info_func(ratefunc, fmt, ...) \
+ pr_info_ ## ratefunc(fmt, ##__VA_ARGS__)
-#define cifs_info(fmt, ...) \
-do { \
- cifs_info_func(ratelimited, fmt, ##__VA_ARGS__); \
-} while (0)
+#define cifs_info(fmt, ...) \
+ cifs_info_func(ratelimited, fmt, ##__VA_ARGS__)
/* information message: e.g., configuration, major event */
-#define cifs_dbg_func(ratefunc, type, fmt, ...) \
-do { \
- if ((type) & FYI && cifsFYI & CIFS_INFO) { \
- pr_debug_ ## ratefunc("%s: " \
- fmt, __FILE__, ##__VA_ARGS__); \
- } else if ((type) & VFS) { \
- pr_err_ ## ratefunc("CIFS VFS: " \
- fmt, ##__VA_ARGS__); \
- } else if ((type) & NOISY && (NOISY != 0)) { \
- pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
- } \
+#define cifs_dbg_func(ratefunc, type, fmt, ...) \
+do { \
+ if ((type) & FYI && cifsFYI & CIFS_INFO) { \
+ pr_debug_ ## ratefunc("%s: " fmt, \
+ __FILE__, ##__VA_ARGS__); \
+ } else if ((type) & VFS) { \
+ pr_err_ ## ratefunc("VFS: " fmt, ##__VA_ARGS__); \
+ } else if ((type) & NOISY && (NOISY != 0)) { \
+ pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
+ } \
} while (0)
-#define cifs_dbg(type, fmt, ...) \
-do { \
- if ((type) & ONCE) \
- cifs_dbg_func(once, \
- type, fmt, ##__VA_ARGS__); \
- else \
- cifs_dbg_func(ratelimited, \
- type, fmt, ##__VA_ARGS__); \
+#define cifs_dbg(type, fmt, ...) \
+do { \
+ if ((type) & ONCE) \
+ cifs_dbg_func(once, type, fmt, ##__VA_ARGS__); \
+ else \
+ cifs_dbg_func(ratelimited, type, fmt, ##__VA_ARGS__); \
} while (0)
-#define cifs_server_dbg_func(ratefunc, type, fmt, ...) \
-do { \
- const char *sn = ""; \
- if (server && server->hostname) \
- sn = server->hostname; \
- if ((type) & FYI && cifsFYI & CIFS_INFO) { \
- pr_debug_ ## ratefunc("%s: \\\\%s " fmt, \
- __FILE__, sn, ##__VA_ARGS__); \
- } else if ((type) & VFS) { \
- pr_err_ ## ratefunc("CIFS VFS: \\\\%s " fmt, \
- sn, ##__VA_ARGS__); \
- } else if ((type) & NOISY && (NOISY != 0)) { \
- pr_debug_ ## ratefunc("\\\\%s " fmt, \
- sn, ##__VA_ARGS__); \
- } \
+#define cifs_server_dbg_func(ratefunc, type, fmt, ...) \
+do { \
+ const char *sn = ""; \
+ if (server && server->hostname) \
+ sn = server->hostname; \
+ if ((type) & FYI && cifsFYI & CIFS_INFO) { \
+ pr_debug_ ## ratefunc("%s: \\\\%s " fmt, \
+ __FILE__, sn, ##__VA_ARGS__); \
+ } else if ((type) & VFS) { \
+ pr_err_ ## ratefunc("VFS: \\\\%s " fmt, \
+ sn, ##__VA_ARGS__); \
+ } else if ((type) & NOISY && (NOISY != 0)) { \
+ pr_debug_ ## ratefunc("\\\\%s " fmt, \
+ sn, ##__VA_ARGS__); \
+ } \
} while (0)
-#define cifs_server_dbg(type, fmt, ...) \
-do { \
- if ((type) & ONCE) \
- cifs_server_dbg_func(once, \
- type, fmt, ##__VA_ARGS__); \
- else \
- cifs_server_dbg_func(ratelimited, \
- type, fmt, ##__VA_ARGS__); \
+#define cifs_server_dbg(type, fmt, ...) \
+do { \
+ if ((type) & ONCE) \
+ cifs_server_dbg_func(once, type, fmt, ##__VA_ARGS__); \
+ else \
+ cifs_server_dbg_func(ratelimited, type, fmt, \
+ ##__VA_ARGS__); \
} while (0)
-#define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \
-do { \
- const char *tn = ""; \
- if (tcon && tcon->treeName) \
- tn = tcon->treeName; \
- if ((type) & FYI && cifsFYI & CIFS_INFO) { \
- pr_debug_ ## ratefunc("%s: %s " fmt, \
- __FILE__, tn, ##__VA_ARGS__); \
- } else if ((type) & VFS) { \
- pr_err_ ## ratefunc("CIFS VFS: %s " fmt, \
- tn, ##__VA_ARGS__); \
- } else if ((type) & NOISY && (NOISY != 0)) { \
- pr_debug_ ## ratefunc("%s " fmt, \
- tn, ##__VA_ARGS__); \
- } \
+#define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \
+do { \
+ const char *tn = ""; \
+ if (tcon && tcon->treeName) \
+ tn = tcon->treeName; \
+ if ((type) & FYI && cifsFYI & CIFS_INFO) { \
+ pr_debug_ ## ratefunc("%s: %s " fmt, \
+ __FILE__, tn, ##__VA_ARGS__); \
+ } else if ((type) & VFS) { \
+ pr_err_ ## ratefunc("VFS: %s " fmt, tn, ##__VA_ARGS__); \
+ } else if ((type) & NOISY && (NOISY != 0)) { \
+ pr_debug_ ## ratefunc("%s " fmt, tn, ##__VA_ARGS__); \
+ } \
} while (0)
-#define cifs_tcon_dbg(type, fmt, ...) \
-do { \
- if ((type) & ONCE) \
- cifs_tcon_dbg_func(once, \
- type, fmt, ##__VA_ARGS__); \
- else \
- cifs_tcon_dbg_func(ratelimited, \
- type, fmt, ##__VA_ARGS__); \
+#define cifs_tcon_dbg(type, fmt, ...) \
+do { \
+ if ((type) & ONCE) \
+ cifs_tcon_dbg_func(once, type, fmt, ##__VA_ARGS__); \
+ else \
+ cifs_tcon_dbg_func(ratelimited, type, fmt, \
+ ##__VA_ARGS__); \
} while (0)
/*
@@ -159,9 +154,7 @@ do { \
} while (0)
#define cifs_info(fmt, ...) \
-do { \
- pr_info("CIFS: "fmt, ##__VA_ARGS__); \
-} while (0)
+ pr_info(fmt, ##__VA_ARGS__)
#endif
#endif /* _H_CIFS_DEBUG */
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 97b7497c13ef..874a551f339c 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -520,7 +520,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
if (rc) {
- cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
+ cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
return rc;
}
@@ -624,7 +624,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
if (rc) {
- cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
+ cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
return rc;
}
@@ -723,7 +723,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
/* calculate ntlmv2_hash */
rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
if (rc) {
- cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
+ cifs_dbg(VFS, "Could not get v2 hash rc %d\n", rc);
goto unlock;
}
@@ -783,7 +783,7 @@ calc_seckey(struct cifs_ses *ses)
ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
if (!ctx_arc4) {
- cifs_dbg(VFS, "could not allocate arc4 context\n");
+ cifs_dbg(VFS, "Could not allocate arc4 context\n");
return -ENOMEM;
}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index c31f362fa098..889f9c71049b 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -534,6 +534,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
seq_puts(s, ",signloosely");
if (tcon->nocase)
seq_puts(s, ",nocase");
+ if (tcon->nodelete)
+ seq_puts(s, ",nodelete");
if (tcon->local_lease)
seq_puts(s, ",locallease");
if (tcon->retry)
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index c9e2e6bbca13..c7a311d28d3d 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -156,5 +156,5 @@ extern int cifs_truncate_page(struct address_space *mapping, loff_t from);
extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */
-#define CIFS_VERSION "2.26"
+#define CIFS_VERSION "2.27"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 39b708d9d86d..e133bb3e172f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -562,6 +562,7 @@ struct smb_vol {
bool override_gid:1;
bool dynperm:1;
bool noperm:1;
+ bool nodelete:1;
bool mode_ace:1;
bool no_psx_acl:1; /* set if posix acl support should be disabled */
bool cifs_acl:1;
@@ -1029,6 +1030,7 @@ struct cifs_ses {
#define CIFS_MAX_CHANNELS 16
struct cifs_chan chans[CIFS_MAX_CHANNELS];
+ struct cifs_chan *binding_chan;
size_t chan_count;
size_t chan_max;
atomic_t chan_seq; /* round robin state */
@@ -1036,23 +1038,31 @@ struct cifs_ses {
/*
* When binding a new channel, we need to access the channel which isn't fully
- * established yet (one past the established count)
+ * established yet.
*/
static inline
struct cifs_chan *cifs_ses_binding_channel(struct cifs_ses *ses)
{
if (ses->binding)
- return &ses->chans[ses->chan_count];
+ return ses->binding_chan;
else
return NULL;
}
+/*
+ * Returns the server pointer of the session. When binding a new
+ * channel this returns the last channel which isn't fully established
+ * yet.
+ *
+ * This function should be use for negprot/sess.setup codepaths. For
+ * the other requests see cifs_pick_channel().
+ */
static inline
struct TCP_Server_Info *cifs_ses_server(struct cifs_ses *ses)
{
if (ses->binding)
- return ses->chans[ses->chan_count].server;
+ return ses->binding_chan->server;
else
return ses->server;
}
@@ -1136,6 +1146,7 @@ struct cifs_tcon {
bool retry:1;
bool nocase:1;
bool nohandlecache:1; /* if strange server resource prob can turn off */
+ bool nodelete:1;
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 */
@@ -1333,6 +1344,7 @@ struct cifs_io_parms {
__u64 offset;
unsigned int length;
struct cifs_tcon *tcon;
+ struct TCP_Server_Info *server;
};
struct cifs_aio_ctx {
@@ -1380,6 +1392,7 @@ struct cifs_readdata {
struct cifs_readdata *rdata,
struct iov_iter *iter);
struct kvec iov[2];
+ struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr;
#endif
@@ -1406,6 +1419,7 @@ struct cifs_writedata {
pid_t pid;
unsigned int bytes;
int result;
+ struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr;
#endif
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 12a895e02db4..bd92070ca30c 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -45,25 +45,25 @@ extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
unsigned int /* length */);
extern unsigned int _get_xid(void);
extern void _free_xid(unsigned int);
-#define get_xid() \
-({ \
+#define get_xid() \
+({ \
unsigned int __xid = _get_xid(); \
- cifs_dbg(FYI, "CIFS VFS: in %s as Xid: %u with uid: %d\n", \
+ cifs_dbg(FYI, "VFS: in %s as Xid: %u with uid: %d\n", \
__func__, __xid, \
from_kuid(&init_user_ns, current_fsuid())); \
- trace_smb3_enter(__xid, __func__); \
- __xid; \
+ trace_smb3_enter(__xid, __func__); \
+ __xid; \
})
-#define free_xid(curr_xid) \
-do { \
- _free_xid(curr_xid); \
- cifs_dbg(FYI, "CIFS VFS: leaving %s (xid = %u) rc = %d\n", \
- __func__, curr_xid, (int)rc); \
- if (rc) \
+#define free_xid(curr_xid) \
+do { \
+ _free_xid(curr_xid); \
+ cifs_dbg(FYI, "VFS: leaving %s (xid = %u) rc = %d\n", \
+ __func__, curr_xid, (int)rc); \
+ if (rc) \
trace_smb3_exit_err(curr_xid, __func__, (int)rc); \
- else \
- trace_smb3_exit_done(curr_xid, __func__); \
+ else \
+ trace_smb3_exit_done(curr_xid, __func__); \
} while (0)
extern int init_cifs_idmap(void);
extern void exit_cifs_idmap(void);
@@ -89,16 +89,20 @@ extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry);
extern void cifs_wake_up_task(struct mid_q_entry *mid);
extern int cifs_handle_standard(struct TCP_Server_Info *server,
struct mid_q_entry *mid);
+extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
extern int cifs_call_async(struct TCP_Server_Info *server,
struct smb_rqst *rqst,
mid_receive_t *receive, mid_callback_t *callback,
mid_handle_t *handle, void *cbdata, const int flags,
const struct cifs_credits *exist_credits);
+extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
+ struct TCP_Server_Info *server,
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,
+ struct TCP_Server_Info *server,
const int flags, const int num_rqst,
struct smb_rqst *rqst, int *resp_buf_type,
struct kvec *resp_iov);
@@ -589,6 +593,8 @@ void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
unsigned int *len, unsigned int *offset);
+struct cifs_chan *
+cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
int cifs_try_adding_channels(struct cifs_ses *ses);
int cifs_ses_add_channel(struct cifs_ses *ses,
struct cifs_server_iface *iface);
@@ -616,6 +622,10 @@ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
return dfs_cache_find(xid, ses, nls_codepage, remap, old_path,
referral, NULL);
}
+
+int match_target_ip(struct TCP_Server_Info *server,
+ const char *share, size_t share_len,
+ bool *result);
#endif
static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
diff --git a/fs/cifs/cifsroot.c b/fs/cifs/cifsroot.c
index 37edbfb8e096..9e91a5a40aae 100644
--- a/fs/cifs/cifsroot.c
+++ b/fs/cifs/cifsroot.c
@@ -56,7 +56,7 @@ static int __init cifs_root_setup(char *line)
/* len is strlen(unc) + '\0' */
len = s - line + 1;
if (len > sizeof(root_dev)) {
- printk(KERN_ERR "Root-CIFS: UNC path too long\n");
+ pr_err("Root-CIFS: UNC path too long\n");
return 1;
}
strlcpy(root_dev, line, len);
@@ -66,7 +66,7 @@ static int __init cifs_root_setup(char *line)
sizeof(root_opts), "%s,%s",
DEFAULT_MNT_OPTS, s + 1);
if (n >= sizeof(root_opts)) {
- printk(KERN_ERR "Root-CIFS: mount options string too long\n");
+ pr_err("Root-CIFS: mount options string too long\n");
root_opts[sizeof(root_opts)-1] = '\0';
return 1;
}
@@ -83,7 +83,7 @@ __setup("cifsroot=", cifs_root_setup);
int __init cifs_root_data(char **dev, char **opts)
{
if (!root_dev[0] || root_server_addr == htonl(INADDR_NONE)) {
- printk(KERN_ERR "Root-CIFS: no SMB server address\n");
+ pr_err("Root-CIFS: no SMB server address\n");
return -1;
}
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 5014a82391ff..bf41ee048396 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -129,6 +129,7 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
struct cifs_tcon *tcon)
{
int rc;
+ struct TCP_Server_Info *server = tcon->ses->server;
struct dfs_cache_tgt_list tl;
struct dfs_cache_tgt_iterator *it = NULL;
char *tree;
@@ -141,15 +142,14 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
if (!tree)
return -ENOMEM;
- if (tcon->ipc) {
- scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
- tcon->ses->server->hostname);
- rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
- goto out;
- }
-
if (!tcon->dfs_path) {
- rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
+ if (tcon->ipc) {
+ scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
+ server->hostname);
+ rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
+ } else {
+ rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
+ }
goto out;
}
@@ -157,13 +157,13 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
if (rc)
goto out;
- extract_unc_hostname(tcon->ses->server->hostname, &tcp_host,
- &tcp_host_len);
+ extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len);
for (it = dfs_cache_get_tgt_iterator(&tl); it;
it = dfs_cache_get_next_tgt(&tl, it)) {
const char *share, *prefix;
size_t share_len, prefix_len;
+ bool target_match;
rc = dfs_cache_get_tgt_share(it, &share, &share_len, &prefix,
&prefix_len);
@@ -177,19 +177,38 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
if (dfs_host_len != tcp_host_len
|| strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
- cifs_dbg(FYI, "%s: skipping %.*s, doesn't match %.*s",
+ cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n",
__func__,
(int)dfs_host_len, dfs_host,
(int)tcp_host_len, tcp_host);
- continue;
- }
- scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len, share);
+ rc = match_target_ip(server, dfs_host, dfs_host_len,
+ &target_match);
+ if (rc) {
+ cifs_dbg(VFS, "%s: failed to match target ip: %d\n",
+ __func__, rc);
+ break;
+ }
+
+ if (!target_match) {
+ cifs_dbg(FYI, "%s: skipping target\n", __func__);
+ continue;
+ }
+ }
- rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
- if (!rc) {
- rc = update_super_prepath(tcon, prefix, prefix_len);
- break;
+ if (tcon->ipc) {
+ scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$",
+ (int)share_len, share);
+ rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
+ } else {
+ scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len,
+ share);
+ rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
+ if (!rc) {
+ rc = update_super_prepath(tcon, prefix,
+ prefix_len);
+ break;
+ }
}
if (rc == -EREMOTE)
break;
@@ -262,8 +281,8 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
(server->tcpStatus != CifsNeedReconnect),
10 * HZ);
if (rc < 0) {
- cifs_dbg(FYI, "%s: aborting reconnect due to a received"
- " signal by the process\n", __func__);
+ cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
+ __func__);
return -ERESTARTSYS;
}
@@ -324,7 +343,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
if (rc) {
- printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
+ pr_warn_once("reconnect tcon failed rc = %d\n", rc);
goto out;
}
@@ -557,7 +576,7 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
/* If server requires signing, does client allow it? */
if (srv_sign_required) {
if (!mnt_sign_enabled) {
- cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
+ cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
return -ENOTSUPP;
}
server->sign = true;
@@ -566,14 +585,14 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
/* If client requires signing, does server allow it? */
if (mnt_sign_required) {
if (!srv_sign_enabled) {
- cifs_dbg(VFS, "Server does not support signing!");
+ cifs_dbg(VFS, "Server does not support signing!\n");
return -ENOTSUPP;
}
server->sign = true;
}
if (cifs_rdma_enabled(server) && server->sign)
- cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
+ cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
return 0;
}
@@ -703,7 +722,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
if (should_set_ext_sec_flag(ses->sectype)) {
- cifs_dbg(FYI, "Requesting extended security.");
+ cifs_dbg(FYI, "Requesting extended security\n");
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
}
@@ -2375,7 +2394,7 @@ int
CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, struct kvec *iov, int n_vec)
{
- int rc = -EACCES;
+ int rc;
WRITE_REQ *pSMB = NULL;
int wct;
int smb_hdr_len;
@@ -3868,7 +3887,7 @@ GetExtAttrRetry:
struct file_chattr_info *pfinfo;
/* BB Do we need a cast or hash here ? */
if (count != 16) {
- cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
+ cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
rc = -EIO;
goto GetExtAttrOut;
}
@@ -4244,7 +4263,7 @@ QFileInfoRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
- cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
+ cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -4411,7 +4430,7 @@ UnixQFileInfoRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
- cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
+ cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -4493,7 +4512,7 @@ UnixQPathInfoRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
- cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
+ cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -4913,7 +4932,7 @@ GetInodeNumberRetry:
struct file_internal_info *pfinfo;
/* BB Do we need a cast or hash here ? */
if (count < 8) {
- cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
+ cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
rc = -EIO;
goto GetInodeNumOut;
}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index ad8fb53b3682..5fac34f192af 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -75,7 +75,7 @@ enum {
Opt_forceuid, Opt_noforceuid,
Opt_forcegid, Opt_noforcegid,
Opt_noblocksend, Opt_noautotune, Opt_nolease,
- Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
+ Opt_hard, Opt_soft, Opt_perm, Opt_noperm, Opt_nodelete,
Opt_mapposix, Opt_nomapposix,
Opt_mapchars, Opt_nomapchars, Opt_sfu,
Opt_nosfu, Opt_nodfs, Opt_posixpaths,
@@ -141,6 +141,7 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_soft, "soft" },
{ Opt_perm, "perm" },
{ Opt_noperm, "noperm" },
+ { Opt_nodelete, "nodelete" },
{ Opt_mapchars, "mapchars" }, /* SFU style */
{ Opt_nomapchars, "nomapchars" },
{ Opt_mapposix, "mapposix" }, /* SFM style */
@@ -426,8 +427,7 @@ static void reconn_inval_dfs_target(struct TCP_Server_Info *server,
}
static inline int reconn_setup_dfs_targets(struct cifs_sb_info *cifs_sb,
- struct dfs_cache_tgt_list *tl,
- struct dfs_cache_tgt_iterator **it)
+ struct dfs_cache_tgt_list *tl)
{
if (!cifs_sb->origin_fullpath)
return -EOPNOTSUPP;
@@ -472,7 +472,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} else {
cifs_sb = CIFS_SB(sb);
- rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it);
+ rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list);
if (rc && (rc != -EOPNOTSUPP)) {
cifs_server_dbg(VFS, "%s: no target servers for DFS failover\n",
__func__);
@@ -572,26 +572,26 @@ cifs_reconnect(struct TCP_Server_Info *server)
try_to_freeze();
mutex_lock(&server->srv_mutex);
+#ifdef CONFIG_CIFS_DFS_UPCALL
/*
* Set up next DFS target server (if any) for reconnect. If DFS
* feature is disabled, then we will retry last server we
* connected to before.
*/
+ reconn_inval_dfs_target(server, cifs_sb, &tgt_list, &tgt_it);
+#endif
+ rc = reconn_set_ipaddr(server);
+ if (rc) {
+ cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
+ __func__, rc);
+ }
+
if (cifs_rdma_enabled(server))
rc = smbd_reconnect(server);
else
rc = generic_ip_connect(server);
if (rc) {
cifs_dbg(FYI, "reconnect error %d\n", rc);
-#ifdef CONFIG_CIFS_DFS_UPCALL
- reconn_inval_dfs_target(server, cifs_sb, &tgt_list,
- &tgt_it);
-#endif
- rc = reconn_set_ipaddr(server);
- if (rc) {
- cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
- __func__, rc);
- }
mutex_unlock(&server->srv_mutex);
msleep(3000);
} else {
@@ -879,8 +879,7 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
* function has finished processing it is a bug.
*/
if (mid->mid_flags & MID_DELETED)
- printk_once(KERN_WARNING
- "trying to dequeue a deleted mid\n");
+ pr_warn_once("trying to dequeue a deleted mid\n");
else {
list_del_init(&mid->qhead);
mid->mid_flags |= MID_DELETED;
@@ -1229,9 +1228,8 @@ next_pdu:
smb2_add_credits_from_hdr(bufs[i], server);
cifs_dbg(FYI, "Received oplock break\n");
} else {
- cifs_server_dbg(VFS, "No task to wake, unknown frame "
- "received! NumMids %d\n",
- atomic_read(&midCount));
+ cifs_server_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));
smb2_add_credits_from_hdr(bufs[i], server);
@@ -1476,9 +1474,7 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
return 1;
}
- cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 "
- "is not recommended unless required for "
- "access to very old servers\n");
+ cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
vol->ops = &smb1_operations;
vol->vals = &smb1_values;
break;
@@ -1545,7 +1541,7 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
size_t len;
if (unlikely(!devname || !*devname)) {
- cifs_dbg(VFS, "Device name not specified.\n");
+ cifs_dbg(VFS, "Device name not specified\n");
return -EINVAL;
}
@@ -1695,13 +1691,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
case 0:
break;
case -ENOMEM:
- cifs_dbg(VFS, "Unable to allocate memory for devname.\n");
+ cifs_dbg(VFS, "Unable to allocate memory for devname\n");
goto cifs_parse_mount_err;
case -EINVAL:
- cifs_dbg(VFS, "Malformed UNC in devname.\n");
+ cifs_dbg(VFS, "Malformed UNC in devname\n");
goto cifs_parse_mount_err;
default:
- cifs_dbg(VFS, "Unknown error parsing devname.\n");
+ cifs_dbg(VFS, "Unknown error parsing devname\n");
goto cifs_parse_mount_err;
}