Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 69cba9d

Browse files
nspmangaloreSteve French
authored andcommitted
cifs: fix mid leak during reconnection after timeout threshold
When the number of responses with status of STATUS_IO_TIMEOUT exceeds a specified threshold (NUM_STATUS_IO_TIMEOUT), we reconnect the connection. But we do not return the mid, or the credits returned for the mid, or reduce the number of in-flight requests. This bug could result in the server->in_flight count to go bad, and also cause a leak in the mids. This change moves the check to a few lines below where the response is decrypted, even of the response is read from the transform header. This way, the code for returning the mids can be reused. Also, the cifs_reconnect was reconnecting just the transport connection before. In case of multi-channel, this may not be what we want to do after several timeouts. Changed that to reconnect the session and the tree too. Also renamed NUM_STATUS_IO_TIMEOUT to a more appropriate name MAX_STATUS_IO_TIMEOUT. Fixes: 8e670f7 ("Handle STATUS_IO_TIMEOUT gracefully") Signed-off-by: Shyam Prasad N <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent c071b34 commit 69cba9d

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

fs/smb/client/connect.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extern bool disable_legacy_dialects;
6060
#define TLINK_IDLE_EXPIRE (600 * HZ)
6161

6262
/* Drop the connection to not overload the server */
63-
#define NUM_STATUS_IO_TIMEOUT 5
63+
#define MAX_STATUS_IO_TIMEOUT 5
6464

6565
static int ip_connect(struct TCP_Server_Info *server);
6666
static int generic_ip_connect(struct TCP_Server_Info *server);
@@ -1117,6 +1117,7 @@ cifs_demultiplex_thread(void *p)
11171117
struct mid_q_entry *mids[MAX_COMPOUND];
11181118
char *bufs[MAX_COMPOUND];
11191119
unsigned int noreclaim_flag, num_io_timeout = 0;
1120+
bool pending_reconnect = false;
11201121

11211122
noreclaim_flag = memalloc_noreclaim_save();
11221123
cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
@@ -1156,6 +1157,8 @@ cifs_demultiplex_thread(void *p)
11561157
cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
11571158
if (!is_smb_response(server, buf[0]))
11581159
continue;
1160+
1161+
pending_reconnect = false;
11591162
next_pdu:
11601163
server->pdu_size = pdu_length;
11611164

@@ -1213,10 +1216,13 @@ cifs_demultiplex_thread(void *p)
12131216
if (server->ops->is_status_io_timeout &&
12141217
server->ops->is_status_io_timeout(buf)) {
12151218
num_io_timeout++;
1216-
if (num_io_timeout > NUM_STATUS_IO_TIMEOUT) {
1217-
cifs_reconnect(server, false);
1219+
if (num_io_timeout > MAX_STATUS_IO_TIMEOUT) {
1220+
cifs_server_dbg(VFS,
1221+
"Number of request timeouts exceeded %d. Reconnecting",
1222+
MAX_STATUS_IO_TIMEOUT);
1223+
1224+
pending_reconnect = true;
12181225
num_io_timeout = 0;
1219-
continue;
12201226
}
12211227
}
12221228

@@ -1268,6 +1274,11 @@ cifs_demultiplex_thread(void *p)
12681274
buf = server->smallbuf;
12691275
goto next_pdu;
12701276
}
1277+
1278+
/* do this reconnect at the very end after processing all MIDs */
1279+
if (pending_reconnect)
1280+
cifs_reconnect(server, true);
1281+
12711282
} /* end while !EXITING */
12721283

12731284
/* buffer usually freed in free_mid - need to free it here on exit */

0 commit comments

Comments
 (0)