Commit d66016c5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '5.19-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs client fixes from Steve French:
 "Nine cifs/smb3 client fixes.

  Includes DFS fixes, some cleanup of leagcy SMB1 code, duplicated
  message cleanup and a double free and deadlock fix"

* tag '5.19-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: fix uninitialized pointer in error case in dfs_cache_get_tgt_share
  cifs: skip trailing separators of prefix paths
  cifs: update internal module number
  cifs: version operations for smb20 unneeded when legacy support disabled
  cifs: do not build smb1ops if legacy support is disabled
  cifs: fix potential deadlock in direct reclaim
  cifs: when extending a file with falloc we should make files not-sparse
  cifs: remove repeated debug message on cifs_put_smb_ses()
  cifs: fix potential double free during failed mount
parents d0e60d46 ee3c8019
...@@ -8,7 +8,7 @@ obj-$(CONFIG_CIFS) += cifs.o ...@@ -8,7 +8,7 @@ obj-$(CONFIG_CIFS) += cifs.o
cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \ cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \
inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \ inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \
cifs_unicode.o nterr.o cifsencrypt.o \ cifs_unicode.o nterr.o cifsencrypt.o \
readdir.o ioctl.o sess.o export.o smb1ops.o unc.o winucase.o \ readdir.o ioctl.o sess.o export.o unc.o winucase.o \
smb2ops.o smb2maperror.o smb2transport.o \ smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \ smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \
dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o
...@@ -30,3 +30,5 @@ cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o ...@@ -30,3 +30,5 @@ cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o
cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o
cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o
cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o
...@@ -465,7 +465,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *a ...@@ -465,7 +465,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *a
int ret = 0; int ret = 0;
/* Store the reconnect address */ /* Store the reconnect address */
mutex_lock(&tcon->ses->server->srv_mutex); cifs_server_lock(tcon->ses->server);
if (cifs_sockaddr_equal(&tcon->ses->server->dstaddr, addr)) if (cifs_sockaddr_equal(&tcon->ses->server->dstaddr, addr))
goto unlock; goto unlock;
...@@ -501,7 +501,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *a ...@@ -501,7 +501,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *a
cifs_signal_cifsd_for_reconnect(tcon->ses->server, false); cifs_signal_cifsd_for_reconnect(tcon->ses->server, false);
unlock: unlock:
mutex_unlock(&tcon->ses->server->srv_mutex); cifs_server_unlock(tcon->ses->server);
return ret; return ret;
} }
......
...@@ -236,9 +236,9 @@ int cifs_verify_signature(struct smb_rqst *rqst, ...@@ -236,9 +236,9 @@ int cifs_verify_signature(struct smb_rqst *rqst,
cpu_to_le32(expected_sequence_number); cpu_to_le32(expected_sequence_number);
cifs_pdu->Signature.Sequence.Reserved = 0; cifs_pdu->Signature.Sequence.Reserved = 0;
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be); rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
if (rc) if (rc)
return rc; return rc;
...@@ -626,7 +626,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) ...@@ -626,7 +626,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
memcpy(ses->auth_key.response + baselen, tiblob, tilen); memcpy(ses->auth_key.response + baselen, tiblob, tilen);
mutex_lock(&ses->server->srv_mutex); cifs_server_lock(ses->server);
rc = cifs_alloc_hash("hmac(md5)", rc = cifs_alloc_hash("hmac(md5)",
&ses->server->secmech.hmacmd5, &ses->server->secmech.hmacmd5,
...@@ -678,7 +678,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) ...@@ -678,7 +678,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
unlock: unlock:
mutex_unlock(&ses->server->srv_mutex); cifs_server_unlock(ses->server);
setup_ntlmv2_rsp_ret: setup_ntlmv2_rsp_ret:
kfree(tiblob); kfree(tiblob);
......
...@@ -838,7 +838,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, ...@@ -838,7 +838,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
int flags, struct smb3_fs_context *old_ctx) int flags, struct smb3_fs_context *old_ctx)
{ {
int rc; int rc;
struct super_block *sb; struct super_block *sb = NULL;
struct cifs_sb_info *cifs_sb = NULL; struct cifs_sb_info *cifs_sb = NULL;
struct cifs_mnt_data mnt_data; struct cifs_mnt_data mnt_data;
struct dentry *root; struct dentry *root;
...@@ -934,10 +934,12 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, ...@@ -934,10 +934,12 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
return root; return root;
out: out:
if (cifs_sb) { if (cifs_sb) {
if (!sb || IS_ERR(sb)) { /* otherwise kill_sb will handle */
kfree(cifs_sb->prepath); kfree(cifs_sb->prepath);
smb3_cleanup_fs_context(cifs_sb->ctx); smb3_cleanup_fs_context(cifs_sb->ctx);
kfree(cifs_sb); kfree(cifs_sb);
} }
}
return root; return root;
} }
......
...@@ -152,6 +152,7 @@ extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type, ...@@ -152,6 +152,7 @@ extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
extern const struct export_operations cifs_export_ops; extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */ #endif /* CONFIG_CIFS_NFSD_EXPORT */
#define SMB3_PRODUCT_BUILD 35 /* when changing internal version - update following two lines at same time */
#define CIFS_VERSION "2.36" #define SMB3_PRODUCT_BUILD 37
#define CIFS_VERSION "2.37"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/mempool.h> #include <linux/mempool.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/sched/mm.h>
#include <linux/netfs.h> #include <linux/netfs.h>
#include "cifs_fs_sb.h" #include "cifs_fs_sb.h"
#include "cifsacl.h" #include "cifsacl.h"
...@@ -628,7 +629,8 @@ struct TCP_Server_Info { ...@@ -628,7 +629,8 @@ struct TCP_Server_Info {
unsigned int in_flight; /* number of requests on the wire to server */ unsigned int in_flight; /* number of requests on the wire to server */
unsigned int max_in_flight; /* max number of requests that were on wire */ unsigned int max_in_flight; /* max number of requests that were on wire */
spinlock_t req_lock; /* protect the two values above */ spinlock_t req_lock; /* protect the two values above */
struct mutex srv_mutex; struct mutex _srv_mutex;
unsigned int nofs_flag;
struct task_struct *tsk; struct task_struct *tsk;
char server_GUID[16]; char server_GUID[16];
__u16 sec_mode; __u16 sec_mode;
...@@ -743,6 +745,22 @@ struct TCP_Server_Info { ...@@ -743,6 +745,22 @@ struct TCP_Server_Info {
#endif #endif
}; };
static inline void cifs_server_lock(struct TCP_Server_Info *server)
{
unsigned int nofs_flag = memalloc_nofs_save();
mutex_lock(&server->_srv_mutex);
server->nofs_flag = nofs_flag;
}
static inline void cifs_server_unlock(struct TCP_Server_Info *server)
{
unsigned int nofs_flag = server->nofs_flag;
mutex_unlock(&server->_srv_mutex);
memalloc_nofs_restore(nofs_flag);
}
struct cifs_credits { struct cifs_credits {
unsigned int value; unsigned int value;
unsigned int instance; unsigned int instance;
...@@ -1945,11 +1963,13 @@ extern mempool_t *cifs_mid_poolp; ...@@ -1945,11 +1963,13 @@ extern mempool_t *cifs_mid_poolp;
/* Operations for different SMB versions */ /* Operations for different SMB versions */
#define SMB1_VERSION_STRING "1.0" #define SMB1_VERSION_STRING "1.0"
#define SMB20_VERSION_STRING "2.0"
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
extern struct smb_version_operations smb1_operations; extern struct smb_version_operations smb1_operations;
extern struct smb_version_values smb1_values; extern struct smb_version_values smb1_values;
#define SMB20_VERSION_STRING "2.0"
extern struct smb_version_operations smb20_operations; extern struct smb_version_operations smb20_operations;
extern struct smb_version_values smb20_values; extern struct smb_version_values smb20_values;
#endif /* CIFS_ALLOW_INSECURE_LEGACY */
#define SMB21_VERSION_STRING "2.1" #define SMB21_VERSION_STRING "2.1"
extern struct smb_version_operations smb21_operations; extern struct smb_version_operations smb21_operations;
extern struct smb_version_values smb21_values; extern struct smb_version_values smb21_values;
......
...@@ -148,7 +148,7 @@ static void cifs_resolve_server(struct work_struct *work) ...@@ -148,7 +148,7 @@ static void cifs_resolve_server(struct work_struct *work)
struct TCP_Server_Info *server = container_of(work, struct TCP_Server_Info *server = container_of(work,
struct TCP_Server_Info, resolve.work); struct TCP_Server_Info, resolve.work);
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
/* /*
* Resolve the hostname again to make sure that IP address is up-to-date. * Resolve the hostname again to make sure that IP address is up-to-date.
...@@ -159,7 +159,7 @@ static void cifs_resolve_server(struct work_struct *work) ...@@ -159,7 +159,7 @@ static void cifs_resolve_server(struct work_struct *work)
__func__, rc); __func__, rc);
} }
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
} }
/* /*
...@@ -267,7 +267,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) ...@@ -267,7 +267,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
/* do not want to be sending data on a socket we are freeing */ /* do not want to be sending data on a socket we are freeing */
cifs_dbg(FYI, "%s: tearing down socket\n", __func__); cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
if (server->ssocket) { if (server->ssocket) {
cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", server->ssocket->state, cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", server->ssocket->state,
server->ssocket->flags); server->ssocket->flags);
...@@ -296,7 +296,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) ...@@ -296,7 +296,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
mid->mid_flags |= MID_DELETED; mid->mid_flags |= MID_DELETED;
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__); cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
list_for_each_entry_safe(mid, nmid, &retry_list, qhead) { list_for_each_entry_safe(mid, nmid, &retry_list, qhead) {
...@@ -306,9 +306,9 @@ cifs_abort_connection(struct TCP_Server_Info *server) ...@@ -306,9 +306,9 @@ cifs_abort_connection(struct TCP_Server_Info *server)
} }
if (cifs_rdma_enabled(server)) { if (cifs_rdma_enabled(server)) {
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
smbd_destroy(server); smbd_destroy(server);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
} }
} }
...@@ -359,7 +359,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, ...@@ -359,7 +359,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
do { do {
try_to_freeze(); try_to_freeze();
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
if (!cifs_swn_set_server_dstaddr(server)) { if (!cifs_swn_set_server_dstaddr(server)) {
/* resolve the hostname again to make sure that IP address is up-to-date */ /* resolve the hostname again to make sure that IP address is up-to-date */
...@@ -372,7 +372,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, ...@@ -372,7 +372,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
else else
rc = generic_ip_connect(server); rc = generic_ip_connect(server);
if (rc) { if (rc) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc); cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc);
msleep(3000); msleep(3000);
} else { } else {
...@@ -383,7 +383,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, ...@@ -383,7 +383,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
server->tcpStatus = CifsNeedNegotiate; server->tcpStatus = CifsNeedNegotiate;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
cifs_swn_reset_server_dstaddr(server); cifs_swn_reset_server_dstaddr(server);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
mod_delayed_work(cifsiod_wq, &server->reconnect, 0); mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
} }
} while (server->tcpStatus == CifsNeedReconnect); } while (server->tcpStatus == CifsNeedReconnect);
...@@ -488,12 +488,12 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) ...@@ -488,12 +488,12 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
do { do {
try_to_freeze(); try_to_freeze();
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
rc = reconnect_target_unlocked(server, &tl, &target_hint); rc = reconnect_target_unlocked(server, &tl, &target_hint);
if (rc) { if (rc) {
/* Failed to reconnect socket */ /* Failed to reconnect socket */
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc); cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc);
msleep(3000); msleep(3000);
continue; continue;
...@@ -510,7 +510,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) ...@@ -510,7 +510,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
server->tcpStatus = CifsNeedNegotiate; server->tcpStatus = CifsNeedNegotiate;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
cifs_swn_reset_server_dstaddr(server); cifs_swn_reset_server_dstaddr(server);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
mod_delayed_work(cifsiod_wq, &server->reconnect, 0); mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
} while (server->tcpStatus == CifsNeedReconnect); } while (server->tcpStatus == CifsNeedReconnect);
...@@ -1565,7 +1565,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, ...@@ -1565,7 +1565,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
init_waitqueue_head(&tcp_ses->response_q); init_waitqueue_head(&tcp_ses->response_q);
init_waitqueue_head(&tcp_ses->request_q); init_waitqueue_head(&tcp_ses->request_q);
INIT_LIST_HEAD(&tcp_ses->pending_mid_q); INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
mutex_init(&tcp_ses->srv_mutex); mutex_init(&tcp_ses->_srv_mutex);
memcpy(tcp_ses->workstation_RFC1001_name, memcpy(tcp_ses->workstation_RFC1001_name,
ctx->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); ctx->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
memcpy(tcp_ses->server_RFC1001_name, memcpy(tcp_ses->server_RFC1001_name,
...@@ -1845,7 +1845,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses) ...@@ -1845,7 +1845,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses)
unsigned int rc, xid; unsigned int rc, xid;
unsigned int chan_count; unsigned int chan_count;
struct TCP_Server_Info *server = ses->server; struct TCP_Server_Info *server = ses->server;
cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (ses->ses_status == SES_EXITING) { if (ses->ses_status == SES_EXITING) {
......
...@@ -1229,6 +1229,30 @@ void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id) ...@@ -1229,6 +1229,30 @@ void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id)
kref_put(&mg->refcount, mount_group_release); kref_put(&mg->refcount, mount_group_release);
} }
/* Extract share from DFS target and return a pointer to prefix path or NULL */
static const char *parse_target_share(const char *target, char **share)
{
const char *s, *seps = "/\\";
size_t len;
s = strpbrk(target + 1, seps);
if (!s)
return ERR_PTR(-EINVAL);
len = strcspn(s + 1, seps);
if (!len)
return ERR_PTR(-EINVAL);
s += len;
len = s - target + 1;
*share = kstrndup(target, len, GFP_KERNEL);
if (!*share)
return ERR_PTR(-ENOMEM);
s = target + len;
return s + strspn(s, seps);
}
/** /**
* dfs_cache_get_tgt_share - parse a DFS target * dfs_cache_get_tgt_share - parse a DFS target
* *
...@@ -1242,56 +1266,46 @@ void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id) ...@@ -1242,56 +1266,46 @@ void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id)
int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share, int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share,
char **prefix) char **prefix)
{ {
char *s, sep, *p; char sep;
size_t len; char *target_share;
size_t plen1, plen2; char *ppath = NULL;
const char *target_ppath, *dfsref_ppath;
size_t target_pplen, dfsref_pplen;
size_t len, c;
if (!it || !path || !share || !prefix || strlen(path) < it->it_path_consumed) if (!it || !path || !share || !prefix || strlen(path) < it->it_path_consumed)
return -EINVAL; return -EINVAL;
*share = NULL;
*prefix = NULL;
sep = it->it_name[0]; sep = it->it_name[0];
if (sep != '\\' && sep != '/') if (sep != '\\' && sep != '/')
return -EINVAL; return -EINVAL;
s = strchr(it->it_name + 1, sep); target_ppath = parse_target_share(it->it_name, &target_share);
if (!s) if (IS_ERR(target_ppath))
return -EINVAL; return PTR_ERR(target_ppath);
/* point to prefix in target node */ /* point to prefix in DFS referral path */
s = strchrnul(s + 1, sep); dfsref_ppath = path + it->it_path_consumed;
dfsref_ppath += strspn(dfsref_ppath, "/\\");
/* extract target share */ target_pplen = strlen(target_ppath);
*share = kstrndup(it->it_name, s - it->it_name, GFP_KERNEL); dfsref_pplen = strlen(dfsref_ppath);
if (!*share)
return -ENOMEM;
/* skip separator */ /* merge prefix paths from DFS referral path and target node */
if (*s) if (target_pplen || dfsref_pplen) {
s++; len = target_pplen + dfsref_pplen + 2;
/* point to prefix in DFS path */ ppath = kzalloc(len, GFP_KERNEL);
p = path + it->it_path_consumed; if (!ppath) {
if (*p == sep) kfree(target_share);
p++;
/* merge prefix paths from DFS path and target node */
plen1 = it->it_name + strlen(it->it_name) - s;
plen2 = path + strlen(path) - p;
if (plen1 || plen2) {
len = plen1 + plen2 + 2;
*prefix = kmalloc(len, GFP_KERNEL);
if (!*prefix) {
kfree(*share);
*share = NULL;
return -ENOMEM; return -ENOMEM;
} }
if (plen1) c = strscpy(ppath, target_ppath, len);
scnprintf(*prefix, len, "%.*s%c%.*s", (int)plen1, s, sep, (int)plen2, p); if (c && dfsref_pplen)
else ppath[c] = sep;
strscpy(*prefix, p, len); strlcat(ppath, dfsref_ppath, len);
} }
*share = target_share;
*prefix = ppath;
return 0; return 0;
} }
...@@ -1327,9 +1341,9 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c ...@@ -1327,9 +1341,9 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
cifs_dbg(VFS, "%s: failed to convert address \'%s\'. skip address matching.\n", cifs_dbg(VFS, "%s: failed to convert address \'%s\'. skip address matching.\n",
__func__, ip); __func__, ip);
} else { } else {
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, &sa); match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, &sa);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
} }
kfree(ip); kfree(ip);
......
...@@ -1120,14 +1120,14 @@ sess_establish_session(struct sess_data *sess_data) ...@@ -1120,14 +1120,14 @@ sess_establish_session(struct sess_data *sess_data)
struct cifs_ses *ses = sess_data->ses; struct cifs_ses *ses = sess_data->ses;
struct TCP_Server_Info *server = sess_data->server; struct TCP_Server_Info *server = sess_data->server;
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
if (!server->session_estab) { if (!server->session_estab) {
if (server->sign) { if (server->sign) {
server->session_key.response = server->session_key.response =
kmemdup(ses->auth_key.response, kmemdup(ses->auth_key.response,
ses->auth_key.len, GFP_KERNEL); ses->auth_key.len, GFP_KERNEL);
if (!server->session_key.response) { if (!server->session_key.response) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
return -ENOMEM; return -ENOMEM;
} }
server->session_key.len = server->session_key.len =
...@@ -1136,7 +1136,7 @@ sess_establish_session(struct sess_data *sess_data) ...@@ -1136,7 +1136,7 @@ sess_establish_session(struct sess_data *sess_data)
server->sequence_number = 0x2; server->sequence_number = 0x2;
server->session_estab = true; server->session_estab = true;
} }
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
cifs_dbg(FYI, "CIFS session established successfully\n"); cifs_dbg(FYI, "CIFS session established successfully\n");
return 0; return 0;
......
...@@ -38,10 +38,10 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, ...@@ -38,10 +38,10 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
in_buf->WordCount = 0; in_buf->WordCount = 0;
put_bcc(0, in_buf); put_bcc(0, in_buf);
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
rc = cifs_sign_smb(in_buf, server, &mid->sequence_number); rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
if (rc) { if (rc) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
return rc; return rc;
} }
...@@ -55,7 +55,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, ...@@ -55,7 +55,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
if (rc < 0) if (rc < 0)
server->sequence_number--; server->sequence_number--;
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
cifs_dbg(FYI, "issued NT_CANCEL for mid %u, rc = %d\n", cifs_dbg(FYI, "issued NT_CANCEL for mid %u, rc = %d\n",
get_mid(in_buf), rc); get_mid(in_buf), rc);
......
...@@ -3859,7 +3859,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, ...@@ -3859,7 +3859,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
if (rc) if (rc)
goto out; goto out;
if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0) if (cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)
smb2_set_sparse(xid, tcon, cfile, inode, false); smb2_set_sparse(xid, tcon, cfile, inode, false);
eof = cpu_to_le64(off + len); eof = cpu_to_le64(off + len);
...@@ -4345,11 +4345,13 @@ smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, ...@@ -4345,11 +4345,13 @@ smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
} }
} }
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
static bool static bool
smb2_is_read_op(__u32 oplock) smb2_is_read_op(__u32 oplock)
{ {
return oplock == SMB2_OPLOCK_LEVEL_II; return oplock == SMB2_OPLOCK_LEVEL_II;
} }
#endif /* CIFS_ALLOW_INSECURE_LEGACY */
static bool static bool
smb21_is_read_op(__u32 oplock) smb21_is_read_op(__u32 oplock)
...@@ -5448,7 +5450,7 @@ smb2_make_node(unsigned int xid, struct inode *inode, ...@@ -5448,7 +5450,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
return rc; return rc;
} }
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
struct smb_version_operations smb20_operations = { struct smb_version_operations smb20_operations = {
.compare_fids = smb2_compare_fids, .compare_fids = smb2_compare_fids,
.setup_request = smb2_setup_request, .setup_request = smb2_setup_request,
...@@ -5547,6 +5549,7 @@ struct smb_version_operations smb20_operations = { ...@@ -5547,6 +5549,7 @@ struct smb_version_operations smb20_operations = {
.is_status_io_timeout = smb2_is_status_io_timeout, .is_status_io_timeout = smb2_is_status_io_timeout,
.is_network_name_deleted = smb2_is_network_name_deleted, .is_network_name_deleted = smb2_is_network_name_deleted,
}; };
#endif /* CIFS_ALLOW_INSECURE_LEGACY */
struct smb_version_operations smb21_operations = { struct smb_version_operations smb21_operations = {
.compare_fids = smb2_compare_fids, .compare_fids = smb2_compare_fids,
...@@ -5878,6 +5881,7 @@ struct smb_version_operations smb311_operations = { ...@@ -5878,6 +5881,7 @@ struct smb_version_operations smb311_operations = {
.is_network_name_deleted = smb2_is_network_name_deleted, .is_network_name_deleted = smb2_is_network_name_deleted,
}; };
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
struct smb_version_values smb20_values = { struct smb_version_values smb20_values = {
.version_string = SMB20_VERSION_STRING, .version_string = SMB20_VERSION_STRING,
.protocol_id = SMB20_PROT_ID, .protocol_id = SMB20_PROT_ID,
...@@ -5898,6 +5902,7 @@ struct smb_version_values smb20_values = { ...@@ -5898,6 +5902,7 @@ struct smb_version_values smb20_values = {
.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
.create_lease_size = sizeof(struct create_lease), .create_lease_size = sizeof(struct create_lease),
}; };
#endif /* ALLOW_INSECURE_LEGACY */
struct smb_version_values smb21_values = { struct smb_version_values smb21_values = {
.version_string = SMB21_VERSION_STRING, .version_string = SMB21_VERSION_STRING,
......
...@@ -1369,13 +1369,13 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data) ...@@ -1369,13 +1369,13 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)
struct cifs_ses *ses = sess_data->ses; struct cifs_ses *ses = sess_data->ses;
struct TCP_Server_Info *server = sess_data->server; struct TCP_Server_Info *server = sess_data->server;
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
if (server->ops->generate_signingkey) { if (server->ops->generate_signingkey) {
rc = server->ops->generate_signingkey(ses, server); rc = server->ops->generate_signingkey(ses, server);
if (rc) { if (rc) {
cifs_dbg(FYI, cifs_dbg(FYI,
"SMB3 session key generation failed\n"); "SMB3 session key generation failed\n");
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
return rc; return rc;
} }
} }
...@@ -1383,7 +1383,7 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data) ...@@ -1383,7 +1383,7 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)
server->sequence_number = 0x2; server->sequence_number = 0x2;
server->session_estab = true; server->session_estab = true;
} }
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
cifs_dbg(FYI, "SMB2/3 session established successfully\n"); cifs_dbg(FYI, "SMB2/3 session established successfully\n");
return rc; return rc;
......
...@@ -1382,9 +1382,9 @@ void smbd_destroy(struct TCP_Server_Info *server) ...@@ -1382,9 +1382,9 @@ void smbd_destroy(struct TCP_Server_Info *server)
log_rdma_event(INFO, "freeing mr list\n"); log_rdma_event(INFO, "freeing mr list\n");
wake_up_interruptible_all(&info->wait_mr); wake_up_interruptible_all(&info->wait_mr);
while (atomic_read(&info->mr_used_count)) { while (atomic_read(&info->mr_used_count)) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
msleep(1000); msleep(1000);
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
} }
destroy_mr_list(info); destroy_mr_list(info);
......
...@@ -822,7 +822,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, ...@@ -822,7 +822,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
} else } else
instance = exist_credits->instance; instance = exist_credits->instance;
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
/* /*
* We can't use credits obtained from the previous session to send this * We can't use credits obtained from the previous session to send this
...@@ -830,14 +830,14 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, ...@@ -830,14 +830,14 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
* return -EAGAIN in such cases to let callers handle it. * return -EAGAIN in such cases to let callers handle it.
*/ */
if (instance != server->reconnect_instance) { if (instance != server->reconnect_instance) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
add_credits_and_wake_if(server, &credits, optype); add_credits_and_wake_if(server, &credits, optype);
return -EAGAIN; return -EAGAIN;
} }
mid = server->ops->setup_async_request(server, rqst); mid = server->ops->setup_async_request(server, rqst);
if (IS_ERR(mid)) { if (IS_ERR(mid)) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
add_credits_and_wake_if(server, &credits, optype); add_credits_and_wake_if(server, &credits, optype);
return PTR_ERR(mid); return PTR_ERR(mid);
} }
...@@ -868,7 +868,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, ...@@ -868,7 +868,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
cifs_delete_mid(mid); cifs_delete_mid(mid);
} }
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
if (rc == 0) if (rc == 0)
return 0; return 0;
...@@ -1109,7 +1109,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -1109,7 +1109,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
* of smb data. * of smb data.
*/ */
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
/* /*
* All the parts of the compound chain belong obtained credits from the * All the parts of the compound chain belong obtained credits from the
...@@ -1119,7 +1119,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -1119,7 +1119,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
* handle it. * handle it.
*/ */
if (instance != server->reconnect_instance) { if (instance != server->reconnect_instance) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
for (j = 0; j < num_rqst; j++) for (j = 0; j < num_rqst; j++)
add_credits(server, &credits[j], optype); add_credits(server, &credits[j], optype);
return -EAGAIN; return -EAGAIN;
...@@ -1131,7 +1131,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -1131,7 +1131,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
revert_current_mid(server, i); revert_current_mid(server, i);
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
cifs_delete_mid(midQ[j]); cifs_delete_mid(midQ[j]);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
/* Update # of requests on wire to server */ /* Update # of requests on wire to server */
for (j = 0; j < num_rqst; j++) for (j = 0; j < num_rqst; j++)
...@@ -1163,7 +1163,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -1163,7 +1163,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
server->sequence_number -= 2; server->sequence_number -= 2;
} }
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
/* /*
* If sending failed for some reason or it is an oplock break that we * If sending failed for some reason or it is an oplock break that we
...@@ -1190,9 +1190,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -1190,9 +1190,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) { if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
smb311_update_preauth_hash(ses, server, rqst[0].rq_iov, rqst[0].rq_nvec); smb311_update_preauth_hash(ses, server, rqst[0].rq_iov, rqst[0].rq_nvec);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
} }
...@@ -1266,9 +1266,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -1266,9 +1266,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
.iov_len = resp_iov[0].iov_len .iov_len = resp_iov[0].iov_len
}; };
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
smb311_update_preauth_hash(ses, server, &iov, 1); smb311_update_preauth_hash(ses, server, &iov, 1);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
} }
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
...@@ -1385,11 +1385,11 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, ...@@ -1385,11 +1385,11 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
and avoid races inside tcp sendmsg code that could cause corruption and avoid races inside tcp sendmsg code that could cause corruption
of smb data */ of smb data */
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
rc = allocate_mid(ses, in_buf, &midQ); rc = allocate_mid(ses, in_buf, &midQ);
if (rc) { if (rc) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
/* Update # of requests on wire to server */ /* Update # of requests on wire to server */
add_credits(server, &credits, 0); add_credits(server, &credits, 0);
return rc; return rc;
...@@ -1397,7 +1397,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, ...@@ -1397,7 +1397,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number);
if (rc) { if (rc) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
goto out; goto out;
} }
...@@ -1411,7 +1411,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, ...@@ -1411,7 +1411,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
if (rc < 0) if (rc < 0)
server->sequence_number -= 2; server->sequence_number -= 2;
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
if (rc < 0) if (rc < 0)
goto out; goto out;
...@@ -1530,18 +1530,18 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1530,18 +1530,18 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
and avoid races inside tcp sendmsg code that could cause corruption and avoid races inside tcp sendmsg code that could cause corruption
of smb data */ of smb data */
mutex_lock(&server->srv_mutex); cifs_server_lock(server);
rc = allocate_mid(ses, in_buf, &midQ); rc = allocate_mid(ses, in_buf, &midQ);
if (rc) { if (rc) {
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
return rc; return rc;
} }
rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number);
if (rc) { if (rc) {
cifs_delete_mid(midQ); cifs_delete_mid(midQ);
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
return rc; return rc;
} }
...@@ -1554,7 +1554,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1554,7 +1554,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
if (rc < 0) if (rc < 0)
server->sequence_number -= 2; server->sequence_number -= 2;
mutex_unlock(&server->srv_mutex); cifs_server_unlock(server);
if (rc < 0) { if (rc < 0) {
cifs_delete_mid(midQ); cifs_delete_mid(midQ);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment