mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 07:03:03 +02:00
cifs: Fix locking usage for tcon fields
We used to use the cifs_tcp_ses_lock to protect a lot of objects that are not just the server, ses or tcon lists. We later introduced srv_lock, ses_lock and tc_lock to protect fields within the corresponding structs. This was done to provide a more granular protection and avoid unnecessary serialization. There were still a couple of uses of cifs_tcp_ses_lock to provide tcon fields. In this patch, I've replaced them with tc_lock. Cc: stable@vger.kernel.org Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
037ddbcc10
commit
96c4af4185
|
|
@ -792,11 +792,11 @@ static void cfids_laundromat_worker(struct work_struct *work)
|
||||||
cfid->dentry = NULL;
|
cfid->dentry = NULL;
|
||||||
|
|
||||||
if (cfid->is_open) {
|
if (cfid->is_open) {
|
||||||
spin_lock(&cifs_tcp_ses_lock);
|
spin_lock(&cfid->tcon->tc_lock);
|
||||||
++cfid->tcon->tc_count;
|
++cfid->tcon->tc_count;
|
||||||
trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count,
|
trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count,
|
||||||
netfs_trace_tcon_ref_get_cached_laundromat);
|
netfs_trace_tcon_ref_get_cached_laundromat);
|
||||||
spin_unlock(&cifs_tcp_ses_lock);
|
spin_unlock(&cfid->tcon->tc_lock);
|
||||||
queue_work(serverclose_wq, &cfid->close_work);
|
queue_work(serverclose_wq, &cfid->close_work);
|
||||||
} else
|
} else
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -820,14 +820,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
|
cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
|
||||||
spin_lock(&cifs_tcp_ses_lock);
|
spin_lock(&tcon->tc_lock);
|
||||||
if (tcon->tc_count <= 0) {
|
if (tcon->tc_count <= 0) {
|
||||||
struct TCP_Server_Info *server = NULL;
|
struct TCP_Server_Info *server = NULL;
|
||||||
|
|
||||||
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
||||||
netfs_trace_tcon_ref_see_cancelled_close);
|
netfs_trace_tcon_ref_see_cancelled_close);
|
||||||
WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
|
WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
|
||||||
spin_unlock(&cifs_tcp_ses_lock);
|
spin_unlock(&tcon->tc_lock);
|
||||||
|
|
||||||
if (tcon->ses) {
|
if (tcon->ses) {
|
||||||
server = tcon->ses->server;
|
server = tcon->ses->server;
|
||||||
|
|
@ -841,7 +841,7 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
|
||||||
tcon->tc_count++;
|
tcon->tc_count++;
|
||||||
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
||||||
netfs_trace_tcon_ref_get_cancelled_close);
|
netfs_trace_tcon_ref_get_cancelled_close);
|
||||||
spin_unlock(&cifs_tcp_ses_lock);
|
spin_unlock(&tcon->tc_lock);
|
||||||
|
|
||||||
rc = __smb2_handle_cancelled_cmd(tcon, SMB2_CLOSE_HE, 0,
|
rc = __smb2_handle_cancelled_cmd(tcon, SMB2_CLOSE_HE, 0,
|
||||||
persistent_fid, volatile_fid);
|
persistent_fid, volatile_fid);
|
||||||
|
|
|
||||||
|
|
@ -3107,7 +3107,9 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
|
||||||
struct cifs_tcon,
|
struct cifs_tcon,
|
||||||
tcon_list);
|
tcon_list);
|
||||||
if (tcon) {
|
if (tcon) {
|
||||||
|
spin_lock(&tcon->tc_lock);
|
||||||
tcon->tc_count++;
|
tcon->tc_count++;
|
||||||
|
spin_unlock(&tcon->tc_lock);
|
||||||
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
||||||
netfs_trace_tcon_ref_get_dfs_refer);
|
netfs_trace_tcon_ref_get_dfs_refer);
|
||||||
}
|
}
|
||||||
|
|
@ -3176,13 +3178,9 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
|
||||||
out:
|
out:
|
||||||
if (tcon && !tcon->ipc) {
|
if (tcon && !tcon->ipc) {
|
||||||
/* ipc tcons are not refcounted */
|
/* ipc tcons are not refcounted */
|
||||||
spin_lock(&cifs_tcp_ses_lock);
|
cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_dfs_refer);
|
||||||
tcon->tc_count--;
|
|
||||||
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
||||||
netfs_trace_tcon_ref_dec_dfs_refer);
|
netfs_trace_tcon_ref_dec_dfs_refer);
|
||||||
/* tc_count can never go negative */
|
|
||||||
WARN_ON(tcon->tc_count < 0);
|
|
||||||
spin_unlock(&cifs_tcp_ses_lock);
|
|
||||||
}
|
}
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
kfree(dfs_req);
|
kfree(dfs_req);
|
||||||
|
|
|
||||||
|
|
@ -4263,7 +4263,9 @@ void smb2_reconnect_server(struct work_struct *work)
|
||||||
|
|
||||||
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
||||||
if (tcon->need_reconnect || tcon->need_reopen_files) {
|
if (tcon->need_reconnect || tcon->need_reopen_files) {
|
||||||
|
spin_lock(&tcon->tc_lock);
|
||||||
tcon->tc_count++;
|
tcon->tc_count++;
|
||||||
|
spin_unlock(&tcon->tc_lock);
|
||||||
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
|
||||||
netfs_trace_tcon_ref_get_reconnect_server);
|
netfs_trace_tcon_ref_get_reconnect_server);
|
||||||
list_add_tail(&tcon->rlist, &tmp_list);
|
list_add_tail(&tcon->rlist, &tmp_list);
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,7 @@
|
||||||
EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \
|
EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \
|
||||||
EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \
|
EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \
|
||||||
EM(netfs_trace_tcon_ref_put_mnt_ctx, "PUT MntCtx") \
|
EM(netfs_trace_tcon_ref_put_mnt_ctx, "PUT MntCtx") \
|
||||||
|
EM(netfs_trace_tcon_ref_put_dfs_refer, "PUT DfsRfr") \
|
||||||
EM(netfs_trace_tcon_ref_put_reconnect_server, "PUT Reconn") \
|
EM(netfs_trace_tcon_ref_put_reconnect_server, "PUT Reconn") \
|
||||||
EM(netfs_trace_tcon_ref_put_tlink, "PUT Tlink ") \
|
EM(netfs_trace_tcon_ref_put_tlink, "PUT Tlink ") \
|
||||||
EM(netfs_trace_tcon_ref_see_cancelled_close, "SEE Cn-Cls") \
|
EM(netfs_trace_tcon_ref_see_cancelled_close, "SEE Cn-Cls") \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user