From 8fd6e1d6941ce623ae62420d264c1b5505971b2b Mon Sep 17 00:00:00 2001 From: Kenneth D'souza Date: Mon, 18 May 2020 13:01:34 +0530 Subject: cifs: handle "nolease" option for vers=1.0 The "nolease" mount option is only supported for SMB2+ mounts. Fail with appropriate error message if vers=1.0 option is passed. Signed-off-by: Kenneth D'souza Reviewed-by: Pavel Shilovsky Signed-off-by: Steve French --- fs/cifs/connect.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'fs/cifs') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 28268ed461b8..62503fbed2ab 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3580,6 +3580,16 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n"); } + if (volume_info->no_lease) { + if (ses->server->vals->protocol_id == 0) { + cifs_dbg(VFS, + "SMB2 or later required for nolease option\n"); + rc = -EOPNOTSUPP; + goto out_fail; + } else + tcon->no_lease = volume_info->no_lease; + } + /* * We can have only one retry value for a connection to a share so for * resources mounted more than once to the same server share the last @@ -3589,7 +3599,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) tcon->nocase = volume_info->nocase; tcon->nohandlecache = volume_info->nohandlecache; tcon->local_lease = volume_info->local_lease; - tcon->no_lease = volume_info->no_lease; INIT_LIST_HEAD(&tcon->pending_opens); spin_lock(&cifs_tcp_ses_lock); -- cgit v1.2.3 From 136a5dc3309a53ee830cd649961d70c8bec55f38 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 27 May 2020 13:50:31 +0100 Subject: cifs: remove redundant initialization of variable rc The variable rc is being initialized with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/cifs') diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5014a82391ff..d62f9175c546 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2375,7 +2375,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; -- cgit v1.2.3 From aaa3aef34d3ab9499a5c7633823429f7a24e6dff Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 19 May 2020 15:38:27 -0300 Subject: cifs: set up next DFS target before generic_ip_connect() If we mount a very specific DFS link \\FS0.FOO.COM\dfs\link -> \FS0\share1, \FS1\share2 where its target list contains NB names ("FS0" & "FS1") rather than FQDN ones ("FS0.FOO.COM" & "FS1.FOO.COM"), we end up connecting to \FOO\share1 but server->hostname will have "FOO.COM". The reason is because both "FS0" and "FS0.FOO.COM" resolve to same IP address and they share same TCP server connection, but "FS0.FOO.COM" was the first hostname set -- which is OK. However, if the echo thread timeouts and we still have a good connection to "FS0", in cifs_reconnect() rc = generic_ip_connect(server) -> success if (rc) { ... reconn_inval_dfs_target(server, cifs_sb, &tgt_list, &tgt_it); ... } ... it successfully reconnects to "FS0" server but does not set up next DFS target - which should be the same target server "\FS0\share1" - and server->hostname remains set to "FS0.FOO.COM" rather than "FS0", as reconn_inval_dfs_target() would have it set to "FS0" if called earlier. Finally, in __smb2_reconnect(), the reconnect of tcons would fail because tcon->ses->server->hostname (FS0.FOO.COM) does not match DFS target's hostname (FS0). Fix that by calling reconn_inval_dfs_target() before generic_ip_connect() so server->hostname will get updated correctly prior to reconnecting its tcons in __smb2_reconnect(). With "cifs: handle hostnames that resolve to same ip in failover" patch - The above problem would not occur. - We could save an DNS query to find out that they both resolve to the same ip address. Signed-off-by: Paulo Alcantara (SUSE) Reviewed-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/connect.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 62503fbed2ab..aa1173f3fb12 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -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 { -- cgit v1.2.3 From e4af35fa55b072190711c11e2bfff8326d313948 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 19 May 2020 15:38:28 -0300 Subject: cifs: handle hostnames that resolve to same ip in failover In order to support reconnect to hostnames that resolve to same ip address, besides relying on the currently set hostname to match DFS targets, attempt to resolve the targets and then match their addresses with the reconnected server ip address. For instance, if we have two hostnames "FOO" and "BAR", and both resolve to the same ip address, we would be able to handle failover in DFS paths like \\FOO\dfs\link1 -> [ \BAZ\share2 (*), \BAR\share1 ] \\FOO\dfs\link2 -> [ \BAZ\share2 (*), \FOO\share1 ] so when "BAZ" is no longer accessible, link1 and link2 would get reconnected despite having different target hostnames. Signed-off-by: Paulo Alcantara (SUSE) Reviewed-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 5 +++++ fs/cifs/cifssmb.c | 55 +++++++++++++++++++++++++++++++++++----------------- fs/cifs/connect.c | 6 +++--- fs/cifs/misc.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb2pdu.c | 56 ++++++++++++++++++++++++++++++++++++----------------- 5 files changed, 131 insertions(+), 39 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 12a895e02db4..311d8e86c5a8 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -89,6 +89,7 @@ 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, @@ -616,6 +617,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/cifssmb.c b/fs/cifs/cifssmb.c index d62f9175c546..5a684f9ac883 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", __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; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index aa1173f3fb12..ea3189a6ae10 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2496,8 +2496,8 @@ cifs_parse_mount_err: * specified, or if srcaddr is specified and * matches the IP address of the rhs argument. */ -static bool -srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs) +bool +cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs) { switch (srcaddr->sa_family) { case AF_UNSPEC: @@ -2588,7 +2588,7 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr, return false; /* don't expect to be here */ } - if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr)) + if (!cifs_match_ipaddr(srcaddr, (struct sockaddr *)&server->srcaddr)) return false; return true; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 550ce9020a3e..1ec6a5543eda 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -32,6 +32,9 @@ #include "cifs_unicode.h" #include "smb2pdu.h" #include "cifsfs.h" +#ifdef CONFIG_CIFS_DFS_UPCALL +#include "dns_resolve.h" +#endif extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; @@ -1083,6 +1086,51 @@ void cifs_put_tcp_super(struct super_block *sb) } #ifdef CONFIG_CIFS_DFS_UPCALL +int match_target_ip(struct TCP_Server_Info *server, + const char *share, size_t share_len, + bool *result) +{ + int rc; + char *target, *tip = NULL; + struct sockaddr tipaddr; + + *result = false; + + target = kzalloc(share_len + 3, GFP_KERNEL); + if (!target) { + rc = -ENOMEM; + goto out; + } + + scnprintf(target, share_len + 3, "\\\\%.*s", (int)share_len, share); + + cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2); + + rc = dns_resolve_server_name_to_ip(target, &tip); + if (rc < 0) + goto out; + + cifs_dbg(FYI, "%s: target ip: %s\n", __func__, tip); + + if (!cifs_convert_address(&tipaddr, tip, strlen(tip))) { + cifs_dbg(VFS, "%s: failed to convert target ip address\n", + __func__); + rc = -EINVAL; + goto out; + } + + *result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, + &tipaddr); + cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result); + rc = 0; + +out: + kfree(target); + kfree(tip); + + return rc; +} + static void tcon_super_cb(struct super_block *sb, void *arg) { struct super_cb_data *sd = arg; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index b30aa3cdd845..cabc19f404e6 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -160,6 +160,7 @@ static int __smb2_reconnect(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; @@ -172,15 +173,15 @@ static int __smb2_reconnect(const struct nls_table *nlsc, if (!tree) return -ENOMEM; - if (tcon->ipc) { - scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", - tcon->ses->server->hostname); - rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); - goto out; - } - if (!tcon->dfs_path) { - rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nlsc); + if (tcon->ipc) { + scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", + server->hostname); + rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); + } else { + rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, + nlsc); + } goto out; } @@ -188,13 +189,13 @@ static int __smb2_reconnect(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); @@ -208,19 +209,38 @@ static int __smb2_reconnect(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", __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; + } - rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); - if (!rc) { - rc = update_super_prepath(tcon, prefix, prefix_len); - break; + if (!target_match) { + cifs_dbg(FYI, "%s: skipping target\n", __func__); + continue; + } + } + + if (tcon->ipc) { + scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$", + (int)share_len, share); + rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); + } else { + scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len, + share); + rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); + if (!rc) { + rc = update_super_prepath(tcon, prefix, + prefix_len); + break; + } } if (rc == -EREMOTE) break; -- cgit v1.2.3 From baf3f08ef4083b76ca67b143e135213a7f941879 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 19 May 2020 15:38:29 -0300 Subject: cifs: get rid of unused parameter in reconn_setup_dfs_targets() The target iterator parameter "it" is not used in reconn_setup_dfs_targets(), so just remove it. Signed-off-by: Paulo Alcantara (SUSE) Reviewed-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/connect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ea3189a6ae10..329babc6b18a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -426,8 +426,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 +471,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__); -- cgit v1.2.3 From a7d5c294628088781da9e91cbb034d61c3a71f71 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 20 May 2020 12:19:59 +1000 Subject: cifs: reduce stack use in smb2_compound_op Move a lot of structures and arrays off the stack and into a dynamically allocated structure instead. Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/smb2inode.c | 92 +++++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index a8c301ae00ed..19115a9088ea 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -47,6 +47,18 @@ free_set_inf_compound(struct smb_rqst *rqst) } +struct cop_vars { + struct cifs_open_parms oparms; + struct kvec rsp_iov[3]; + struct smb_rqst rqst[3]; + struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; + struct kvec qi_iov[1]; + struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; + struct kvec close_iov[1]; + struct smb2_file_rename_info rename_info; + struct smb2_file_link_info link_info; +}; + static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, @@ -54,35 +66,33 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, __u32 create_options, umode_t mode, void *ptr, int command, struct cifsFileInfo *cfile) { + struct cop_vars *vars = NULL; + struct kvec *rsp_iov; + struct smb_rqst *rqst; int rc; __le16 *utf16_path = NULL; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; - struct cifs_open_parms oparms; struct cifs_fid fid; struct cifs_ses *ses = tcon->ses; int num_rqst = 0; - struct smb_rqst rqst[3]; int resp_buftype[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; - struct kvec qi_iov[1]; - struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; - struct kvec close_iov[1]; struct smb2_query_info_rsp *qi_rsp = NULL; int flags = 0; __u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0}; unsigned int size[2]; void *data[2]; - struct smb2_file_rename_info rename_info; - struct smb2_file_link_info link_info; int len; + vars = kzalloc(sizeof(*vars), GFP_ATOMIC); + if (vars == NULL) + return -ENOMEM; + rqst = &vars->rqst[0]; + rsp_iov = &vars->rsp_iov[0]; + if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; - memset(rqst, 0, sizeof(rqst)); resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - memset(rsp_iov, 0, sizeof(rsp_iov)); /* We already have a handle so we can skip the open */ if (cfile) @@ -95,19 +105,17 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } - memset(&oparms, 0, sizeof(struct cifs_open_parms)); - oparms.tcon = tcon; - oparms.desired_access = desired_access; - oparms.disposition = create_disposition; - oparms.create_options = cifs_create_options(cifs_sb, create_options); - oparms.fid = &fid; - oparms.reconnect = false; - oparms.mode = mode; - - memset(&open_iov, 0, sizeof(open_iov)); - rqst[num_rqst].rq_iov = open_iov; + vars->oparms.tcon = tcon; + vars->oparms.desired_access = desired_access; + vars->oparms.disposition = create_disposition; + vars->oparms.create_options = cifs_create_options(cifs_sb, create_options); + vars->oparms.fid = &fid; + vars->oparms.reconnect = false; + vars->oparms.mode = mode; + + rqst[num_rqst].rq_iov = &vars->open_iov[0]; rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE; - rc = SMB2_open_init(tcon, &rqst[num_rqst], &oplock, &oparms, + rc = SMB2_open_init(tcon, &rqst[num_rqst], &oplock, &vars->oparms, utf16_path); kfree(utf16_path); if (rc) @@ -121,8 +129,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, /* Operation */ switch (command) { case SMB2_OP_QUERY_INFO: - memset(&qi_iov, 0, sizeof(qi_iov)); - rqst[num_rqst].rq_iov = qi_iov; + rqst[num_rqst].rq_iov = &vars->qi_iov[0]; rqst[num_rqst].rq_nvec = 1; if (cfile) @@ -164,8 +171,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path); break; case SMB2_OP_RMDIR: - memset(&si_iov, 0, sizeof(si_iov)); - rqst[num_rqst].rq_iov = si_iov; + rqst[num_rqst].rq_iov = &vars->si_iov[0]; rqst[num_rqst].rq_nvec = 1; size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */ @@ -182,8 +188,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); break; case SMB2_OP_SET_EOF: - memset(&si_iov, 0, sizeof(si_iov)); - rqst[num_rqst].rq_iov = si_iov; + rqst[num_rqst].rq_iov = &vars->si_iov[0]; rqst[num_rqst].rq_nvec = 1; size[0] = 8; /* sizeof __le64 */ @@ -200,8 +205,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); break; case SMB2_OP_SET_INFO: - memset(&si_iov, 0, sizeof(si_iov)); - rqst[num_rqst].rq_iov = si_iov; + rqst[num_rqst].rq_iov = &vars->si_iov[0]; rqst[num_rqst].rq_nvec = 1; @@ -233,18 +237,17 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, full_path); break; case SMB2_OP_RENAME: - memset(&si_iov, 0, sizeof(si_iov)); - rqst[num_rqst].rq_iov = si_iov; + rqst[num_rqst].rq_iov = &vars->si_iov[0]; rqst[num_rqst].rq_nvec = 2; len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX)); - rename_info.ReplaceIfExists = 1; - rename_info.RootDirectory = 0; - rename_info.FileNameLength = cpu_to_le32(len); + vars->rename_info.ReplaceIfExists = 1; + vars->rename_info.RootDirectory = 0; + vars->rename_info.FileNameLength = cpu_to_le32(len); size[0] = sizeof(struct smb2_file_rename_info); - data[0] = &rename_info; + data[0] = &vars->rename_info; size[1] = len + 2 /* null */; data[1] = (__le16 *)ptr; @@ -271,18 +274,17 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); break; case SMB2_OP_HARDLINK: - memset(&si_iov, 0, sizeof(si_iov)); - rqst[num_rqst].rq_iov = si_iov; + rqst[num_rqst].rq_iov = &vars->si_iov[0]; rqst[num_rqst].rq_nvec = 2; len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX)); - link_info.ReplaceIfExists = 0; - link_info.RootDirectory = 0; - link_info.FileNameLength = cpu_to_le32(len); + vars->link_info.ReplaceIfExists = 0; + vars->link_info.RootDirectory = 0; + vars->link_info.FileNameLength = cpu_to_le32(len); size[0] = sizeof(struct smb2_file_link_info); - data[0] = &link_info; + data[0] = &vars->link_info; size[1] = len + 2 /* null */; data[1] = (__le16 *)ptr; @@ -308,8 +310,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, if (cfile) goto after_close; /* Close */ - memset(&close_iov, 0, sizeof(close_iov)); - rqst[num_rqst].rq_iov = close_iov; + rqst[num_rqst].rq_iov = &vars->close_iov[0]; rqst[num_rqst].rq_nvec = 1; rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, false); @@ -420,6 +421,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); + kfree(vars); return rc; } -- cgit v1.2.3 From b2ca6c2c9eddc41c09e49e8e83f8208bd80fdb8e Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 21 May 2020 15:03:15 +1000 Subject: cifs: move some variables off the stack in smb2_ioctl_query_info Move some large data structures off the stack and into dynamically allocated memory in the function smb2_ioctl_query_info Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 58 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 23 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index f829f4165d38..fa5c79f64c0b 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1452,6 +1452,16 @@ req_res_key_exit: return rc; } +struct iqi_vars { + struct smb_rqst rqst[3]; + struct kvec rsp_iov[3]; + struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; + struct kvec qi_iov[1]; + struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; + struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; + struct kvec close_iov[1]; +}; + static int smb2_ioctl_query_info(const unsigned int xid, struct cifs_tcon *tcon, @@ -1459,6 +1469,9 @@ smb2_ioctl_query_info(const unsigned int xid, __le16 *path, int is_dir, unsigned long p) { + struct iqi_vars *vars; + struct smb_rqst *rqst; + struct kvec *rsp_iov; struct cifs_ses *ses = tcon->ses; char __user *arg = (char __user *)p; struct smb_query_info qi; @@ -1468,45 +1481,47 @@ smb2_ioctl_query_info(const unsigned int xid, struct smb2_query_info_rsp *qi_rsp = NULL; struct smb2_ioctl_rsp *io_rsp = NULL; void *buffer = NULL; - struct smb_rqst rqst[3]; int resp_buftype[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; struct cifs_open_parms oparms; u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_fid fid; - struct kvec qi_iov[1]; - struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; - struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; - struct kvec close_iov[1]; unsigned int size[2]; void *data[2]; int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR; - memset(rqst, 0, sizeof(rqst)); + vars = kzalloc(sizeof(*vars), GFP_ATOMIC); + if (vars == NULL) + return -ENOMEM; + rqst = &vars->rqst[0]; + rsp_iov = &vars->rsp_iov[0]; + resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - memset(rsp_iov, 0, sizeof(rsp_iov)); if (copy_from_user(&qi, arg, sizeof(struct smb_query_info))) - return -EFAULT; + goto e_fault; - if (qi.output_buffer_length > 1024) + if (qi.output_buffer_length > 1024) { + kfree(vars); return -EINVAL; + } - if (!ses || !(ses->server)) + if (!ses || !(ses->server)) { + kfree(vars); return -EIO; + } if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; buffer = memdup_user(arg + sizeof(struct smb_query_info), qi.output_buffer_length); - if (IS_ERR(buffer)) + if (IS_ERR(buffer)) { + kfree(vars); return PTR_ERR(buffer); + } /* Open */ - memset(&open_iov, 0, sizeof(open_iov)); - rqst[0].rq_iov = open_iov; + rqst[0].rq_iov = &vars->open_iov[0]; rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; memset(&oparms, 0, sizeof(oparms)); @@ -1548,8 +1563,7 @@ smb2_ioctl_query_info(const unsigned int xid, if (!capable(CAP_SYS_ADMIN)) rc = -EPERM; else { - memset(&io_iov, 0, sizeof(io_iov)); - rqst[1].rq_iov = io_iov; + rqst[1].rq_iov = &vars->io_iov[0]; rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; rc = SMB2_ioctl_init(tcon, &rqst[1], @@ -1565,8 +1579,7 @@ smb2_ioctl_query_info(const unsigned int xid, if (!capable(CAP_SYS_ADMIN)) rc = -EPERM; else { - memset(&si_iov, 0, sizeof(si_iov)); - rqst[1].rq_iov = si_iov; + rqst[1].rq_iov = &vars->si_iov[0]; rqst[1].rq_nvec = 1; size[0] = 8; @@ -1579,8 +1592,7 @@ smb2_ioctl_query_info(const unsigned int xid, SMB2_O_INFO_FILE, 0, data, size); } } else if (qi.flags == PASSTHRU_QUERY_INFO) { - memset(&qi_iov, 0, sizeof(qi_iov)); - rqst[1].rq_iov = qi_iov; + rqst[1].rq_iov = &vars->qi_iov[0]; rqst[1].rq_nvec = 1; rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, @@ -1599,8 +1611,7 @@ smb2_ioctl_query_info(const unsigned int xid, smb2_set_related(&rqst[1]); /* Close */ - memset(&close_iov, 0, sizeof(close_iov)); - rqst[2].rq_iov = close_iov; + rqst[2].rq_iov = &vars->close_iov[0]; rqst[2].rq_nvec = 1; rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); @@ -1649,6 +1660,7 @@ smb2_ioctl_query_info(const unsigned int xid, } iqinf_exit: + kfree(vars); kfree(buffer); SMB2_open_free(&rqst[0]); if (qi.flags & PASSTHRU_FSCTL) -- cgit v1.2.3 From 82e9367c43890cb6a870f700c9180c7eb2035684 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 19 May 2020 03:06:57 -0500 Subject: smb3: Add new parm "nodelete" In order to handle workloads where it is important to make sure that a buggy app did not delete content on the drive, the new mount option "nodelete" allows standard permission checks on the server to work, but prevents on the client any attempts to unlink a file or delete a directory on that mount point. This can be helpful when running a little understood app on a network mount that contains important content that should not be deleted. Signed-off-by: Steve French CC: Stable Reviewed-by: Pavel Shilovsky --- fs/cifs/cifsfs.c | 2 ++ fs/cifs/cifsglob.h | 2 ++ fs/cifs/connect.c | 9 ++++++++- fs/cifs/inode.c | 11 +++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) (limited to 'fs/cifs') 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/cifsglob.h b/fs/cifs/cifsglob.h index 39b708d9d86d..4d261fd78fcb 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; @@ -1136,6 +1137,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 */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 329babc6b18a..57d1cc6bf86f 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 */ @@ -1760,6 +1761,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, case Opt_noperm: vol->noperm = 1; break; + case Opt_nodelete: + vol->nodelete = 1; + break; case Opt_mapchars: vol->sfu_remap = true; vol->remap = false; /* disable SFM mapping */ @@ -3362,6 +3366,8 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info) return 0; if (tcon->no_lease != volume_info->no_lease) return 0; + if (tcon->nodelete != volume_info->nodelete) + return 0; return 1; } @@ -3597,6 +3603,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) tcon->retry = volume_info->retry; tcon->nocase = volume_info->nocase; tcon->nohandlecache = volume_info->nohandlecache; + tcon->nodelete = volume_info->nodelete; tcon->local_lease = volume_info->local_lease; INIT_LIST_HEAD(&tcon->pending_opens); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 5d2965a23730..873b1effd412 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1418,6 +1418,11 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) xid = get_xid(); + if (tcon->nodelete) { + rc = -EACCES; + goto unlink_out; + } + /* Unlink can be called from rename so we can not take the * sb->s_vfs_rename_mutex here */ full_path = build_path_from_dentry(dentry); @@ -1746,6 +1751,12 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) goto rmdir_exit; } + if (tcon->nodelete) { + rc = -EACCES; + cifs_put_tlink(tlink); + goto rmdir_exit; + } + rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb); cifs_put_tlink(tlink); -- cgit v1.2.3 From a0a3036b81f1f66fa3333559ecfe18f5bbfa5076 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 14 Apr 2020 22:42:53 -0700 Subject: cifs: Standardize logging output Use pr_fmt to standardize all logging for fs/cifs. Some logging output had no CIFS: specific prefix. Now all output has one of three prefixes: o CIFS: o CIFS: VFS: o Root-CIFS: Miscellanea: o Convert printks to pr_ o Neaten macro definitions o Remove embedded CIFS: prefixes from formats o Convert "illegal" to "invalid" o Coalesce formats o Add missing '\n' format terminations o Consolidate multiple cifs_dbg continuations into single calls o More consistent use of upper case first word output logging o Multiline statement argument alignment and wrapping Signed-off-by: Joe Perches Signed-off-by: Steve French --- fs/cifs/cifs_debug.h | 145 +++++++++++++++++++++----------------------- fs/cifs/cifsencrypt.c | 8 +-- fs/cifs/cifsproto.h | 26 ++++---- fs/cifs/cifsroot.c | 6 +- fs/cifs/cifssmb.c | 24 ++++---- fs/cifs/connect.c | 77 ++++++++++------------- fs/cifs/dfs_cache.c | 14 ++--- fs/cifs/file.c | 24 +++----- fs/cifs/inode.c | 4 +- fs/cifs/misc.c | 12 ++-- fs/cifs/netmisc.c | 6 +- fs/cifs/readdir.c | 10 +-- fs/cifs/sess.c | 28 ++++----- fs/cifs/smb1ops.c | 2 +- fs/cifs/smb2inode.c | 3 +- fs/cifs/smb2misc.c | 20 +++--- fs/cifs/smb2ops.c | 31 +++++----- fs/cifs/smb2pdu.c | 70 ++++++++++----------- fs/cifs/smbdirect.c | 165 ++++++++++++++++++++------------------------------ fs/cifs/transport.c | 25 ++++---- 20 files changed, 319 insertions(+), 381 deletions(-) (limited to 'fs/cifs') 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/cifsproto.h b/fs/cifs/cifsproto.h index 311d8e86c5a8..8036216ce434 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); 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 5a684f9ac883..5820f9569b7f 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -281,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; } @@ -343,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; } @@ -576,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; @@ -585,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; } @@ -722,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; } @@ -3887,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; } @@ -4263,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); @@ -4430,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); @@ -4512,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); @@ -4932,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 57d1cc6bf86f..daf90f988de1 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -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; } @@ -1912,7 +1908,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->seal = 1; break; case Opt_noac: - pr_warn("CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n"); + pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n"); break; case Opt_fsc: #ifndef CONFIG_CIFS_FSCACHE @@ -2159,7 +2155,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (strnlen(string, CIFS_MAX_USERNAME_LEN) > CIFS_MAX_USERNAME_LEN) { - pr_warn("CIFS: username too long\n"); + pr_warn("username too long\n"); goto cifs_parse_mount_err; } @@ -2225,7 +2221,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, temp_len = strlen(value); vol->password = kzalloc(temp_len+1, GFP_KERNEL); if (vol->password == NULL) { - pr_warn("CIFS: no memory for password\n"); + pr_warn("no memory for password\n"); goto cifs_parse_mount_err; } @@ -2249,7 +2245,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (!cifs_convert_address(dstaddr, string, strlen(string))) { - pr_err("CIFS: bad ip= option (%s).\n", string); + pr_err("bad ip= option (%s)\n", string); goto cifs_parse_mount_err; } got_ip = true; @@ -2261,14 +2257,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN) == CIFS_MAX_DOMAINNAME_LEN) { - pr_warn("CIFS: domain name too long\n"); + pr_warn("domain name too long\n"); goto cifs_parse_mount_err; } kfree(vol->domainname); vol->domainname = kstrdup(string, GFP_KERNEL); if (!vol->domainname) { - pr_warn("CIFS: no memory for domainname\n"); + pr_warn("no memory for domainname\n"); goto cifs_parse_mount_err; } cifs_dbg(FYI, "Domain name set\n"); @@ -2281,7 +2277,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (!cifs_convert_address( (struct sockaddr *)&vol->srcaddr, string, strlen(string))) { - pr_warn("CIFS: Could not parse srcaddr: %s\n", + pr_warn("Could not parse srcaddr: %s\n", string); goto cifs_parse_mount_err; } @@ -2292,7 +2288,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto out_nomem; if (strnlen(string, 1024) >= 65) { - pr_warn("CIFS: iocharset name too long.\n"); + pr_warn("iocharset name too long\n"); goto cifs_parse_mount_err; } @@ -2301,7 +2297,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->iocharset = kstrdup(string, GFP_KERNEL); if (!vol->iocharset) { - pr_warn("CIFS: no memory for charset\n"); + pr_warn("no memory for charset\n"); goto cifs_parse_mount_err; } } @@ -2332,7 +2328,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, * set at top of the function */ if (i == RFC1001_NAME_LEN && string[i] != 0) - pr_warn("CIFS: netbiosname longer than 15 truncated.\n"); + pr_warn("netbiosname longer than 15 truncated\n"); break; case Opt_servern: /* servernetbiosname specified override *SMBSERVER */ @@ -2358,7 +2354,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* The string has 16th byte zero still from set at top of the function */ if (i == RFC1001_NAME_LEN && string[i] != 0) - pr_warn("CIFS: server netbiosname longer than 15 truncated.\n"); + pr_warn("server netbiosname longer than 15 truncated\n"); break; case Opt_ver: /* version of mount userspace tools, not dialect */ @@ -2369,17 +2365,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* If interface changes in mount.cifs bump to new ver */ if (strncasecmp(string, "1", 1) == 0) { if (strlen(string) > 1) { - pr_warn("Bad mount helper ver=%s. Did " - "you want SMB1 (CIFS) dialect " - "and mean to type vers=1.0 " - "instead?\n", string); + pr_warn("Bad mount helper ver=%s. Did you want SMB1 (CIFS) dialect and mean to type vers=1.0 instead?\n", + string); goto cifs_parse_mount_err; } /* This is the default */ break; } /* For all other value, error */ - pr_warn("CIFS: Invalid mount helper version specified\n"); + pr_warn("Invalid mount helper version specified\n"); goto cifs_parse_mount_err; case Opt_vers: /* protocol version (dialect) */ @@ -2422,7 +2416,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } if (!sloppy && invalid) { - pr_err("CIFS: Unknown mount option \"%s\"\n", invalid); + pr_err("Unknown mount option \"%s\"\n", invalid); goto cifs_parse_mount_err; } @@ -2458,7 +2452,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, slash = strchr(&vol->UNC[2], '\\'); len = slash - &vol->UNC[2]; if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) { - pr_err("Unable to determine destination address.\n"); + pr_err("Unable to determine destination address\n"); goto cifs_parse_mount_err; } } @@ -2469,20 +2463,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (uid_specified) vol->override_uid = override_uid; else if (override_uid == 1) - pr_notice("CIFS: ignoring forceuid mount option specified with no uid= option.\n"); + pr_notice("ignoring forceuid mount option specified with no uid= option\n"); if (gid_specified) vol->override_gid = override_gid; else if (override_gid == 1) - pr_notice("CIFS: ignoring forcegid mount option specified with no gid= option.\n"); + pr_notice("ignoring forcegid mount option specified with no gid= option\n"); if (got_version == false) - pr_warn_once("No dialect specified on mount. Default has changed" - " to a more secure dialect, SMB2.1 or later (e.g. " - "SMB3.1.1), from CIFS (SMB1). To use the less secure " - "SMB1 dialect to access old servers which do not " - "support SMB3.1.1 (or even SMB3 or SMB2.1) specify " - "vers=1.0 on mount.\n"); + pr_warn_once("No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.\n"); kfree(mountdata_copy); return 0; @@ -3200,8 +3189,8 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses) strlen(ses->domainName), GFP_KERNEL); if (!vol->domainname) { - cifs_dbg(FYI, "Unable to allocate %zd bytes for " - "domain\n", len); + cifs_dbg(FYI, "Unable to allocate %zd bytes for domain\n", + len); rc = -ENOMEM; kfree(vol->username); vol->username = NULL; @@ -3524,10 +3513,9 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) 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"); + pr_warn_once("SMB3.11 POSIX Extensions are experimental\n"); } else { - cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions.\n"); + cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n"); rc = -EOPNOTSUPP; goto out_fail; } @@ -4757,8 +4745,7 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, rc = cifs_are_all_path_components_accessible(server, xid, tcon, cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); if (rc != 0) { - cifs_server_dbg(VFS, "cannot query dirs between root and final path, " - "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); + cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; rc = 0; } diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index a67f88bf7ae1..df81c718d2fa 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -198,7 +198,7 @@ static ssize_t dfscache_proc_write(struct file *file, const char __user *buffer, if (c != '0') return -EINVAL; - cifs_dbg(FYI, "clearing dfs cache"); + cifs_dbg(FYI, "clearing dfs cache\n"); down_write(&htable_rw_lock); flush_cache_ents(); @@ -234,8 +234,8 @@ static inline void dump_tgts(const struct cache_entry *ce) static inline void dump_ce(const struct cache_entry *ce) { - cifs_dbg(FYI, "cache entry: path=%s,type=%s,ttl=%d,etime=%ld," - "interlink=%s,path_consumed=%d,expired=%s\n", ce->path, + cifs_dbg(FYI, "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,interlink=%s,path_consumed=%d,expired=%s\n", + ce->path, ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl, ce->etime.tv_nsec, IS_INTERLINK_SET(ce->flags) ? "yes" : "no", @@ -453,11 +453,11 @@ static void remove_oldest_entry(void) } if (!to_del) { - cifs_dbg(FYI, "%s: no entry to remove", __func__); + cifs_dbg(FYI, "%s: no entry to remove\n", __func__); return; } - cifs_dbg(FYI, "%s: removing entry", __func__); + cifs_dbg(FYI, "%s: removing entry\n", __func__); dump_ce(to_del); flush_cache_ent(to_del); } @@ -696,8 +696,8 @@ static int __dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, } if (atomic_read(&cache_count) >= CACHE_MAX_ENTRIES) { - cifs_dbg(FYI, "%s: reached max cache size (%d)", __func__, - CACHE_MAX_ENTRIES); + cifs_dbg(FYI, "%s: reached max cache size (%d)\n", + __func__, CACHE_MAX_ENTRIES); down_write(&htable_rw_lock); remove_oldest_entry(); up_write(&htable_rw_lock); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 75ddce8ef456..226bfa5e9444 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -857,7 +857,7 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon) tcon->need_reopen_files = false; - cifs_dbg(FYI, "Reopen persistent handles"); + cifs_dbg(FYI, "Reopen persistent handles\n"); INIT_LIST_HEAD(&tmp_list); /* list all files open on tree connection, reopen resilient handles */ @@ -2056,7 +2056,7 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, int flags) rc = cifs_get_writable_file(cifs_inode, flags, &cfile); if (rc) - cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc); + cifs_dbg(FYI, "Couldn't find writable handle rc=%d\n", rc); return cfile; } @@ -2923,11 +2923,9 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, from, &pagevec, cur_len, &start); if (result < 0) { cifs_dbg(VFS, - "direct_writev couldn't get user pages " - "(rc=%zd) iter type %d iov_offset %zd " - "count %zd\n", - result, iov_iter_type(from), - from->iov_offset, from->count); + "direct_writev couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n", + result, iov_iter_type(from), + from->iov_offset, from->count); dump_stack(); rc = result; @@ -3654,12 +3652,10 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, cur_len, &start); if (result < 0) { cifs_dbg(VFS, - "couldn't get user pages (rc=%zd)" - " iter type %d" - " iov_offset %zd count %zd\n", - result, iov_iter_type(&direct_iov), - direct_iov.iov_offset, - direct_iov.count); + "Couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n", + result, iov_iter_type(&direct_iov), + direct_iov.iov_offset, + direct_iov.count); dump_stack(); rc = result; @@ -4828,7 +4824,7 @@ static int cifs_swap_activate(struct swap_info_struct *sis, } *span = sis->pages; - printk_once(KERN_WARNING "Swap support over SMB3 is experimental\n"); + pr_warn_once("Swap support over SMB3 is experimental\n"); /* * TODO: consider adding ACL (or documenting how) to prevent other diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 873b1effd412..b94c6398da94 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1155,7 +1155,7 @@ struct inode *cifs_root_iget(struct super_block *sb) /* some servers mistakenly claim POSIX support */ if (rc != -EOPNOTSUPP) goto iget_no_retry; - cifs_dbg(VFS, "server does not support POSIX extensions"); + cifs_dbg(VFS, "server does not support POSIX extensions\n"); tcon->unix_ext = false; } @@ -2010,7 +2010,7 @@ cifs_invalidate_mapping(struct inode *inode) if (inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = invalidate_inode_pages2(inode->i_mapping); if (rc) - cifs_dbg(VFS, "%s: could not invalidate inode %p\n", + cifs_dbg(VFS, "%s: Could not invalidate inode %p\n", __func__, inode); } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 1ec6a5543eda..56791a692c8b 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -424,7 +424,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) if (data_offset > len - sizeof(struct file_notify_information)) { - cifs_dbg(FYI, "invalid data_offset %u\n", + cifs_dbg(FYI, "Invalid data_offset %u\n", data_offset); return true; } @@ -452,7 +452,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) large dirty files cached on the client */ if ((NT_STATUS_INVALID_HANDLE) == le32_to_cpu(pSMB->hdr.Status.CifsError)) { - cifs_dbg(FYI, "invalid handle on oplock break\n"); + cifs_dbg(FYI, "Invalid handle on oplock break\n"); return true; } else if (ERRbadfid == le16_to_cpu(pSMB->hdr.Status.DosError.Error)) { @@ -533,9 +533,9 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; cifs_sb->mnt_cifs_serverino_autodisabled = true; - cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s.\n", + cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s\n", tcon ? tcon->treeName : "new server"); - cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS).\n"); + cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS)\n"); cifs_dbg(VFS, "Hardlinks will not be recognized on this mount. Consider mounting with the \"noserverino\" option to silence this message.\n"); } @@ -877,7 +877,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) while (count && npages < max_pages) { rc = iov_iter_get_pages(iter, pages, count, max_pages, &start); if (rc < 0) { - cifs_dbg(VFS, "couldn't get user pages (rc=%zd)\n", rc); + cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc); break; } @@ -936,7 +936,7 @@ cifs_alloc_hash(const char *name, *shash = crypto_alloc_shash(name, 0, 0); if (IS_ERR(*shash)) { - cifs_dbg(VFS, "could not allocate crypto %s\n", name); + cifs_dbg(VFS, "Could not allocate crypto %s\n", name); rc = PTR_ERR(*shash); *shash = NULL; *sdesc = NULL; diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 9b41436fb8db..b7ca4960d4ca 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -957,15 +957,15 @@ struct timespec64 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 %lld\n", min, sec); + cifs_dbg(VFS, "Invalid time min %d sec %lld\n", min, sec); sec += (min * 60); sec += 60 * 60 * st->Hours; if (st->Hours > 24) - cifs_dbg(VFS, "illegal hours %d\n", st->Hours); + cifs_dbg(VFS, "Invalid hours %d\n", st->Hours); day = sd->Day; month = sd->Month; if (day < 1 || day > 31 || month < 1 || month > 12) { - cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, day); + cifs_dbg(VFS, "Invalid date, month %d day: %d\n", month, day); day = clamp(day, 1, 31); month = clamp(month, 1, 12); } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 50f776a8d4ba..6df0922e7e30 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -53,7 +53,7 @@ static void dump_cifs_file_struct(struct file *file, char *label) return; } if (cf->invalidHandle) - cifs_dbg(FYI, "invalid handle\n"); + cifs_dbg(FYI, "Invalid handle\n"); if (cf->srch_inf.endOfSearch) cifs_dbg(FYI, "end of search\n"); if (cf->srch_inf.emptyDir) @@ -246,7 +246,7 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info, */ fattr->cf_mode = le32_to_cpu(info->Mode) & ~S_IFMT; - cifs_dbg(FYI, "posix fattr: dev %d, reparse %d, mode %o", + cifs_dbg(FYI, "posix fattr: dev %d, reparse %d, mode %o\n", le32_to_cpu(info->DeviceId), le32_to_cpu(info->ReparseTag), le32_to_cpu(info->Mode)); @@ -478,7 +478,7 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset); if (old_entry + next_offset < old_entry) { - cifs_dbg(VFS, "invalid offset %u\n", next_offset); + cifs_dbg(VFS, "Invalid offset %u\n", next_offset); return NULL; } new_entry = old_entry + next_offset; @@ -515,7 +515,7 @@ static void cifs_fill_dirent_posix(struct cifs_dirent *de, /* payload should have already been checked at this point */ if (posix_info_parse(info, NULL, &parsed) < 0) { - cifs_dbg(VFS, "invalid POSIX info payload"); + cifs_dbg(VFS, "Invalid POSIX info payload\n"); return; } @@ -968,7 +968,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx) } else if (current_entry != NULL) { cifs_dbg(FYI, "entry %lld found\n", ctx->pos); } else { - cifs_dbg(FYI, "could not find entry\n"); + cifs_dbg(FYI, "Could not find entry\n"); goto rddir2_exit; } cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n", diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 43a88e26d26b..3f8b43e77539 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -162,12 +162,14 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) int rc; unsigned int xid = get_xid(); - cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ", - ses, iface->speed, iface->rdma_capable ? "yes" : "no"); if (iface->sockaddr.ss_family == AF_INET) - cifs_dbg(FYI, "ip:%pI4)\n", &ipv4->sin_addr); + cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n", + ses, iface->speed, iface->rdma_capable ? "yes" : "no", + &ipv4->sin_addr); else - cifs_dbg(FYI, "ip:%pI6)\n", &ipv6->sin6_addr); + cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n", + ses, iface->speed, iface->rdma_capable ? "yes" : "no", + &ipv6->sin6_addr); /* * Setup a smb_vol with mostly the same info as the existing @@ -569,15 +571,15 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset); tilen = le16_to_cpu(pblob->TargetInfoArray.Length); if (tioffset > blob_len || tioffset + tilen > blob_len) { - cifs_dbg(VFS, "tioffset + tilen too high %u + %u", - tioffset, tilen); + cifs_dbg(VFS, "tioffset + tilen too high %u + %u\n", + tioffset, tilen); return -EINVAL; } if (tilen) { ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen, GFP_KERNEL); if (!ses->auth_key.response) { - cifs_dbg(VFS, "Challenge target info alloc failure"); + cifs_dbg(VFS, "Challenge target info alloc failure\n"); return -ENOMEM; } ses->auth_key.len = tilen; @@ -1303,9 +1305,8 @@ sess_auth_kerberos(struct sess_data *sess_data) * sending us a response in an expected form */ if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) { - cifs_dbg(VFS, - "incorrect version of cifs.upcall (expected %d but got %d)", - CIFS_SPNEGO_UPCALL_VERSION, msg->version); + cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n", + CIFS_SPNEGO_UPCALL_VERSION, msg->version); rc = -EKEYREJECTED; goto out_put_spnego_key; } @@ -1313,8 +1314,8 @@ sess_auth_kerberos(struct sess_data *sess_data) ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len, GFP_KERNEL); if (!ses->auth_key.response) { - cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory", - msg->sesskey_len); + cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n", + msg->sesskey_len); rc = -ENOMEM; goto out_put_spnego_key; } @@ -1657,8 +1658,7 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data) type = cifs_select_sectype(ses->server, ses->sectype); cifs_dbg(FYI, "sess setup type %d\n", type); if (type == Unspecified) { - cifs_dbg(VFS, - "Unable to select appropriate authentication method!"); + cifs_dbg(VFS, "Unable to select appropriate authentication method!\n"); return -EINVAL; } diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index b130efaf8feb..197ed455e657 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -247,7 +247,7 @@ check2ndT2(char *buf) /* check for plausible wct, bcc and t2 data and parm sizes */ /* check for parm and data offset going beyond end of smb */ if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */ - cifs_dbg(FYI, "invalid transact2 word count\n"); + cifs_dbg(FYI, "Invalid transact2 word count\n"); return -EINVAL; } diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 19115a9088ea..fa86c78384c3 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -337,8 +337,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, SMB2_open_free(&rqst[0]); if (rc == -EREMCHG) { - printk_once(KERN_WARNING "server share %s deleted\n", - tcon->treeName); + pr_warn_once("server share %s deleted\n", tcon->treeName); tcon->need_reconnect = true; } diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index 497afb0b9960..6a39451973f8 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -110,14 +110,14 @@ static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len, /* Make sure that negotiate contexts start after gss security blob */ nc_offset = le32_to_cpu(pneg_rsp->NegotiateContextOffset); if (nc_offset < non_ctxlen) { - printk_once(KERN_WARNING "invalid negotiate context offset\n"); + pr_warn_once("Invalid negotiate context offset\n"); return 0; } size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen; /* Verify that at least minimal negotiate contexts fit within frame */ if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) { - printk_once(KERN_WARNING "negotiate context goes beyond end\n"); + pr_warn_once("negotiate context goes beyond end\n"); return 0; } @@ -190,14 +190,14 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) return 1; if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { - cifs_dbg(VFS, "Illegal structure size %u\n", + cifs_dbg(VFS, "Invalid structure size %u\n", le16_to_cpu(shdr->StructureSize)); return 1; } command = le16_to_cpu(shdr->Command); if (command >= NUMBER_OF_SMB2_COMMANDS) { - cifs_dbg(VFS, "Illegal SMB2 command %d\n", command); + cifs_dbg(VFS, "Invalid SMB2 command %d\n", command); return 1; } @@ -205,7 +205,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) { /* error packets have 9 byte structure size */ - cifs_dbg(VFS, "Illegal response size %u for command %d\n", + cifs_dbg(VFS, "Invalid response size %u for command %d\n", le16_to_cpu(pdu->StructureSize2), command); return 1; } else if (command == SMB2_OPLOCK_BREAK_HE @@ -213,7 +213,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) && (le16_to_cpu(pdu->StructureSize2) != 44) && (le16_to_cpu(pdu->StructureSize2) != 36)) { /* special case for SMB2.1 lease break message */ - cifs_dbg(VFS, "Illegal response size %d for oplock break\n", + cifs_dbg(VFS, "Invalid response size %d for oplock break\n", le16_to_cpu(pdu->StructureSize2)); return 1; } @@ -864,14 +864,14 @@ ok: d = server->secmech.sdescsha512; rc = crypto_shash_init(&d->shash); if (rc) { - cifs_dbg(VFS, "%s: could not init sha512 shash\n", __func__); + cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); return rc; } rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash, SMB2_PREAUTH_HASH_SIZE); if (rc) { - cifs_dbg(VFS, "%s: could not update sha512 shash\n", __func__); + cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); return rc; } @@ -879,7 +879,7 @@ ok: rc = crypto_shash_update(&d->shash, iov[i].iov_base, iov[i].iov_len); if (rc) { - cifs_dbg(VFS, "%s: could not update sha512 shash\n", + cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); return rc; } @@ -887,7 +887,7 @@ ok: rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash); if (rc) { - cifs_dbg(VFS, "%s: could not finalize sha512 shash\n", + cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n", __func__); return rc; } diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index fa5c79f64c0b..dec055d7c2f4 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -79,7 +79,7 @@ smb2_add_credits(struct TCP_Server_Info *server, if (*val > 65000) { *val = 65000; /* Don't get near 64K credits, avoid srv bugs */ - printk_once(KERN_WARNING "server overflowed SMB3 credits\n"); + pr_warn_once("server overflowed SMB3 credits\n"); } server->in_flight--; if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP) @@ -767,8 +767,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, if (rc) { if (rc == -EREMCHG) { tcon->need_reconnect = true; - printk_once(KERN_WARNING "server share %s deleted\n", - tcon->treeName); + pr_warn_once("server share %s deleted\n", + tcon->treeName); } goto oshr_exit; } @@ -1601,7 +1601,8 @@ smb2_ioctl_query_info(const unsigned int xid, qi.input_buffer_length, qi.output_buffer_length, buffer); } else { /* unknown flags */ - cifs_tcon_dbg(VFS, "invalid passthru query flags: 0x%x\n", qi.flags); + cifs_tcon_dbg(VFS, "Invalid passthru query flags: 0x%x\n", + qi.flags); rc = -EINVAL; } @@ -1731,7 +1732,7 @@ smb2_copychunk_range(const unsigned int xid, if (rc == 0) { if (ret_data_len != sizeof(struct copychunk_ioctl_rsp)) { - cifs_tcon_dbg(VFS, "invalid cchunk response size\n"); + cifs_tcon_dbg(VFS, "Invalid cchunk response size\n"); rc = -EIO; goto cchunk_out; } @@ -1745,12 +1746,12 @@ smb2_copychunk_range(const unsigned int xid, */ if (le32_to_cpu(retbuf->TotalBytesWritten) > le32_to_cpu(pcchunk->Length)) { - cifs_tcon_dbg(VFS, "invalid copy chunk response\n"); + cifs_tcon_dbg(VFS, "Invalid copy chunk response\n"); rc = -EIO; goto cchunk_out; } if (le32_to_cpu(retbuf->ChunksWritten) != 1) { - cifs_tcon_dbg(VFS, "invalid num chunks written\n"); + cifs_tcon_dbg(VFS, "Invalid num chunks written\n"); rc = -EIO; goto cchunk_out; } @@ -2484,8 +2485,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); if (rc == -EREMCHG) { tcon->need_reconnect = true; - printk_once(KERN_WARNING "server share %s deleted\n", - tcon->treeName); + pr_warn_once("server share %s deleted\n", + tcon->treeName); } goto qic_exit; } @@ -2765,15 +2766,15 @@ parse_reparse_point(struct reparse_data_buffer *buf, struct cifs_sb_info *cifs_sb) { if (plen < sizeof(struct reparse_data_buffer)) { - cifs_dbg(VFS, "reparse buffer is too small. Must be " - "at least 8 bytes but was %d\n", plen); + cifs_dbg(VFS, "reparse buffer is too small. Must be at least 8 bytes but was %d\n", + plen); return -EIO; } if (plen < le16_to_cpu(buf->ReparseDataLength) + sizeof(struct reparse_data_buffer)) { - cifs_dbg(VFS, "srv returned invalid reparse buf " - "length: %d\n", plen); + cifs_dbg(VFS, "srv returned invalid reparse buf length: %d\n", + plen); return -EIO; } @@ -2788,8 +2789,8 @@ parse_reparse_point(struct reparse_data_buffer *buf, (struct reparse_symlink_data_buffer *)buf, plen, target_path, cifs_sb); default: - cifs_dbg(VFS, "srv returned unknown symlink buffer " - "tag:0x%08x\n", le32_to_cpu(buf->ReparseTag)); + cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n", + le32_to_cpu(buf->ReparseTag)); return -EOPNOTSUPP; } } diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index cabc19f404e6..4b79181ff872 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -334,8 +334,8 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) (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; } @@ -404,7 +404,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); if (rc) { /* If sess reconnected but tcon didn't, something strange ... */ - printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc); + pr_warn_once("reconnect tcon failed rc = %d\n", rc); goto out; } @@ -646,13 +646,13 @@ static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) /* If invalid preauth context warn but use what we requested, SHA-512 */ if (len < MIN_PREAUTH_CTXT_DATA_LEN) { - printk_once(KERN_WARNING "server sent bad preauth context\n"); + pr_warn_once("server sent bad preauth context\n"); return; } if (le16_to_cpu(ctxt->HashAlgorithmCount) != 1) - printk_once(KERN_WARNING "illegal SMB3 hash algorithm count\n"); + pr_warn_once("Invalid SMB3 hash algorithm count\n"); if (ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512) - printk_once(KERN_WARNING "unknown SMB3 hash algorithm\n"); + pr_warn_once("unknown SMB3 hash algorithm\n"); } static void decode_compress_ctx(struct TCP_Server_Info *server, @@ -662,15 +662,15 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, /* sizeof compress context is a one element compression capbility struct */ if (len < 10) { - printk_once(KERN_WARNING "server sent bad compression cntxt\n"); + pr_warn_once("server sent bad compression cntxt\n"); return; } if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) { - printk_once(KERN_WARNING "illegal SMB3 compress algorithm count\n"); + pr_warn_once("Invalid SMB3 compress algorithm count\n"); return; } if (le16_to_cpu(ctxt->CompressionAlgorithms[0]) > 3) { - printk_once(KERN_WARNING "unknown compression algorithm\n"); + pr_warn_once("unknown compression algorithm\n"); return; } server->compress_algorithm = ctxt->CompressionAlgorithms[0]; @@ -683,18 +683,18 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server, cifs_dbg(FYI, "decode SMB3.11 encryption neg context of len %d\n", len); if (len < MIN_ENCRYPT_CTXT_DATA_LEN) { - printk_once(KERN_WARNING "server sent bad crypto ctxt len\n"); + pr_warn_once("server sent bad crypto ctxt len\n"); return -EINVAL; } if (le16_to_cpu(ctxt->CipherCount) != 1) { - printk_once(KERN_WARNING "illegal SMB3.11 cipher count\n"); + pr_warn_once("Invalid SMB3.11 cipher count\n"); return -EINVAL; } cifs_dbg(FYI, "SMB311 cipher type:%d\n", le16_to_cpu(ctxt->Ciphers[0])); if ((ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_CCM) && (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_GCM)) { - printk_once(KERN_WARNING "invalid SMB3.11 cipher returned\n"); + pr_warn_once("Invalid SMB3.11 cipher returned\n"); return -EINVAL; } server->cipher_type = ctxt->Ciphers[0]; @@ -794,7 +794,7 @@ create_posix_buf(umode_t mode) buf->Name[14] = 0xCD; buf->Name[15] = 0x7C; buf->Mode = cpu_to_le32(mode); - cifs_dbg(FYI, "mode on posix create 0%o", mode); + cifs_dbg(FYI, "mode on posix create 0%o\n", mode); return buf; } @@ -806,7 +806,7 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) iov[num].iov_base = create_posix_buf(mode); if (mode == ACL_NO_MODE) - cifs_dbg(FYI, "illegal mode\n"); + cifs_dbg(FYI, "Invalid mode\n"); if (iov[num].iov_base == NULL) return -ENOMEM; iov[num].iov_len = sizeof(struct create_posix); @@ -924,9 +924,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); */ if (rc == -EOPNOTSUPP) { - cifs_server_dbg(VFS, "Dialect not supported by server. Consider " - "specifying vers=1.0 or vers=2.0 on mount for accessing" - " older servers\n"); + cifs_server_dbg(VFS, "Dialect not supported by server. Consider specifying vers=1.0 or vers=2.0 on mount for accessing older servers\n"); goto neg_exit; } else if (rc != 0) goto neg_exit; @@ -959,8 +957,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) } else if (le16_to_cpu(rsp->DialectRevision) != server->vals->protocol_id) { /* if requested single dialect ensure returned dialect matched */ - cifs_server_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", - le16_to_cpu(rsp->DialectRevision)); + cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n", + le16_to_cpu(rsp->DialectRevision)); return -EIO; } @@ -977,8 +975,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); else { - cifs_server_dbg(VFS, "Illegal dialect returned by server 0x%x\n", - le16_to_cpu(rsp->DialectRevision)); + cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n", + le16_to_cpu(rsp->DialectRevision)); rc = -EIO; goto neg_exit; } @@ -1136,15 +1134,16 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) rc = 0; goto out_free_inbuf; } else if (rc != 0) { - cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); + cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n", + rc); rc = -EIO; goto out_free_inbuf; } rc = -EIO; if (rsplen != sizeof(*pneg_rsp)) { - cifs_tcon_dbg(VFS, "invalid protocol negotiate response size: %d\n", - rsplen); + cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n", + rsplen); /* relax check since Mac returns max bufsize allowed on ioctl */ if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) @@ -1377,9 +1376,8 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) * sending us a response in an expected form */ if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) { - cifs_dbg(VFS, - "bad cifs.upcall version. Expected %d got %d", - CIFS_SPNEGO_UPCALL_VERSION, msg->version); + cifs_dbg(VFS, "bad cifs.upcall version. Expected %d got %d\n", + CIFS_SPNEGO_UPCALL_VERSION, msg->version); rc = -EKEYREJECTED; goto out_put_spnego_key; } @@ -1389,8 +1387,7 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len, GFP_KERNEL); if (!ses->auth_key.response) { - cifs_dbg(VFS, - "Kerberos can't allocate (%u bytes) memory", + cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n", msg->sesskey_len); rc = -ENOMEM; goto out_put_spnego_key; @@ -1604,8 +1601,7 @@ SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data) type = smb2_select_sectype(cifs_ses_server(ses), ses->sectype); cifs_dbg(FYI, "sess setup type %d\n", type); if (type == Unspecified) { - cifs_dbg(VFS, - "Unable to select appropriate authentication method!"); + cifs_dbg(VFS, "Unable to select appropriate authentication method!\n"); return -EINVAL; } @@ -2832,8 +2828,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, trace_smb3_open_err(xid, tcon->tid, ses->Suid, oparms->create_options, oparms->desired_access, rc); if (rc == -EREMCHG) { - printk_once(KERN_WARNING "server share %s deleted\n", - tcon->treeName); + pr_warn_once("server share %s deleted\n", + tcon->treeName); tcon->need_reconnect = true; } goto creat_exit; @@ -3245,7 +3241,7 @@ smb2_validate_iov(unsigned int offset, unsigned int buffer_length, } if ((begin_of_buf > end_of_smb) || (end_of_buf > end_of_smb)) { - cifs_dbg(VFS, "illegal server response, bad offset to data\n"); + cifs_dbg(VFS, "Invalid server response, bad offset to data\n"); return -EINVAL; } @@ -4128,8 +4124,8 @@ smb2_writev_callback(struct mid_q_entry *mid) tcon->tid, tcon->ses->Suid, wdata->offset, wdata->bytes, wdata->result); if (wdata->result == -ENOSPC) - printk_once(KERN_WARNING "Out of space writing to %s\n", - tcon->treeName); + pr_warn_once("Out of space writing to %s\n", + tcon->treeName); } else trace_smb3_write_done(0 /* no xid */, wdata->cfile->fid.persistent_fid, @@ -4652,7 +4648,7 @@ smb2_parse_query_directory(struct cifs_tcon *tcon, else if (resp_buftype == CIFS_SMALL_BUFFER) srch_inf->smallBuf = true; else - cifs_tcon_dbg(VFS, "illegal search buffer type\n"); + cifs_tcon_dbg(VFS, "Invalid search buffer type\n"); return 0; } diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 1a5834a5d597..b029ed31ef91 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -294,15 +294,12 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) static void dump_smbd_negotiate_resp(struct smbd_negotiate_resp *resp) { - log_rdma_event(INFO, "resp message min_version %u max_version %u " - "negotiated_version %u credits_requested %u " - "credits_granted %u status %u max_readwrite_size %u " - "preferred_send_size %u max_receive_size %u " - "max_fragmented_size %u\n", - resp->min_version, resp->max_version, resp->negotiated_version, - resp->credits_requested, resp->credits_granted, resp->status, - resp->max_readwrite_size, resp->preferred_send_size, - resp->max_receive_size, resp->max_fragmented_size); + log_rdma_event(INFO, "resp message min_version %u max_version %u negotiated_version %u credits_requested %u credits_granted %u status %u max_readwrite_size %u preferred_send_size %u max_receive_size %u max_fragmented_size %u\n", + resp->min_version, resp->max_version, + resp->negotiated_version, resp->credits_requested, + resp->credits_granted, resp->status, + resp->max_readwrite_size, resp->preferred_send_size, + resp->max_receive_size, resp->max_fragmented_size); } /* @@ -450,10 +447,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) struct smbd_connection *info = response->info; int data_length = 0; - log_rdma_recv(INFO, "response=%p type=%d wc status=%d wc opcode %d " - "byte_len=%d pkey_index=%x\n", - response, response->type, wc->status, wc->opcode, - wc->byte_len, wc->pkey_index); + log_rdma_recv(INFO, "response=%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%x\n", + response, response->type, wc->status, wc->opcode, + wc->byte_len, wc->pkey_index); if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { log_rdma_recv(INFO, "wc->status=%d opcode=%d\n", @@ -519,12 +515,11 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) wake_up_interruptible(&info->wait_send_queue); } - log_incoming(INFO, "data flags %d data_offset %d " - "data_length %d remaining_data_length %d\n", - le16_to_cpu(data_transfer->flags), - le32_to_cpu(data_transfer->data_offset), - le32_to_cpu(data_transfer->data_length), - le32_to_cpu(data_transfer->remaining_data_length)); + log_incoming(INFO, "data flags %d data_offset %d data_length %d remaining_data_length %d\n", + le16_to_cpu(data_transfer->flags), + le32_to_cpu(data_transfer->data_offset), + le32_to_cpu(data_transfer->data_length), + le32_to_cpu(data_transfer->remaining_data_length)); /* Send a KEEP_ALIVE response right away if requested */ info->keep_alive_requested = KEEP_ALIVE_NONE; @@ -632,14 +627,10 @@ static int smbd_ia_open( } if (!frwr_is_supported(&info->id->device->attrs)) { - log_rdma_event(ERR, - "Fast Registration Work Requests " - "(FRWR) is not supported\n"); - log_rdma_event(ERR, - "Device capability flags = %llx " - "max_fast_reg_page_list_len = %u\n", - info->id->device->attrs.device_cap_flags, - info->id->device->attrs.max_fast_reg_page_list_len); + log_rdma_event(ERR, "Fast Registration Work Requests (FRWR) is not supported\n"); + log_rdma_event(ERR, "Device capability flags = %llx max_fast_reg_page_list_len = %u\n", + info->id->device->attrs.device_cap_flags, + info->id->device->attrs.max_fast_reg_page_list_len); rc = -EPROTONOSUPPORT; goto out2; } @@ -898,13 +889,12 @@ wait_send_queue: packet->remaining_data_length = cpu_to_le32(remaining_data_length); packet->padding = 0; - log_outgoing(INFO, "credits_requested=%d credits_granted=%d " - "data_offset=%d data_length=%d remaining_data_length=%d\n", - le16_to_cpu(packet->credits_requested), - le16_to_cpu(packet->credits_granted), - le32_to_cpu(packet->data_offset), - le32_to_cpu(packet->data_length), - le32_to_cpu(packet->remaining_data_length)); + log_outgoing(INFO, "credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n", + le16_to_cpu(packet->credits_requested), + le16_to_cpu(packet->credits_granted), + le32_to_cpu(packet->data_offset), + le32_to_cpu(packet->data_length), + le32_to_cpu(packet->remaining_data_length)); /* Map the packet to DMA */ header_length = sizeof(struct smbd_data_transfer); @@ -1078,11 +1068,9 @@ static int smbd_negotiate(struct smbd_connection *info) response->type = SMBD_NEGOTIATE_RESP; rc = smbd_post_recv(info, response); - log_rdma_event(INFO, - "smbd_post_recv rc=%d iov.addr=%llx iov.length=%x " - "iov.lkey=%x\n", - rc, response->sge.addr, - response->sge.length, response->sge.lkey); + log_rdma_event(INFO, "smbd_post_recv rc=%d iov.addr=%llx iov.length=%x iov.lkey=%x\n", + rc, response->sge.addr, + response->sge.length, response->sge.lkey); if (rc) return rc; @@ -1540,25 +1528,19 @@ static struct smbd_connection *_smbd_get_connection( if (smbd_send_credit_target > info->id->device->attrs.max_cqe || smbd_send_credit_target > info->id->device->attrs.max_qp_wr) { - log_rdma_event(ERR, - "consider lowering send_credit_target = %d. " - "Possible CQE overrun, device " - "reporting max_cpe %d max_qp_wr %d\n", - smbd_send_credit_target, - info->id->device->attrs.max_cqe, - info->id->device->attrs.max_qp_wr); + log_rdma_event(ERR, "consider lowering send_credit_target = %d. Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", + smbd_send_credit_target, + info->id->device->attrs.max_cqe, + info->id->device->attrs.max_qp_wr); goto config_failed; } if (smbd_receive_credit_max > info->id->device->attrs.max_cqe || smbd_receive_credit_max > info->id->device->attrs.max_qp_wr) { - log_rdma_event(ERR, - "consider lowering receive_credit_max = %d. " - "Possible CQE overrun, device " - "reporting max_cpe %d max_qp_wr %d\n", - smbd_receive_credit_max, - info->id->device->attrs.max_cqe, - info->id->device->attrs.max_qp_wr); + log_rdma_event(ERR, "consider lowering receive_credit_max = %d. Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", + smbd_receive_credit_max, + info->id->device->attrs.max_cqe, + info->id->device->attrs.max_qp_wr); goto config_failed; } @@ -1865,11 +1847,9 @@ again: to_read -= to_copy; data_read += to_copy; - log_read(INFO, "_get_first_reassembly memcpy %d bytes " - "data_transfer_length-offset=%d after that " - "to_read=%d data_read=%d offset=%d\n", - to_copy, data_length - offset, - to_read, data_read, offset); + log_read(INFO, "_get_first_reassembly memcpy %d bytes data_transfer_length-offset=%d after that to_read=%d data_read=%d offset=%d\n", + to_copy, data_length - offset, + to_read, data_read, offset); } spin_lock_irq(&info->reassembly_queue_lock); @@ -1878,10 +1858,9 @@ again: spin_unlock_irq(&info->reassembly_queue_lock); info->first_entry_offset = offset; - log_read(INFO, "returning to thread data_read=%d " - "reassembly_data_length=%d first_entry_offset=%d\n", - data_read, info->reassembly_data_length, - info->first_entry_offset); + log_read(INFO, "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n", + data_read, info->reassembly_data_length, + info->first_entry_offset); read_rfc1002_done: return data_read; } @@ -1952,7 +1931,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg) if (iov_iter_rw(&msg->msg_iter) == WRITE) { /* It's a bug in upper layer to get there */ - cifs_dbg(VFS, "CIFS: invalid msg iter dir %u\n", + cifs_dbg(VFS, "Invalid msg iter dir %u\n", iov_iter_rw(&msg->msg_iter)); rc = -EINVAL; goto out; @@ -1974,7 +1953,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg) default: /* It's a bug in upper layer to get there */ - cifs_dbg(VFS, "CIFS: invalid msg type %d\n", + cifs_dbg(VFS, "Invalid msg type %d\n", iov_iter_type(&msg->msg_iter)); rc = -EINVAL; } @@ -2043,10 +2022,9 @@ next_rqst: dump_smb(iov[i].iov_base, iov[i].iov_len); - log_write(INFO, "rqst_idx=%d nvec=%d rqst->rq_npages=%d rq_pagesz=%d " - "rq_tailsz=%d buflen=%lu\n", - rqst_idx, rqst->rq_nvec, rqst->rq_npages, rqst->rq_pagesz, - rqst->rq_tailsz, smb_rqst_len(server, rqst)); + log_write(INFO, "rqst_idx=%d nvec=%d rqst->rq_npages=%d rq_pagesz=%d rq_tailsz=%d buflen=%lu\n", + rqst_idx, rqst->rq_nvec, rqst->rq_npages, rqst->rq_pagesz, + rqst->rq_tailsz, smb_rqst_len(server, rqst)); start = i = 0; buflen = 0; @@ -2056,11 +2034,9 @@ next_rqst: if (i > start) { remaining_data_length -= (buflen-iov[i].iov_len); - log_write(INFO, "sending iov[] from start=%d " - "i=%d nvecs=%d " - "remaining_data_length=%d\n", - start, i, i-start, - remaining_data_length); + log_write(INFO, "sending iov[] from start=%d i=%d nvecs=%d remaining_data_length=%d\n", + start, i, i - start, + remaining_data_length); rc = smbd_post_send_data( info, &iov[start], i-start, remaining_data_length); @@ -2069,10 +2045,9 @@ next_rqst: } else { /* iov[start] is too big, break it */ nvecs = (buflen+max_iov_size-1)/max_iov_size; - log_write(INFO, "iov[%d] iov_base=%p buflen=%d" - " break to %d vectors\n", - start, iov[start].iov_base, - buflen, nvecs); + log_write(INFO, "iov[%d] iov_base=%p buflen=%d break to %d vectors\n", + start, iov[start].iov_base, + buflen, nvecs); for (j = 0; j < nvecs; j++) { vec.iov_base = (char *)iov[start].iov_base + @@ -2084,11 +2059,9 @@ next_rqst: max_iov_size*(nvecs-1); remaining_data_length -= vec.iov_len; log_write(INFO, - "sending vec j=%d iov_base=%p" - " iov_len=%zu " - "remaining_data_length=%d\n", - j, vec.iov_base, vec.iov_len, - remaining_data_length); + "sending vec j=%d iov_base=%p iov_len=%zu remaining_data_length=%d\n", + j, vec.iov_base, vec.iov_len, + remaining_data_length); rc = smbd_post_send_data( info, &vec, 1, remaining_data_length); @@ -2106,11 +2079,9 @@ next_rqst: if (i == rqst->rq_nvec) { /* send out all remaining vecs */ remaining_data_length -= buflen; - log_write(INFO, - "sending iov[] from start=%d i=%d " - "nvecs=%d remaining_data_length=%d\n", - start, i, i-start, - remaining_data_length); + log_write(INFO, "sending iov[] from start=%d i=%d nvecs=%d remaining_data_length=%d\n", + start, i, i - start, + remaining_data_length); rc = smbd_post_send_data(info, &iov[start], i-start, remaining_data_length); if (rc) @@ -2134,10 +2105,9 @@ next_rqst: if (j == nvecs-1) size = buflen - j*max_iov_size; remaining_data_length -= size; - log_write(INFO, "sending pages i=%d offset=%d size=%d" - " remaining_data_length=%d\n", - i, j*max_iov_size+offset, size, - remaining_data_length); + log_write(INFO, "sending pages i=%d offset=%d size=%d remaining_data_length=%d\n", + i, j * max_iov_size + offset, size, + remaining_data_length); rc = smbd_post_send_page( info, rqst->rq_pages[i], j*max_iov_size + offset, @@ -2211,11 +2181,9 @@ static void smbd_mr_recovery_work(struct work_struct *work) info->pd, info->mr_type, info->max_frmr_depth); if (IS_ERR(smbdirect_mr->mr)) { - log_rdma_mr(ERR, - "ib_alloc_mr failed mr_type=%x " - "max_frmr_depth=%x\n", - info->mr_type, - info->max_frmr_depth); + log_rdma_mr(ERR, "ib_alloc_mr failed mr_type=%x max_frmr_depth=%x\n", + info->mr_type, + info->max_frmr_depth); smbd_disconnect_rdma_connection(info); continue; } @@ -2278,9 +2246,8 @@ static int allocate_mr_list(struct smbd_connection *info) smbdirect_mr->mr = ib_alloc_mr(info->pd, info->mr_type, info->max_frmr_depth); if (IS_ERR(smbdirect_mr->mr)) { - log_rdma_mr(ERR, "ib_alloc_mr failed mr_type=%x " - "max_frmr_depth=%x\n", - info->mr_type, info->max_frmr_depth); + log_rdma_mr(ERR, "ib_alloc_mr failed mr_type=%x max_frmr_depth=%x\n", + info->mr_type, info->max_frmr_depth); goto out; } smbdirect_mr->sgl = kcalloc( diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index c97570eb2c18..c359221d6848 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -112,7 +112,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) #ifdef CONFIG_CIFS_STATS2 now = jiffies; if (now < midEntry->when_alloc) - cifs_server_dbg(VFS, "invalid mid allocation time\n"); + cifs_server_dbg(VFS, "Invalid mid allocation time\n"); roundtrip_time = now - midEntry->when_alloc; if (smb_cmd < NUMBER_OF_SMB2_COMMANDS) { @@ -151,12 +151,12 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) trace_smb3_slow_rsp(smb_cmd, midEntry->mid, midEntry->pid, midEntry->when_sent, midEntry->when_received); if (cifsFYI & CIFS_TIMER) { - pr_debug(" CIFS slow rsp: cmd %d mid %llu", - midEntry->command, midEntry->mid); - cifs_info(" A: 0x%lx S: 0x%lx R: 0x%lx\n", - now - midEntry->when_alloc, - now - midEntry->when_sent, - now - midEntry->when_received); + pr_debug("slow rsp: cmd %d mid %llu", + midEntry->command, midEntry->mid); + cifs_info("A: 0x%lx S: 0x%lx R: 0x%lx\n", + now - midEntry->when_alloc, + now - midEntry->when_sent, + now - midEntry->when_received); } } #endif @@ -477,8 +477,7 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, return -ENOMEM; if (!server->ops->init_transform_rq) { - cifs_server_dbg(VFS, "Encryption requested but transform " - "callback is missing\n"); + cifs_server_dbg(VFS, "Encryption requested but transform callback is missing\n"); return -EIO; } @@ -1300,8 +1299,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, use ses->maxReq */ if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { - cifs_server_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", - len); + cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", + len); return -EIO; } @@ -1441,8 +1440,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, use ses->maxReq */ if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { - cifs_tcon_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", - len); + cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", + len); return -EIO; } -- cgit v1.2.3 From adbb2dafe732d4715a602ca727dedaa55c0df7a7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 30 May 2020 16:45:11 -0500 Subject: cifs: minor fix to two debug messages Joe Perches pointed out that we were missing a newline at the end of two debug messages Reported-by: Joe Perches Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 2 +- fs/cifs/smb2pdu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5820f9569b7f..bf41ee048396 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -177,7 +177,7 @@ 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: %.*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); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 4b79181ff872..06463f386a60 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -209,7 +209,7 @@ static int __smb2_reconnect(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: %.*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); -- cgit v1.2.3 From 3563a6f4683eb08f9a437e028dd027ac31092381 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 30 May 2020 17:10:16 -0500 Subject: smb3: minor update to compression header definitions MS-SMB2 specification was updated in March. Make minor additions and corrections to compression related definitions in smb2pdu.h Signed-off-by: Steve French Reviewed-by: Aurelien Aptel --- fs/cifs/smb2pdu.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 10acf90f858d..3b0e6acf9d7d 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -143,8 +143,17 @@ struct smb2_transform_hdr { __u64 SessionId; } __packed; +/* See MS-SMB2 2.2.42 */ +struct smb2_compression_transform_hdr { + __le32 ProtocolId; /* 0xFC 'S' 'M' 'B' */ + __le32 OriginalCompressedSegmentSize; + __le16 CompressionAlgorithm; + __le16 Flags; + __le16 Length; /* if chained it is length, else offset */ +} __packed; + /* See MS-SMB2 2.2.42.1 */ -struct compression_playload_header { +struct compression_payload_header { __le16 AlgorithmId; __le16 Reserved; __le32 Length; @@ -333,7 +342,7 @@ struct smb2_encryption_neg_context { #define SMB3_COMPRESS_LZ77 cpu_to_le16(0x0002) #define SMB3_COMPRESS_LZ77_HUFF cpu_to_le16(0x0003) /* Pattern scanning algorithm See MS-SMB2 3.1.4.4.1 */ -#define SMB3_COMPRESS_PATTERN cpu_to_le16(0x0004) +#define SMB3_COMPRESS_PATTERN cpu_to_le16(0x0004) /* Pattern_V1 */ /* Compression Flags */ #define SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE cpu_to_le32(0x00000000) -- cgit v1.2.3 From bbbf9eafbfdaa2af75fb5ed6d5ddb01be89e6d30 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 30 May 2020 17:29:50 -0500 Subject: cifs: fix minor typos in comments and log messages Fix four minor typos in comments and log messages Signed-off-by: Steve French Reviewed-by: Aurelien Aptel --- fs/cifs/sess.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 3f8b43e77539..0ae25cc77fc0 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -122,7 +122,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses) tries++; if (tries > 3*ses->chan_max) { - cifs_dbg(FYI, "too many attempt at opening channels (%d channels left to open)\n", + cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n", left); break; } @@ -200,7 +200,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) vol.UNC = unc; vol.prepath = ""; - /* Re-use same version as master connection */ + /* Reuse same version as master connection */ vol.vals = ses->server->vals; vol.ops = ses->server->ops; @@ -263,7 +263,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) goto out; /* success, put it on the list - * XXX: sharing ses between 2 tcp server is not possible, the + * XXX: sharing ses between 2 tcp servers is not possible, the * way "internal" linked lists works in linux makes element * only able to belong to one list * @@ -972,7 +972,7 @@ sess_auth_lanman(struct sess_data *sess_data) /* Calculate hash with password and copy into bcc_ptr. * Encryption Key (stored as in cryptkey) gets used if the - * security mode bit in Negottiate Protocol response states + * security mode bit in Negotiate Protocol response states * to use challenge/response method (i.e. Password bit is 1). */ rc = calc_lanman_hash(ses->password, ses->server->cryptkey, -- cgit v1.2.3 From 5f68ea4aa98bcddb5ec5229d2a0933d84ed17732 Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Wed, 22 Apr 2020 15:58:57 +0200 Subject: cifs: multichannel: move channel selection in function This commit moves channel picking code in separate function. Signed-off-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 1 + fs/cifs/transport.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 8036216ce434..9767f9b5d315 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -96,6 +96,7 @@ extern int cifs_call_async(struct TCP_Server_Info *server, 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 smb_rqst *rqst, int *resp_buf_type, const int flags, struct kvec *resp_iov); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index c359221d6848..4d4cb26d2ae1 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -992,6 +992,32 @@ cifs_cancelled_callback(struct mid_q_entry *mid) DeleteMidQEntry(mid); } +/* + * Return a channel (master if none) of @ses that can be used to send + * regular requests. + * + * If we are currently binding a new channel (negprot/sess.setup), + * return the new incomplete channel. + */ +struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) +{ + uint index = 0; + + if (!ses) + return NULL; + + if (!ses->binding) { + /* round robin */ + if (ses->chan_count > 1) { + index = (uint)atomic_inc_return(&ses->chan_seq); + index %= ses->chan_count; + } + return ses->chans[index].server; + } else { + return cifs_ses_server(ses); + } +} + int compound_send_recv(const unsigned int xid, struct cifs_ses *ses, const int flags, const int num_rqst, struct smb_rqst *rqst, @@ -1017,17 +1043,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, return -EIO; } - if (!ses->binding) { - uint index = 0; - - if (ses->chan_count > 1) { - index = (uint)atomic_inc_return(&ses->chan_seq); - index %= ses->chan_count; - } - server = ses->chans[index].server; - } else { - server = cifs_ses_server(ses); - } + server = cifs_pick_channel(ses); if (server->tcpStatus == CifsExiting) return -ENOENT; -- cgit v1.2.3 From 1ee0e6d47d08ef309e0975a96d643972855511d0 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 2 Jun 2020 23:17:16 -0500 Subject: smb3: default to minimum of two channels when multichannel specified When "multichannel" is specified on mount, make sure to default to at least two channels. Signed-off-by: Steve French Reviewed-by: Ronnie Sahlberg --- fs/cifs/connect.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/cifs') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index daf90f988de1..fdfd7cf4c720 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1964,9 +1964,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, break; case Opt_multichannel: vol->multichannel = true; + /* if number of channels not specified, default to 2 */ + if (vol->max_channels < 2) + vol->max_channels = 2; break; case Opt_nomultichannel: vol->multichannel = false; + vol->max_channels = 1; break; case Opt_compress: vol->compression = UNKNOWN_TYPE; -- cgit v1.2.3 From e80ddeb2f70ebd0786aa7cdba3e58bc931fa0bb5 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 3 Jun 2020 01:33:58 -0500 Subject: smb3: fix incorrect number of credits when ioctl MaxOutputResponse > 64K We were not checking to see if ioctl requests asked for more than 64K (ie when CIFSMaxBufSize was > 64K) so when setting larger CIFSMaxBufSize then ioctls would fail with invalid parameter errors. When requests ask for more than 64K in MaxOutputResponse then we need to ask for more than 1 credit. Signed-off-by: Steve French CC: Stable Reviewed-by: Aurelien Aptel --- fs/cifs/smb2pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/cifs') diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 06463f386a60..12de0af12f75 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2938,7 +2938,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, * response size smaller. */ req->MaxOutputResponse = cpu_to_le32(max_response_size); - + req->sync_hdr.CreditCharge = cpu_to_le16(DIV_ROUND_UP(max_response_size, SMB2_MAX_BUFFER_SIZE)); if (is_fsctl) req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); else -- cgit v1.2.3 From 8e84a61a9c5ce55c5707448bb3c2cc544fccaa21 Mon Sep 17 00:00:00 2001 From: Kenneth D'souza Date: Thu, 4 Jun 2020 21:14:41 +0530 Subject: cifs: dump Security Type info in DebugData Currently the end user is unaware with what sec type the cifs share is mounted if no sec= option is parsed. With this patch one can easily check from DebugData. Example: 1) Name: x.x.x.x Uses: 1 Capability: 0x8001f3fc Session Status: 1 Security type: RawNTLMSSP Signed-off-by: Kenneth D'souza Signed-off-by: Roberto Bergantinos Corpas Signed-off-by: Steve French Acked-by: Aurelien Aptel --- fs/cifs/cifs_debug.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/cifs') 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 " -- cgit v1.2.3 From 7c06514afd38ed7a4b83edfd39ab033c804b4cf3 Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Thu, 4 Jun 2020 17:23:55 +0200 Subject: cifs: multichannel: always zero struct cifs_io_parms SMB2_read/SMB2_write check and use cifs_io_parms->server, which might be uninitialized memory. This change makes all callers zero-initialize the struct. Signed-off-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/file.c | 4 ++-- fs/cifs/inode.c | 2 +- fs/cifs/link.c | 6 +++--- fs/cifs/smb2ops.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 226bfa5e9444..de130f3aa452 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1853,7 +1853,7 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, unsigned int xid; struct dentry *dentry = open_file->dentry; struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry)); - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n", write_size, *offset, dentry); @@ -4014,7 +4014,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) unsigned int xid; char *cur_offset; struct cifsFileInfo *open_file; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; int buf_type = CIFS_NO_BUFFER; __u32 pid; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b94c6398da94..5416ff339401 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -447,7 +447,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, struct cifs_tcon *tcon; struct cifs_fid fid; struct cifs_open_parms oparms; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; char buf[24]; unsigned int bytes_read; char *pbuf; diff --git a/fs/cifs/link.c b/fs/cifs/link.c index a25ef35b023e..2072458e6e24 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -308,7 +308,7 @@ cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int oplock = 0; struct cifs_fid fid; struct cifs_open_parms oparms; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; int buf_type = CIFS_NO_BUFFER; FILE_ALL_INFO file_info; @@ -352,7 +352,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int oplock = 0; struct cifs_fid fid; struct cifs_open_parms oparms; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; @@ -389,7 +389,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int rc; struct cifs_fid fid; struct cifs_open_parms oparms; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; int buf_type = CIFS_NO_BUFFER; __le16 *utf16_path; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index dec055d7c2f4..49c5c80f5d36 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4584,7 +4584,7 @@ smb2_make_node(unsigned int xid, struct inode *inode, struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); int rc = -EPERM; FILE_ALL_INFO *buf = NULL; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; __u32 oplock = 0; struct cifs_fid fid; struct cifs_open_parms oparms; -- cgit v1.2.3 From 352d96f3acc6e02099f58a24d5cabce7f8ee061f Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Sun, 31 May 2020 12:38:22 -0500 Subject: cifs: multichannel: move channel selection above transport layer Move the channel (TCP_Server_Info*) selection from the tranport layer to higher in the call stack so that: - credit handling is done with the server that will actually be used to send. * ->wait_mtu_credit * ->set_credits / set_credits * ->add_credits / add_credits * add_credits_and_wake_if - potential reconnection (smb2_reconnect) done when initializing a request is checked and done with the server that will actually be used to send. To do this: - remove the cifs_pick_channel() call out of compound_send_recv() - select channel and pass it down by adding a cifs_pick_channel(ses) call in: - smb311_posix_mkdir - SMB2_open - SMB2_ioctl - __SMB2_close - query_info - SMB2_change_notify - SMB2_flush - smb2_async_readv (if none provided in context param) - SMB2_read (if none provided in context param) - smb2_async_writev (if none provided in context param) - SMB2_write (if none provided in context param) - SMB2_query_directory - send_set_info - SMB2_oplock_break - SMB311_posix_qfs_info - SMB2_QFS_info - SMB2_QFS_attr - smb2_lockv - SMB2_lease_break - smb2_compound_op - smb2_set_ea - smb2_ioctl_query_info - smb2_query_dir_first - smb2_query_info_comound - smb2_query_symlink - cifs_writepages - cifs_write_from_iter - cifs_send_async_read - cifs_read - cifs_readpages - add TCP_Server_Info *server param argument to: - cifs_send_recv - compound_send_recv - SMB2_open_init - SMB2_query_info_init - SMB2_set_info_init - SMB2_close_init - SMB2_ioctl_init - smb2_iotcl_req_init - SMB2_query_directory_init - SMB2_notify_init - SMB2_flush_init - build_qfs_info_req - smb2_hdr_assemble - smb2_reconnect - fill_small_buf - smb2_plain_req_init - __smb2_plain_req_init The read/write codepath is different than the rest as it is using pages, io iterators and async calls. To deal with those we add a server pointer in the cifs_writedata/cifs_readdata/cifs_io_parms context struct and set it in: - cifs_writepages (wdata) - cifs_write_from_iter (wdata) - cifs_readpages (rdata) - cifs_send_async_read (rdata) The [rw]data->server pointer is eventually copied to cifs_io_parms->server to pass it down to SMB2_read/SMB2_write. If SMB2_read/SMB2_write is called from a different place that doesn't set the server field it will pick a channel. Some places do not pick a channel and just use ses->server or cifs_ses_server(ses). All cifs_ses_server(ses) calls are in codepaths involving negprot/sess.setup. - SMB2_negotiate (binding channel) - SMB2_sess_alloc_buffer (binding channel) - SMB2_echo (uses provided one) - SMB2_logoff (uses master) - SMB2_tdis (uses master) (list not exhaustive) Signed-off-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 3 + fs/cifs/cifsproto.h | 2 + fs/cifs/file.c | 32 +++-- fs/cifs/link.c | 2 +- fs/cifs/smb2inode.c | 44 ++++--- fs/cifs/smb2ops.c | 79 ++++++++---- fs/cifs/smb2pdu.c | 353 ++++++++++++++++++++++++++++++++-------------------- fs/cifs/smb2proto.h | 25 +++- fs/cifs/transport.c | 14 +-- 9 files changed, 356 insertions(+), 198 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 4d261fd78fcb..c0cbbd0bbb1d 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1335,6 +1335,7 @@ struct cifs_io_parms { __u64 offset; unsigned int length; struct cifs_tcon *tcon; + struct TCP_Server_Info *server; }; struct cifs_aio_ctx { @@ -1382,6 +1383,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 @@ -1408,6 +1410,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 9767f9b5d315..a25a46237f9f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -98,9 +98,11 @@ extern int cifs_call_async(struct TCP_Server_Info *server, 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); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index de130f3aa452..2ca9b387d216 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2292,8 +2292,6 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages, struct address_space *mapping, struct writeback_control *wbc) { int rc; - struct TCP_Server_Info *server = - tlink_tcon(wdata->cfile->tlink)->ses->server; wdata->sync_mode = wbc->sync_mode; wdata->nr_pages = nr_pages; @@ -2305,14 +2303,15 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages, wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz; wdata->pid = wdata->cfile->pid; - rc = adjust_credits(server, &wdata->credits, wdata->bytes); + rc = adjust_credits(wdata->server, &wdata->credits, wdata->bytes); if (rc) return rc; if (wdata->cfile->invalidHandle) rc = -EAGAIN; else - rc = server->ops->async_writev(wdata, cifs_writedata_release); + rc = wdata->server->ops->async_writev(wdata, + cifs_writedata_release); return rc; } @@ -2349,7 +2348,8 @@ static int cifs_writepages(struct address_space *mapping, range_whole = true; scanned = true; } - server = cifs_sb_master_tcon(cifs_sb)->ses->server; + server = cifs_pick_channel(cifs_sb_master_tcon(cifs_sb)->ses); + retry: while (!done && index <= end) { unsigned int i, nr_pages, found_pages, wsize; @@ -2403,6 +2403,7 @@ retry: wdata->credits = credits_on_stack; wdata->cfile = cfile; + wdata->server = server; cfile = NULL; if (!wdata->cfile) { @@ -2806,8 +2807,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list, unsigned int wsize; struct cifs_credits credits; int rc; - struct TCP_Server_Info *server = - tlink_tcon(wdata->cfile->tlink)->ses->server; + struct TCP_Server_Info *server = wdata->server; do { if (wdata->cfile->invalidHandle) { @@ -2893,7 +2893,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, else pid = current->tgid; - server = tlink_tcon(open_file->tlink)->ses->server; + server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses); xid = get_xid(); do { @@ -2997,6 +2997,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, wdata->nr_pages = nr_pages; wdata->offset = (__u64)offset; wdata->cfile = cifsFileInfo_get(open_file); + wdata->server = server; wdata->pid = pid; wdata->bytes = cur_len; wdata->pagesz = PAGE_SIZE; @@ -3538,8 +3539,10 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata, unsigned int rsize; struct cifs_credits credits; int rc; - struct TCP_Server_Info *server = - tlink_tcon(rdata->cfile->tlink)->ses->server; + struct TCP_Server_Info *server; + + /* XXX: should we pick a new channel here? */ + server = rdata->server; do { if (rdata->cfile->invalidHandle) { @@ -3618,7 +3621,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, size_t start; struct iov_iter direct_iov = ctx->iter; - server = tlink_tcon(open_file->tlink)->ses->server; + server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) pid = open_file->pid; @@ -3702,6 +3705,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, rdata->tailsz = PAGE_SIZE; } + rdata->server = server; rdata->cfile = cifsFileInfo_get(open_file); rdata->nr_pages = npages; rdata->offset = offset; @@ -4031,7 +4035,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) } open_file = file->private_data; tcon = tlink_tcon(open_file->tlink); - server = tcon->ses->server; + server = cifs_pick_channel(tcon->ses); if (!server->ops->sync_read) { free_xid(xid); @@ -4070,6 +4074,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) io_parms.tcon = tcon; io_parms.offset = *offset; io_parms.length = current_read_size; + io_parms.server = server; rc = server->ops->sync_read(xid, &open_file->fid, &io_parms, &bytes_read, &cur_offset, &buf_type); @@ -4372,7 +4377,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, pid = current->tgid; rc = 0; - server = tlink_tcon(open_file->tlink)->ses->server; + server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses); cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n", __func__, file, mapping, num_pages); @@ -4443,6 +4448,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, } rdata->cfile = cifsFileInfo_get(open_file); + rdata->server = server; rdata->mapping = mapping; rdata->offset = offset; rdata->bytes = bytes; diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 2072458e6e24..c381d2d03ef6 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -450,7 +450,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int rc; struct cifs_fid fid; struct cifs_open_parms oparms; - struct cifs_io_parms io_parms; + struct cifs_io_parms io_parms = {0}; __le16 *utf16_path; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct kvec iov[2]; diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index fa86c78384c3..0a116fc490a9 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -74,6 +74,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_fid fid; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server; int num_rqst = 0; int resp_buftype[3]; struct smb2_query_info_rsp *qi_rsp = NULL; @@ -89,6 +90,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, rqst = &vars->rqst[0]; rsp_iov = &vars->rsp_iov[0]; + server = cifs_pick_channel(ses); + if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; @@ -115,7 +118,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, rqst[num_rqst].rq_iov = &vars->open_iov[0]; rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE; - rc = SMB2_open_init(tcon, &rqst[num_rqst], &oplock, &vars->oparms, + rc = SMB2_open_init(tcon, server, + &rqst[num_rqst], &oplock, &vars->oparms, utf16_path); kfree(utf16_path); if (rc) @@ -133,7 +137,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, rqst[num_rqst].rq_nvec = 1; if (cfile) - rc = SMB2_query_info_init(tcon, &rqst[num_rqst], + rc = SMB2_query_info_init(tcon, server, + &rqst[num_rqst], cfile->fid.persistent_fid, cfile->fid.volatile_fid, FILE_ALL_INFORMATION, @@ -141,10 +146,11 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, sizeof(struct smb2_file_all_info) + PATH_MAX * 2, 0, NULL); else { - rc = SMB2_query_info_init(tcon, &rqst[num_rqst], + rc = SMB2_query_info_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, - FILE_ALL_INFORMATION, + FILE_ALL_INFORMATION, SMB2_O_INFO_FILE, 0, sizeof(struct smb2_file_all_info) + PATH_MAX * 2, 0, NULL); @@ -177,7 +183,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */ data[0] = &delete_pending[0]; - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_DISPOSITION_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); @@ -194,7 +201,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, size[0] = 8; /* sizeof __le64 */ data[0] = ptr; - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); @@ -213,13 +221,15 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, data[0] = ptr; if (cfile) - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], cfile->fid.persistent_fid, cfile->fid.volatile_fid, current->tgid, FILE_BASIC_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); else { - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_BASIC_INFORMATION, @@ -253,13 +263,15 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, data[1] = (__le16 *)ptr; if (cfile) - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], cfile->fid.persistent_fid, cfile->fid.volatile_fid, current->tgid, FILE_RENAME_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); else { - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_RENAME_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); @@ -289,7 +301,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, size[1] = len + 2 /* null */; data[1] = (__le16 *)ptr; - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_LINK_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); @@ -312,7 +325,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, /* Close */ rqst[num_rqst].rq_iov = &vars->close_iov[0]; rqst[num_rqst].rq_nvec = 1; - rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID, + rc = SMB2_close_init(tcon, server, + &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, false); smb2_set_related(&rqst[num_rqst]); if (rc) @@ -323,11 +337,13 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, if (cfile) { cifsFileInfo_put(cfile); cfile = NULL; - rc = compound_send_recv(xid, ses, flags, num_rqst - 2, + rc = compound_send_recv(xid, ses, server, + flags, num_rqst - 2, &rqst[1], &resp_buftype[1], &rsp_iov[1]); } else - rc = compound_send_recv(xid, ses, flags, num_rqst, + rc = compound_send_recv(xid, ses, server, + flags, num_rqst, rqst, resp_buftype, rsp_iov); diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 49c5c80f5d36..e97eb0050a0e 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -708,7 +708,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, oparms.fid = pfid; oparms.reconnect = false; - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &utf16_path); + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, &utf16_path); if (rc) goto oshr_free; smb2_set_next_command(tcon, &rqst[0]); @@ -717,7 +718,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, rqst[1].rq_iov = qi_iov; rqst[1].rq_nvec = 1; - rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, + rc = SMB2_query_info_init(tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, FILE_ALL_INFORMATION, SMB2_O_INFO_FILE, 0, sizeof(struct smb2_file_all_info) + @@ -727,7 +729,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[1]); - rc = compound_send_recv(xid, ses, flags, 2, rqst, + rc = compound_send_recv(xid, ses, server, + flags, 2, rqst, resp_buftype, rsp_iov); mutex_lock(&tcon->crfid.fid_mutex); @@ -1102,6 +1105,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb) { struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); __le16 *utf16_path = NULL; int ea_name_len = strlen(ea_name); int flags = 0; @@ -1190,7 +1194,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, oparms.fid = &fid; oparms.reconnect = false; - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path); + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, utf16_path); if (rc) goto sea_exit; smb2_set_next_command(tcon, &rqst[0]); @@ -1216,7 +1221,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, size[0] = len; data[0] = ea; - rc = SMB2_set_info_init(tcon, &rqst[1], COMPOUND_FID, + rc = SMB2_set_info_init(tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); @@ -1228,10 +1234,12 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, memset(&close_iov, 0, sizeof(close_iov)); rqst[2].rq_iov = close_iov; rqst[2].rq_nvec = 1; - rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); + rc = SMB2_close_init(tcon, server, + &rqst[2], COMPOUND_FID, COMPOUND_FID, false); smb2_set_related(&rqst[2]); - rc = compound_send_recv(xid, ses, flags, 3, rqst, + rc = compound_send_recv(xid, ses, server, + flags, 3, rqst, resp_buftype, rsp_iov); /* no need to bump num_remote_opens because handle immediately closed */ @@ -1473,6 +1481,7 @@ smb2_ioctl_query_info(const unsigned int xid, struct smb_rqst *rqst; struct kvec *rsp_iov; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); char __user *arg = (char __user *)p; struct smb_query_info qi; struct smb_query_info __user *pqi; @@ -1505,7 +1514,7 @@ smb2_ioctl_query_info(const unsigned int xid, return -EINVAL; } - if (!ses || !(ses->server)) { + if (!ses || !server) { kfree(vars); return -EIO; } @@ -1552,7 +1561,8 @@ smb2_ioctl_query_info(const unsigned int xid, oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL; } - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, path); + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, path); if (rc) goto iqinf_exit; smb2_set_next_command(tcon, &rqst[0]); @@ -1566,7 +1576,8 @@ smb2_ioctl_query_info(const unsigned int xid, rqst[1].rq_iov = &vars->io_iov[0]; rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; - rc = SMB2_ioctl_init(tcon, &rqst[1], + rc = SMB2_ioctl_init(tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, qi.info_type, true, buffer, qi.output_buffer_length, @@ -1585,7 +1596,8 @@ smb2_ioctl_query_info(const unsigned int xid, size[0] = 8; data[0] = buffer; - rc = SMB2_set_info_init(tcon, &rqst[1], + rc = SMB2_set_info_init(tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_END_OF_FILE_INFORMATION, @@ -1595,7 +1607,8 @@ smb2_ioctl_query_info(const unsigned int xid, rqst[1].rq_iov = &vars->qi_iov[0]; rqst[1].rq_nvec = 1; - rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, + rc = SMB2_query_info_init(tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, qi.file_info_class, qi.info_type, qi.additional_information, qi.input_buffer_length, @@ -1615,12 +1628,14 @@ smb2_ioctl_query_info(const unsigned int xid, rqst[2].rq_iov = &vars->close_iov[0]; rqst[2].rq_nvec = 1; - rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); + rc = SMB2_close_init(tcon, server, + &rqst[2], COMPOUND_FID, COMPOUND_FID, false); if (rc) goto iqinf_exit; smb2_set_related(&rqst[2]); - rc = compound_send_recv(xid, ses, flags, 3, rqst, + rc = compound_send_recv(xid, ses, server, + flags, 3, rqst, resp_buftype, rsp_iov); if (rc) goto iqinf_exit; @@ -2172,6 +2187,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_open_parms oparms; struct smb2_query_directory_rsp *qd_rsp = NULL; struct smb2_create_rsp *op_rsp = NULL; + struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); if (!utf16_path) @@ -2196,7 +2212,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, oparms.fid = fid; oparms.reconnect = false; - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path); + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, utf16_path); if (rc) goto qdf_free; smb2_set_next_command(tcon, &rqst[0]); @@ -2209,7 +2226,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, rqst[1].rq_iov = qd_iov; rqst[1].rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE; - rc = SMB2_query_directory_init(xid, tcon, &rqst[1], + rc = SMB2_query_directory_init(xid, tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, 0, srch_inf->info_level); if (rc) @@ -2217,7 +2235,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[1]); - rc = compound_send_recv(xid, tcon->ses, flags, 2, rqst, + rc = compound_send_recv(xid, tcon->ses, server, + flags, 2, rqst, resp_buftype, rsp_iov); /* If the open failed there is nothing to do */ @@ -2422,6 +2441,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb) { struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); int flags = 0; struct smb_rqst rqst[3]; int resp_buftype[3]; @@ -2452,7 +2472,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, oparms.fid = &fid; oparms.reconnect = false; - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path); + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, utf16_path); if (rc) goto qic_exit; smb2_set_next_command(tcon, &rqst[0]); @@ -2461,7 +2482,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, rqst[1].rq_iov = qi_iov; rqst[1].rq_nvec = 1; - rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, COMPOUND_FID, + rc = SMB2_query_info_init(tcon, server, + &rqst[1], COMPOUND_FID, COMPOUND_FID, class, type, 0, output_len, 0, NULL); @@ -2474,12 +2496,14 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, rqst[2].rq_iov = close_iov; rqst[2].rq_nvec = 1; - rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); + rc = SMB2_close_init(tcon, server, + &rqst[2], COMPOUND_FID, COMPOUND_FID, false); if (rc) goto qic_exit; smb2_set_related(&rqst[2]); - rc = compound_send_recv(xid, ses, flags, 3, rqst, + rc = compound_send_recv(xid, ses, server, + flags, 3, rqst, resp_buftype, rsp_iov); if (rc) { free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); @@ -2811,6 +2835,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, struct kvec err_iov = {NULL, 0}; struct smb2_err_rsp *err_buf = NULL; struct smb2_symlink_err_rsp *symlink; + struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); unsigned int sub_len; unsigned int sub_offset; unsigned int print_len; @@ -2856,7 +2881,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, oparms.fid = &fid; oparms.reconnect = false; - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path); + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, utf16_path); if (rc) goto querty_exit; smb2_set_next_command(tcon, &rqst[0]); @@ -2867,7 +2893,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, rqst[1].rq_iov = io_iov; rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; - rc = SMB2_ioctl_init(tcon, &rqst[1], fid.persistent_fid, + rc = SMB2_ioctl_init(tcon, server, + &rqst[1], fid.persistent_fid, fid.volatile_fid, FSCTL_GET_REPARSE_POINT, true /* is_fctl */, NULL, 0, CIFSMaxBufSize - @@ -2885,13 +2912,15 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, rqst[2].rq_iov = close_iov; rqst[2].rq_nvec = 1; - rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); + rc = SMB2_close_init(tcon, server, + &rqst[2], COMPOUND_FID, COMPOUND_FID, false); if (rc) goto querty_exit; smb2_set_related(&rqst[2]); - rc = compound_send_recv(xid, tcon->ses, flags, 3, rqst, + rc = compound_send_recv(xid, tcon->ses, server, + flags, 3, rqst, resp_buftype, rsp_iov); create_rsp = rsp_iov[0].iov_base; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 12de0af12f75..fe5a8452b213 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -98,14 +98,13 @@ int smb3_encryption_required(const struct cifs_tcon *tcon) static void smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, - const struct cifs_tcon *tcon) + const struct cifs_tcon *tcon, + struct TCP_Server_Info *server) { shdr->ProtocolId = SMB2_PROTO_NUMBER; shdr->StructureSize = cpu_to_le16(64); shdr->Command = smb2_cmd; - if (tcon && tcon->ses && tcon->ses->server) { - struct TCP_Server_Info *server = tcon->ses->server; - + if (server) { spin_lock(&server->req_lock); /* Request up to 10 credits but don't go over the limit. */ if (server->credits >= server->max_credits) @@ -125,8 +124,7 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, /* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */ /* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */ - if ((tcon->ses) && (tcon->ses->server) && - (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) + if (server && (server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) shdr->CreditCharge = cpu_to_le16(1); /* else CreditCharge MBZ */ @@ -148,8 +146,7 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, /* if (tcon->share_flags & SHI1005_FLAGS_DFS) shdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */ - if (tcon->ses && tcon->ses->server && tcon->ses->server->sign && - !smb3_encryption_required(tcon)) + if (server && server->sign && !smb3_encryption_required(tcon)) shdr->Flags |= SMB2_FLAGS_SIGNED; out: return; @@ -267,12 +264,12 @@ static inline int __smb2_reconnect(const struct nls_table *nlsc, #endif static int -smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) +smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, + struct TCP_Server_Info *server) { int rc; struct nls_table *nls_codepage; struct cifs_ses *ses; - struct TCP_Server_Info *server; int retries; /* @@ -301,12 +298,10 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) } } if ((!tcon->ses) || (tcon->ses->status == CifsExiting) || - (!tcon->ses->server)) + (!tcon->ses->server) || !server) return -EIO; ses = tcon->ses; - server = ses->server; - retries = server->nr_targets; /* @@ -439,7 +434,9 @@ failed: } static void -fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, void *buf, +fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + void *buf, unsigned int *total_len) { struct smb2_sync_pdu *spdu = (struct smb2_sync_pdu *)buf; @@ -452,7 +449,7 @@ fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, void *buf, */ memset(buf, 0, 256); - smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon); + smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon, server); spdu->StructureSize2 = cpu_to_le16(parmsize); *total_len = parmsize + sizeof(struct smb2_sync_hdr); @@ -464,7 +461,8 @@ fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, void *buf, * function must have filled in request_buf pointer. */ static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, - void **request_buf, unsigned int *total_len) + struct TCP_Server_Info *server, + void **request_buf, unsigned int *total_len) { /* BB eventually switch this to SMB2 specific small buf size */ if (smb2_command == SMB2_SET_INFO) @@ -476,7 +474,7 @@ static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, return -ENOMEM; } - fill_small_buf(smb2_command, tcon, + fill_small_buf(smb2_command, tcon, server, (struct smb2_sync_hdr *)(*request_buf), total_len); @@ -490,27 +488,30 @@ static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, } static int smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, + struct TCP_Server_Info *server, void **request_buf, unsigned int *total_len) { int rc; - rc = smb2_reconnect(smb2_command, tcon); + rc = smb2_reconnect(smb2_command, tcon, server); if (rc) return rc; - return __smb2_plain_req_init(smb2_command, tcon, request_buf, + return __smb2_plain_req_init(smb2_command, tcon, server, request_buf, total_len); } static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon, + struct TCP_Server_Info *server, void **request_buf, unsigned int *total_len) { /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */ if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) { - return __smb2_plain_req_init(SMB2_IOCTL, tcon, request_buf, - total_len); + return __smb2_plain_req_init(SMB2_IOCTL, tcon, server, + request_buf, total_len); } - return smb2_plain_req_init(SMB2_IOCTL, tcon, request_buf, total_len); + return smb2_plain_req_init(SMB2_IOCTL, tcon, server, + request_buf, total_len); } /* For explanation of negotiate contexts see MS-SMB2 section 2.2.3.1 */ @@ -858,7 +859,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) return -EIO; } - rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server, + (void **) &req, &total_len); if (rc) return rc; @@ -916,7 +918,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_negotiate_rsp *)rsp_iov.iov_base; /* @@ -1227,8 +1230,9 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data) struct TCP_Server_Info *server = cifs_ses_server(ses); unsigned int total_len; - rc = smb2_plain_req_init(SMB2_SESSION_SETUP, NULL, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_SESSION_SETUP, NULL, server, + (void **) &req, + &total_len); if (rc) return rc; @@ -1305,6 +1309,7 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data) /* BB add code to build os and lm fields */ rc = cifs_send_recv(sess_data->xid, sess_data->ses, + cifs_ses_server(sess_data->ses), &rqst, &sess_data->buf0_type, CIFS_LOG_ERROR | CIFS_NEG_OP, &rsp_iov); @@ -1689,7 +1694,8 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses) if (ses->need_reconnect) goto smb2_session_already_dead; - rc = smb2_plain_req_init(SMB2_LOGOFF, NULL, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_LOGOFF, NULL, ses->server, + (void **) &req, &total_len); if (rc) return rc; @@ -1710,7 +1716,8 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses) rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, ses->server, + &rqst, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); /* * No tcon so can't do @@ -1751,7 +1758,10 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, __le16 *unc_path = NULL; int flags = 0; unsigned int total_len; - struct TCP_Server_Info *server = ses->server; + struct TCP_Server_Info *server; + + /* always use master channel */ + server = ses->server; cifs_dbg(FYI, "TCON\n"); @@ -1772,8 +1782,8 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */ tcon->tid = 0; atomic_set(&tcon->num_remote_opens, 0); - rc = smb2_plain_req_init(SMB2_TREE_CONNECT, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_TREE_CONNECT, tcon, server, + (void **) &req, &total_len); if (rc) { kfree(unc_path); return rc; @@ -1812,7 +1822,8 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, /* Need 64 for max size write so ask for more in case not there yet */ req->sync_hdr.CreditRequest = cpu_to_le16(64); - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; trace_smb3_tcon(xid, tcon->tid, ses->Suid, tree, rc); @@ -1897,8 +1908,9 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) close_shroot_lease(&tcon->crfid); - rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, ses->server, + (void **) &req, + &total_len); if (rc) return rc; @@ -1914,7 +1926,8 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, ses->server, + &rqst, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); if (rc) cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE); @@ -2468,6 +2481,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, int flags = 0; unsigned int total_len; __le16 *utf16_path = NULL; + struct TCP_Server_Info *server = cifs_pick_channel(ses); cifs_dbg(FYI, "mkdir\n"); @@ -2476,13 +2490,14 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, if (!utf16_path) return -ENOMEM; - if (!ses || !(ses->server)) { + if (!ses || !server) { rc = -EIO; goto err_free_path; } /* resource #2: request */ - rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_CREATE, tcon, server, + (void **) &req, &total_len); if (rc) goto err_free_path; @@ -2568,7 +2583,8 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES); /* resource #4: response buffer */ - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); if (rc) { cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid, @@ -2597,10 +2613,10 @@ err_free_path: } int -SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, +SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + struct smb_rqst *rqst, __u8 *oplock, struct cifs_open_parms *oparms, __le16 *path) { - struct TCP_Server_Info *server = tcon->ses->server; struct smb2_create_req *req; unsigned int n_iov = 2; __u32 file_attributes = 0; @@ -2611,7 +2627,8 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, __le16 *copy_path; int rc; - rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_CREATE, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -2783,9 +2800,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, { struct smb_rqst rqst; struct smb2_create_rsp *rsp = NULL; - struct TCP_Server_Info *server; struct cifs_tcon *tcon = oparms->tcon; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); struct kvec iov[SMB2_CREATE_IOV_SIZE]; struct kvec rsp_iov = {NULL, 0}; int resp_buftype = CIFS_NO_BUFFER; @@ -2793,9 +2810,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, int flags = 0; cifs_dbg(FYI, "create/open\n"); - if (ses && (ses->server)) - server = ses->server; - else + if (!ses || !server) return -EIO; if (smb3_encryption_required(tcon)) @@ -2806,14 +2821,16 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, rqst.rq_iov = iov; rqst.rq_nvec = SMB2_CREATE_IOV_SIZE; - rc = SMB2_open_init(tcon, &rqst, oplock, oparms, path); + rc = SMB2_open_init(tcon, server, + &rqst, oplock, oparms, path); if (rc) goto creat_exit; trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->create_options, oparms->desired_access); - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; @@ -2865,7 +2882,8 @@ creat_exit: } int -SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, u32 opcode, bool is_fsctl, char *in_data, u32 indatalen, __u32 max_response_size) @@ -2876,7 +2894,8 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, int rc; char *in_data_buf; - rc = smb2_ioctl_req_init(opcode, tcon, (void **) &req, &total_len); + rc = smb2_ioctl_req_init(opcode, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -2976,12 +2995,12 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, struct smb_rqst rqst; struct smb2_ioctl_rsp *rsp = NULL; struct cifs_ses *ses; + struct TCP_Server_Info *server; struct kvec iov[SMB2_IOCTL_IOV_SIZE]; struct kvec rsp_iov = {NULL, 0}; int resp_buftype = CIFS_NO_BUFFER; int rc = 0; int flags = 0; - struct TCP_Server_Info *server; cifs_dbg(FYI, "SMB2 IOCTL\n"); @@ -2992,14 +3011,14 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (plen) *plen = 0; - if (tcon) - ses = tcon->ses; - else + if (!tcon) return -EIO; + ses = tcon->ses; if (!ses) return -EIO; - server = ses->server; + + server = cifs_pick_channel(ses); if (!server) return -EIO; @@ -3011,12 +3030,14 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, rqst.rq_iov = iov; rqst.rq_nvec = SMB2_IOCTL_IOV_SIZE; - rc = SMB2_ioctl_init(tcon, &rqst, persistent_fid, volatile_fid, opcode, + rc = SMB2_ioctl_init(tcon, server, + &rqst, persistent_fid, volatile_fid, opcode, is_fsctl, in_data, indatalen, max_out_data_len); if (rc) goto ioctl_exit; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_ioctl_rsp *)rsp_iov.iov_base; @@ -3104,7 +3125,8 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, } int -SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, bool query_attrs) { struct smb2_close_req *req; @@ -3112,7 +3134,8 @@ SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, unsigned int total_len; int rc; - rc = smb2_plain_req_init(SMB2_CLOSE, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_CLOSE, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -3143,6 +3166,7 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, struct smb_rqst rqst; struct smb2_close_rsp *rsp = NULL; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); struct kvec iov[1]; struct kvec rsp_iov; int resp_buftype = CIFS_NO_BUFFER; @@ -3152,7 +3176,7 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, cifs_dbg(FYI, "Close\n"); - if (!ses || !(ses->server)) + if (!ses || !server) return -EIO; if (smb3_encryption_required(tcon)) @@ -3168,12 +3192,14 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, query_attrs = true; trace_smb3_close_enter(xid, persistent_fid, tcon->tid, ses->Suid); - rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid, + rc = SMB2_close_init(tcon, server, + &rqst, persistent_fid, volatile_fid, query_attrs); if (rc) goto close_exit; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_close_rsp *)rsp_iov.iov_base; if (rc != 0) { @@ -3273,7 +3299,8 @@ smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length, } int -SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, u8 info_class, u8 info_type, u32 additional_info, size_t output_len, size_t input_len, void *input) @@ -3283,8 +3310,8 @@ SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, unsigned int total_len; int rc; - rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -3336,7 +3363,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, if (!ses) return -EIO; - server = ses->server; + server = cifs_pick_channel(ses); if (!server) return -EIO; @@ -3348,7 +3375,8 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = SMB2_query_info_init(tcon, &rqst, persistent_fid, volatile_fid, + rc = SMB2_query_info_init(tcon, server, + &rqst, persistent_fid, volatile_fid, info_class, info_type, additional_info, output_len, 0, NULL); if (rc) @@ -3357,7 +3385,8 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid, ses->Suid, info_class, (__u32)info_type); - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; if (rc) { @@ -3442,15 +3471,17 @@ SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, static int SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst, - struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, - u32 completion_filter, bool watch_tree) + struct cifs_tcon *tcon, struct TCP_Server_Info *server, + u64 persistent_fid, u64 volatile_fid, + u32 completion_filter, bool watch_tree) { struct smb2_change_notify_req *req; struct kvec *iov = rqst->rq_iov; unsigned int total_len; int rc; - rc = smb2_plain_req_init(SMB2_CHANGE_NOTIFY, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_CHANGE_NOTIFY, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -3477,6 +3508,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, u32 completion_filter) { struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); struct smb_rqst rqst; struct kvec iov[1]; struct kvec rsp_iov = {NULL, 0}; @@ -3485,7 +3517,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; cifs_dbg(FYI, "change notify\n"); - if (!ses || !(ses->server)) + if (!ses || !server) return -EIO; if (smb3_encryption_required(tcon)) @@ -3496,14 +3528,16 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = SMB2_notify_init(xid, &rqst, tcon, persistent_fid, volatile_fid, + rc = SMB2_notify_init(xid, &rqst, tcon, server, + persistent_fid, volatile_fid, completion_filter, watch_tree); if (rc) goto cnotify_exit; trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid, (u8)watch_tree, completion_filter); - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); if (rc != 0) { cifs_stats_fail_inc(tcon, SMB2_CHANGE_NOTIFY_HE); @@ -3593,7 +3627,7 @@ void smb2_reconnect_server(struct work_struct *work) spin_unlock(&cifs_tcp_ses_lock); list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { - rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon); + rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server); if (!rc) cifs_reopen_persistent_handles(tcon); else @@ -3633,7 +3667,8 @@ SMB2_echo(struct TCP_Server_Info *server) return rc; } - rc = smb2_plain_req_init(SMB2_ECHO, NULL, (void **)&req, &total_len); + rc = smb2_plain_req_init(SMB2_ECHO, NULL, server, + (void **)&req, &total_len); if (rc) return rc; @@ -3660,14 +3695,16 @@ SMB2_flush_free(struct smb_rqst *rqst) int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, - struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid) + struct cifs_tcon *tcon, struct TCP_Server_Info *server, + u64 persistent_fid, u64 volatile_fid) { struct smb2_flush_req *req; struct kvec *iov = rqst->rq_iov; unsigned int total_len; int rc; - rc = smb2_plain_req_init(SMB2_FLUSH, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_FLUSH, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -3688,6 +3725,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, struct smb_rqst rqst; struct kvec iov[1]; struct kvec rsp_iov = {NULL, 0}; + struct TCP_Server_Info *server = cifs_pick_channel(ses); int resp_buftype = CIFS_NO_BUFFER; int flags = 0; int rc = 0; @@ -3704,12 +3742,14 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = SMB2_flush_init(xid, &rqst, tcon, persistent_fid, volatile_fid); + rc = SMB2_flush_init(xid, &rqst, tcon, server, + persistent_fid, volatile_fid); if (rc) goto flush_exit; trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid); - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); if (rc != 0) { cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE); @@ -3737,14 +3777,13 @@ smb2_new_read_req(void **buf, unsigned int *total_len, int rc = -EACCES; struct smb2_read_plain_req *req = NULL; struct smb2_sync_hdr *shdr; - struct TCP_Server_Info *server; + struct TCP_Server_Info *server = io_parms->server; - rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, (void **) &req, - total_len); + rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server, + (void **) &req, total_len); if (rc) return rc; - server = io_parms->tcon->ses->server; if (server == NULL) return -ECONNABORTED; @@ -3773,8 +3812,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len, rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) { struct smbd_buffer_descriptor_v1 *v1; - bool need_invalidate = - io_parms->tcon->ses->server->dialect == SMB30_PROT_ID; + bool need_invalidate = server->dialect == SMB30_PROT_ID; rdata->mr = smbd_register_mr( server->smbd_conn, rdata->pages, @@ -3831,7 +3869,7 @@ smb2_readv_callback(struct mid_q_entry *mid) { struct cifs_readdata *rdata = mid->callback_data; struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); - struct TCP_Server_Info *server = tcon->ses->server; + struct TCP_Server_Info *server = rdata->server; struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)rdata->iov[0].iov_base; struct cifs_credits credits = { .value = 0, .instance = 0 }; @@ -3843,6 +3881,10 @@ smb2_readv_callback(struct mid_q_entry *mid) .rq_pagesz = rdata->pagesz, .rq_tailsz = rdata->tailsz }; + WARN_ONCE(rdata->server != mid->server, + "rdata server %p != mid server %p", + rdata->server, mid->server); + cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n", __func__, mid->mid, mid->mid_state, rdata->result, rdata->bytes); @@ -3920,20 +3962,23 @@ smb2_async_readv(struct cifs_readdata *rdata) struct smb_rqst rqst = { .rq_iov = rdata->iov, .rq_nvec = 1 }; struct TCP_Server_Info *server; + struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); unsigned int total_len; cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n", __func__, rdata->offset, rdata->bytes); + if (!rdata->server) + rdata->server = cifs_pick_channel(tcon->ses); + io_parms.tcon = tlink_tcon(rdata->cfile->tlink); + io_parms.server = server = rdata->server; io_parms.offset = rdata->offset; io_parms.length = rdata->bytes; io_parms.persistent_fid = rdata->cfile->fid.persistent_fid; io_parms.volatile_fid = rdata->cfile->fid.volatile_fid; io_parms.pid = rdata->pid; - server = io_parms.tcon->ses->server; - rc = smb2_new_read_req( (void **) &buf, &total_len, &io_parms, rdata, 0, 0); if (rc) @@ -3961,7 +4006,7 @@ smb2_async_readv(struct cifs_readdata *rdata) } kref_get(&rdata->refcount); - rc = cifs_call_async(io_parms.tcon->ses->server, &rqst, + rc = cifs_call_async(server, &rqst, cifs_readv_receive, smb2_readv_callback, smb3_handle_read_data, rdata, flags, &rdata->credits); @@ -3993,6 +4038,9 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, int flags = CIFS_LOG_ERROR; struct cifs_ses *ses = io_parms->tcon->ses; + if (!io_parms->server) + io_parms->server = cifs_pick_channel(io_parms->tcon->ses); + *nbytes = 0; rc = smb2_new_read_req((void **)&req, &total_len, io_parms, NULL, 0, 0); if (rc) @@ -4008,7 +4056,8 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, io_parms->server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_read_rsp *)rsp_iov.iov_base; if (rc) { @@ -4064,11 +4113,15 @@ smb2_writev_callback(struct mid_q_entry *mid) { struct cifs_writedata *wdata = mid->callback_data; struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); - struct TCP_Server_Info *server = tcon->ses->server; + struct TCP_Server_Info *server = wdata->server; unsigned int written; struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf; struct cifs_credits credits = { .value = 0, .instance = 0 }; + WARN_ONCE(wdata->server != mid->server, + "wdata server %p != mid server %p", + wdata->server, mid->server); + switch (mid->mid_state) { case MID_RESPONSE_RECEIVED: credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest); @@ -4146,12 +4199,16 @@ smb2_async_writev(struct cifs_writedata *wdata, struct smb2_write_req *req = NULL; struct smb2_sync_hdr *shdr; struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); - struct TCP_Server_Info *server = tcon->ses->server; + struct TCP_Server_Info *server = wdata->server; struct kvec iov[1]; struct smb_rqst rqst = { }; unsigned int total_len; - rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len); + if (!wdata->server) + server = wdata->server = cifs_pick_channel(tcon->ses); + + rc = smb2_plain_req_init(SMB2_WRITE, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -4290,20 +4347,24 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, struct kvec rsp_iov; int flags = 0; unsigned int total_len; + struct TCP_Server_Info *server; *nbytes = 0; if (n_vec < 1) return rc; - rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, (void **) &req, - &total_len); + if (!io_parms->server) + io_parms->server = cifs_pick_channel(io_parms->tcon->ses); + server = io_parms->server; + if (server == NULL) + return -ECONNABORTED; + + rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, server, + (void **) &req, &total_len); if (rc) return rc; - if (io_parms->tcon->ses->server == NULL) - return -ECONNABORTED; - if (smb3_encryption_required(io_parms->tcon)) flags |= CIFS_TRANSFORM_REQ; @@ -4332,7 +4393,8 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, rqst.rq_iov = iov; rqst.rq_nvec = n_vec + 1; - rc = cifs_send_recv(xid, io_parms->tcon->ses, &rqst, + rc = cifs_send_recv(xid, io_parms->tcon->ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_write_rsp *)rsp_iov.iov_base; @@ -4506,11 +4568,12 @@ num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry, * Readdir/FindFirst */ int SMB2_query_directory_init(const unsigned int xid, - struct cifs_tcon *tcon, struct smb_rqst *rqst, + struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, int index, int info_level) { - struct TCP_Server_Info *server = tcon->ses->server; struct smb2_query_directory_req *req; unsigned char *bufptr; __le16 asteriks = cpu_to_le16('*'); @@ -4521,8 +4584,8 @@ int SMB2_query_directory_init(const unsigned int xid, struct kvec *iov = rqst->rq_iov; int len, rc; - rc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -4665,6 +4728,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, struct kvec rsp_iov; int rc = 0; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); int flags = 0; if (!ses || !(ses->server)) @@ -4678,13 +4742,15 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE; - rc = SMB2_query_directory_init(xid, tcon, &rqst, persistent_fid, + rc = SMB2_query_directory_init(xid, tcon, server, + &rqst, persistent_fid, volatile_fid, index, srch_inf->info_level); if (rc) goto qdir_exit; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base; if (rc) { @@ -4721,17 +4787,19 @@ qdir_exit: } int -SMB2_set_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, - u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class, - u8 info_type, u32 additional_info, - void **data, unsigned int *size) +SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + struct smb_rqst *rqst, + u64 persistent_fid, u64 volatile_fid, u32 pid, + u8 info_class, u8 info_type, u32 additional_info, + void **data, unsigned int *size) { struct smb2_set_info_req *req; struct kvec *iov = rqst->rq_iov; unsigned int i, total_len; int rc; - rc = smb2_plain_req_init(SMB2_SET_INFO, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_SET_INFO, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -4782,9 +4850,10 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; int resp_buftype; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); int flags = 0; - if (!ses || !(ses->server)) + if (!ses || !server) return -EIO; if (!num) @@ -4801,7 +4870,8 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = num; - rc = SMB2_set_info_init(tcon, &rqst, persistent_fid, volatile_fid, pid, + rc = SMB2_set_info_init(tcon, server, + &rqst, persistent_fid, volatile_fid, pid, info_class, info_type, additional_info, data, size); if (rc) { @@ -4810,7 +4880,8 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, } - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); SMB2_set_info_free(&rqst); rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base; @@ -4873,6 +4944,7 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, int rc; struct smb2_oplock_break *req = NULL; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); int flags = CIFS_OBREAK_OP; unsigned int total_len; struct kvec iov[1]; @@ -4880,8 +4952,8 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, int resp_buf_type; cifs_dbg(FYI, "SMB2_oplock_break\n"); - rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -4902,7 +4974,8 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); if (rc) { @@ -4945,8 +5018,10 @@ copy_posix_fs_info_to_kstatfs(FILE_SYSTEM_POSIX_INFO *response_data, } static int -build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, - int outbuf_len, u64 persistent_fid, u64 volatile_fid) +build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + int level, int outbuf_len, u64 persistent_fid, + u64 volatile_fid) { int rc; struct smb2_query_info_req *req; @@ -4954,11 +5029,11 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, cifs_dbg(FYI, "Query FSInfo level %d\n", level); - if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) + if ((tcon->ses == NULL) || server == NULL) return -EIO; - rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -4988,10 +5063,12 @@ SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; int resp_buftype; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); FILE_SYSTEM_POSIX_INFO *info = NULL; int flags = 0; - rc = build_qfs_info_req(&iov, tcon, FS_POSIX_INFORMATION, + rc = build_qfs_info_req(&iov, tcon, server, + FS_POSIX_INFORMATION, sizeof(FILE_SYSTEM_POSIX_INFO), persistent_fid, volatile_fid); if (rc) @@ -5004,7 +5081,8 @@ SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = &iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -5036,10 +5114,12 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; int resp_buftype; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); struct smb2_fs_full_size_info *info = NULL; int flags = 0; - rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION, + rc = build_qfs_info_req(&iov, tcon, server, + FS_FULL_SIZE_INFORMATION, sizeof(struct smb2_fs_full_size_info), persistent_fid, volatile_fid); if (rc) @@ -5052,7 +5132,8 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = &iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -5084,6 +5165,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; int resp_buftype, max_len, min_len; struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); unsigned int rsp_len, offset; int flags = 0; @@ -5104,7 +5186,8 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, return -EINVAL; } - rc = build_qfs_info_req(&iov, tcon, level, max_len, + rc = build_qfs_info_req(&iov, tcon, server, + level, max_len, persistent_fid, volatile_fid); if (rc) return rc; @@ -5116,7 +5199,8 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = &iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -5169,10 +5253,12 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, unsigned int count; int flags = CIFS_NO_RSP_BUF; unsigned int total_len; + struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock); - rc = smb2_plain_req_init(SMB2_LOCK, tcon, (void **) &req, &total_len); + rc = smb2_plain_req_init(SMB2_LOCK, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -5198,7 +5284,8 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 2; - rc = cifs_send_recv(xid, tcon->ses, &rqst, &resp_buf_type, flags, + rc = cifs_send_recv(xid, tcon->ses, server, + &rqst, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); if (rc) { @@ -5243,10 +5330,11 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, int resp_buf_type; __u64 *please_key_high; __u64 *please_key_low; + struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); cifs_dbg(FYI, "SMB2_lease_break\n"); - rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req, - &total_len); + rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server, + (void **) &req, &total_len); if (rc) return rc; @@ -5269,7 +5357,8 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 1; - rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); please_key_low = (__u64 *)lease_key; diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 087d5f14320b..71ba74792c9e 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -143,7 +143,9 @@ extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, struct smb2_file_all_info *buf, struct create_posix_rsp *posix, struct kvec *err_iov, int *resp_buftype); -extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +extern int SMB2_open_init(struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + struct smb_rqst *rqst, __u8 *oplock, struct cifs_open_parms *oparms, __le16 *path); extern void SMB2_open_free(struct smb_rqst *rqst); @@ -151,7 +153,9 @@ extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, u32 opcode, bool is_fsctl, char *in_data, u32 indatalen, u32 maxoutlen, char **out_data, u32 *plen /* returned data len */); -extern int SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +extern int SMB2_ioctl_init(struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, u32 opcode, bool is_fsctl, char *in_data, u32 indatalen, __u32 max_response_size); @@ -165,19 +169,25 @@ extern int __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, struct smb2_file_network_open_info *pbuf); extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id); -extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, - u64 persistent_fid, u64 volatile_fid, bool query_attrs); +extern int SMB2_close_init(struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + struct smb_rqst *rqst, + u64 persistent_fid, u64 volatile_fid, + bool query_attrs); extern void SMB2_close_free(struct smb_rqst *rqst); extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id); extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, struct cifs_tcon *tcon, + struct TCP_Server_Info *server, u64 persistent_file_id, u64 volatile_file_id); extern void SMB2_flush_free(struct smb_rqst *rqst); extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id, struct smb2_file_all_info *data); -extern int SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +extern int SMB2_query_info_init(struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, u8 info_class, u8 info_type, u32 additional_info, size_t output_len, @@ -201,6 +211,7 @@ extern int SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, int index, struct cifs_search_info *srch_inf); extern int SMB2_query_directory_init(unsigned int xid, struct cifs_tcon *tcon, + struct TCP_Server_Info *server, struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, int index, int info_level); @@ -208,7 +219,9 @@ extern void SMB2_query_directory_free(struct smb_rqst *rqst); extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, u32 pid, __le64 *eof); -extern int SMB2_set_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, +extern int SMB2_set_info_init(struct cifs_tcon *tcon, + struct TCP_Server_Info *server, + struct smb_rqst *rqst, u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class, u8 info_type, u32 additional_info, void **data, unsigned int *size); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 4d4cb26d2ae1..100d04af62b1 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -1020,6 +1020,7 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) 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) { @@ -1031,20 +1032,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, }; unsigned int instance; char *buf; - struct TCP_Server_Info *server; optype = flags & CIFS_OP_MASK; for (i = 0; i < num_rqst; i++) resp_buf_type[i] = CIFS_NO_BUFFER; /* no response buf yet */ - if ((ses == NULL) || (ses->server == NULL)) { + if (!ses || !ses->server || !server) { cifs_dbg(VFS, "Null session\n"); return -EIO; } - server = cifs_pick_channel(ses); - if (server->tcpStatus == CifsExiting) return -ENOENT; @@ -1239,11 +1237,12 @@ out: 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) { - return compound_send_recv(xid, ses, flags, 1, rqst, resp_buf_type, - resp_iov); + return compound_send_recv(xid, ses, server, flags, 1, + rqst, resp_buf_type, resp_iov); } int @@ -1278,7 +1277,8 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, rqst.rq_iov = new_iov; rqst.rq_nvec = n_vec + 1; - rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov); + rc = cifs_send_recv(xid, ses, ses->server, + &rqst, resp_buf_type, flags, resp_iov); if (n_vec + 1 > CIFS_MAX_IOV_SIZE) kfree(new_iov); return rc; -- cgit v1.2.3 From edb161353680e6d488d94cbcaf967745bee98d17 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 31 May 2020 14:36:56 -0500 Subject: smb3: remove static checker warning Remove static checker warning pointed out by Dan Carpenter: The patch feeaec621c09: "cifs: multichannel: move channel selection above transport layer" from Apr 24, 2020, leads to the following static checker warning: fs/cifs/smb2pdu.c:149 smb2_hdr_assemble() error: we previously assumed 'tcon->ses' could be null (see line 133) Reported-by: Dan Carpenter CC: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/cifs') diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index fe5a8452b213..2497e0e428ac 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -85,7 +85,7 @@ static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = { int smb3_encryption_required(const struct cifs_tcon *tcon) { - if (!tcon) + if (!tcon || !tcon->ses) return 0; if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) || (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)) -- cgit v1.2.3 From 8eec79540d2b9cec385707be45f6e9388b34020f Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Fri, 24 Apr 2020 15:24:05 +0200 Subject: cifs: multichannel: use pointer for binding channel Add a cifs_chan pointer in struct cifs_ses that points to the channel currently being bound if ses->binding is true. Previously it was always the channel past the established count. This will make reconnecting (and rebinding) a channel easier later on. Signed-off-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 15 ++++++++++++--- fs/cifs/sess.c | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'fs/cifs') diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index c0cbbd0bbb1d..e133bb3e172f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1030,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 */ @@ -1037,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; } diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 0ae25cc77fc0..1ffdd7dadc55 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -231,7 +231,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) mutex_lock(&ses->session_mutex); - chan = &ses->chans[ses->chan_count]; + chan = ses->binding_chan = &ses->chans[ses->chan_count]; chan->server = cifs_get_tcp_session(&vol); if (IS_ERR(chan->server)) { rc = PTR_ERR(chan->server); @@ -276,6 +276,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) atomic_set(&ses->chan_seq, 0); out: ses->binding = false; + ses->binding_chan = NULL; mutex_unlock(&ses->session_mutex); if (rc && chan->server) -- cgit v1.2.3 From 2f58967979409ea3ec799343aa35e9007f735a3b Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Fri, 24 Apr 2020 16:55:31 +0200 Subject: cifs: multichannel: try to rebind when reconnecting a channel first steps in trying to make channels properly reconnect. * add cifs_ses_find_chan() function to find the enclosing cifs_chan struct it belongs to * while we have the session lock and are redoing negprot and sess.setup in smb2_reconnect() redo the binding of channels. Signed-off-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 2 ++ fs/cifs/sess.c | 16 ++++++++++++++++ fs/cifs/smb2pdu.c | 16 ++++++++++++++++ 3 files changed, 34 insertions(+) (limited to 'fs/cifs') diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index a25a46237f9f..bd92070ca30c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -593,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); diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 1ffdd7dadc55..5d05bd2822d2 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -150,6 +150,22 @@ int cifs_try_adding_channels(struct cifs_ses *ses) return ses->chan_count - old_chan_count; } +/* + * If server is a channel of ses, return the corresponding enclosing + * cifs_chan otherwise return NULL. + */ +struct cifs_chan * +cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server) +{ + int i; + + for (i = 0; i < ses->chan_count; i++) { + if (ses->chans[i].server == server) + return &ses->chans[i]; + } + return NULL; +} + int cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) { diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 2497e0e428ac..ded96b529a4d 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -375,15 +375,31 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, goto out; } + /* + * If we are reconnecting an extra channel, bind + */ + if (server->is_channel) { + ses->binding = true; + ses->binding_chan = cifs_ses_find_chan(ses, server); + } + rc = cifs_negotiate_protocol(0, tcon->ses); if (!rc && tcon->ses->need_reconnect) { rc = cifs_setup_session(0, tcon->ses, nls_codepage); if ((rc == -EACCES) && !tcon->retry) { rc = -EHOSTDOWN; + ses->binding = false; + ses->binding_chan = NULL; mutex_unlock(&tcon->ses->session_mutex); goto failed; } } + /* + * End of channel binding + */ + ses->binding = false; + ses->binding_chan = NULL; + if (rc || !tcon->need_reconnect) { mutex_unlock(&tcon->ses->session_mutex); goto out; -- cgit v1.2.3 From 331cc667a99c633abbbebeab4675beae713fb331 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 2 Jun 2020 23:30:50 -0500 Subject: cifs: update internal module version number To 2.27 Signed-off-by: Steve French --- fs/cifs/cifsfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/cifs') 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 */ -- cgit v1.2.3