Skip to content

Commit dca6581

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: use a different reconnect helper for non-cifsd threads
The cifs_demultiplexer_thread should only call cifs_reconnect. If any other thread wants to trigger a reconnect, they can do so by updating the server tcpStatus to CifsNeedReconnect. The last patch attempted to use the same helper function for both types of threads, but that causes other issues with lock dependencies. This patch creates a new helper for non-cifsd threads, that will indicate to cifsd that the server needs reconnect. Fixes: 2a05137 ("cifs: mark sessions for reconnection in helper function") Signed-off-by: Shyam Prasad N <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 9a14b65 commit dca6581

File tree

6 files changed

+50
-7
lines changed

6 files changed

+50
-7
lines changed

fs/cifs/cifs_swn.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,11 @@ static int cifs_swn_resource_state_changed(struct cifs_swn_reg *swnreg, const ch
396396
switch (state) {
397397
case CIFS_SWN_RESOURCE_STATE_UNAVAILABLE:
398398
cifs_dbg(FYI, "%s: resource name '%s' become unavailable\n", __func__, name);
399-
cifs_mark_tcp_ses_conns_for_reconnect(swnreg->tcon->ses->server, true);
399+
cifs_signal_cifsd_for_reconnect(swnreg->tcon->ses->server, true);
400400
break;
401401
case CIFS_SWN_RESOURCE_STATE_AVAILABLE:
402402
cifs_dbg(FYI, "%s: resource name '%s' become available\n", __func__, name);
403-
cifs_mark_tcp_ses_conns_for_reconnect(swnreg->tcon->ses->server, true);
403+
cifs_signal_cifsd_for_reconnect(swnreg->tcon->ses->server, true);
404404
break;
405405
case CIFS_SWN_RESOURCE_STATE_UNKNOWN:
406406
cifs_dbg(FYI, "%s: resource name '%s' changed to unknown state\n", __func__, name);
@@ -498,7 +498,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *a
498498
goto unlock;
499499
}
500500

501-
cifs_mark_tcp_ses_conns_for_reconnect(tcon->ses->server, false);
501+
cifs_signal_cifsd_for_reconnect(tcon->ses->server, false);
502502

503503
unlock:
504504
mutex_unlock(&tcon->ses->server->srv_mutex);

fs/cifs/cifsproto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
132132
struct smb_hdr *out_buf,
133133
int *bytes_returned);
134134
void
135+
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
136+
bool all_channels);
137+
void
135138
cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
136139
bool mark_smb_session);
137140
extern int cifs_reconnect(struct TCP_Server_Info *server,

fs/cifs/connect.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,51 @@ static void cifs_resolve_server(struct work_struct *work)
162162
mutex_unlock(&server->srv_mutex);
163163
}
164164

165+
/*
166+
* Update the tcpStatus for the server.
167+
* This is used to signal the cifsd thread to call cifs_reconnect
168+
* ONLY cifsd thread should call cifs_reconnect. For any other
169+
* thread, use this function
170+
*
171+
* @server: the tcp ses for which reconnect is needed
172+
* @all_channels: if this needs to be done for all channels
173+
*/
174+
void
175+
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
176+
bool all_channels)
177+
{
178+
struct TCP_Server_Info *pserver;
179+
struct cifs_ses *ses;
180+
int i;
181+
182+
/* If server is a channel, select the primary channel */
183+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
184+
185+
spin_lock(&cifs_tcp_ses_lock);
186+
if (!all_channels) {
187+
pserver->tcpStatus = CifsNeedReconnect;
188+
spin_unlock(&cifs_tcp_ses_lock);
189+
return;
190+
}
191+
192+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
193+
spin_lock(&ses->chan_lock);
194+
for (i = 0; i < ses->chan_count; i++)
195+
ses->chans[i].server->tcpStatus = CifsNeedReconnect;
196+
spin_unlock(&ses->chan_lock);
197+
}
198+
spin_unlock(&cifs_tcp_ses_lock);
199+
}
200+
165201
/*
166202
* Mark all sessions and tcons for reconnect.
203+
* IMPORTANT: make sure that this gets called only from
204+
* cifsd thread. For any other thread, use
205+
* cifs_signal_cifsd_for_reconnect
167206
*
207+
* @server: the tcp ses for which reconnect is needed
168208
* @server needs to be previously set to CifsNeedReconnect.
169-
*
209+
* @mark_smb_session: whether even sessions need to be marked
170210
*/
171211
void
172212
cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,

fs/cifs/dfs_cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
13551355
}
13561356

13571357
cifs_dbg(FYI, "%s: no cached or matched targets. mark dfs share for reconnect.\n", __func__);
1358-
cifs_mark_tcp_ses_conns_for_reconnect(tcon->ses->server, true);
1358+
cifs_signal_cifsd_for_reconnect(tcon->ses->server, true);
13591359
}
13601360

13611361
/* Refresh dfs referral of tcon and mark it for reconnect if needed */

fs/cifs/smb1ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server)
228228
spin_unlock(&GlobalMid_Lock);
229229

230230
if (reconnect) {
231-
cifs_mark_tcp_ses_conns_for_reconnect(server, false);
231+
cifs_signal_cifsd_for_reconnect(server, false);
232232
}
233233

234234
return mid;

fs/cifs/transport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
430430
* be taken as the remainder of this one. We need to kill the
431431
* socket so the server throws away the partial SMB
432432
*/
433-
cifs_mark_tcp_ses_conns_for_reconnect(server, false);
433+
cifs_signal_cifsd_for_reconnect(server, false);
434434
trace_smb3_partial_send_reconnect(server->CurrentMid,
435435
server->conn_id, server->hostname);
436436
}

0 commit comments

Comments
 (0)