Commit 96c4af41 authored by Shyam Prasad N's avatar Shyam Prasad N Committed by Steve French
Browse files

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: default avatarShyam Prasad N <sprasad@microsoft.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 037ddbcc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -792,11 +792,11 @@ static void cfids_laundromat_worker(struct work_struct *work)
		cfid->dentry = NULL;

		if (cfid->is_open) {
			spin_lock(&cifs_tcp_ses_lock);
			spin_lock(&cfid->tcon->tc_lock);
			++cfid->tcon->tc_count;
			trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count,
					    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);
		} else
			/*
+3 −3
Original line number Diff line number Diff line
@@ -820,14 +820,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
	int rc;

	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) {
		struct TCP_Server_Info *server = NULL;

		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
				    netfs_trace_tcon_ref_see_cancelled_close);
		WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
		spin_unlock(&cifs_tcp_ses_lock);
		spin_unlock(&tcon->tc_lock);

		if (tcon->ses) {
			server = tcon->ses->server;
@@ -841,7 +841,7 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
	tcon->tc_count++;
	trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
			    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,
					 persistent_fid, volatile_fid);
+3 −5
Original line number Diff line number Diff line
@@ -3107,7 +3107,9 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
						struct cifs_tcon,
						tcon_list);
		if (tcon) {
			spin_lock(&tcon->tc_lock);
			tcon->tc_count++;
			spin_unlock(&tcon->tc_lock);
			trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
					    netfs_trace_tcon_ref_get_dfs_refer);
		}
@@ -3176,13 +3178,9 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
 out:
	if (tcon && !tcon->ipc) {
		/* ipc tcons are not refcounted */
		spin_lock(&cifs_tcp_ses_lock);
		tcon->tc_count--;
		cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_dfs_refer);
		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
				    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(dfs_req);
+2 −0
Original line number Diff line number Diff line
@@ -4263,7 +4263,9 @@ void smb2_reconnect_server(struct work_struct *work)

		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
			if (tcon->need_reconnect || tcon->need_reopen_files) {
				spin_lock(&tcon->tc_lock);
				tcon->tc_count++;
				spin_unlock(&tcon->tc_lock);
				trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
						    netfs_trace_tcon_ref_get_reconnect_server);
				list_add_tail(&tcon->rlist, &tmp_list);
+1 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@
	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_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_tlink,		"PUT Tlink ") \
	EM(netfs_trace_tcon_ref_see_cancelled_close,	"SEE Cn-Cls") \