Skip to content

Commit f3ba7c9

Browse files
Wang Zhaolongsmfrench
authored andcommitted
smb: client: rename server mid_lock to mid_queue_lock
This is step 1/4 of a patch series to fix mid_q_entry memory leaks caused by race conditions in callback execution. The current mid_lock name is somewhat ambiguous about what it protects. To prepare for splitting this lock into separate, more granular locks, this patch renames mid_lock to mid_queue_lock to clearly indicate its specific responsibility for protecting the pending_mid_q list and related queue operations. No functional changes are made in this patch - it only prepares the codebase for the lock splitting that follows. - mid_queue_lock for queue operations - mid_counter_lock for mid counter operations - per-mid locks for individual mid state management Signed-off-by: Wang Zhaolong <[email protected]> Acked-by: Enzo Matsumiya <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 5b432ae commit f3ba7c9

File tree

7 files changed

+54
-54
lines changed

7 files changed

+54
-54
lines changed

fs/smb/client/cifs_debug.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
6060
return;
6161

6262
cifs_dbg(VFS, "Dump pending requests:\n");
63-
spin_lock(&server->mid_lock);
63+
spin_lock(&server->mid_queue_lock);
6464
list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
6565
cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
6666
mid_entry->mid_state,
@@ -83,7 +83,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
8383
mid_entry->resp_buf, 62);
8484
}
8585
}
86-
spin_unlock(&server->mid_lock);
86+
spin_unlock(&server->mid_queue_lock);
8787
#endif /* CONFIG_CIFS_DEBUG2 */
8888
}
8989

@@ -672,7 +672,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
672672

673673
seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
674674
chan_server->conn_id);
675-
spin_lock(&chan_server->mid_lock);
675+
spin_lock(&chan_server->mid_queue_lock);
676676
list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
677677
seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
678678
mid_entry->mid_state,
@@ -681,7 +681,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
681681
mid_entry->callback_data,
682682
mid_entry->mid);
683683
}
684-
spin_unlock(&chan_server->mid_lock);
684+
spin_unlock(&chan_server->mid_queue_lock);
685685
}
686686
spin_unlock(&ses->chan_lock);
687687
seq_puts(m, "\n--\n");

fs/smb/client/cifsglob.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ struct TCP_Server_Info {
732732
#endif
733733
wait_queue_head_t response_q;
734734
wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
735-
spinlock_t mid_lock; /* protect mid queue and it's entries */
735+
spinlock_t mid_queue_lock; /* protect mid queue */
736736
struct list_head pending_mid_q;
737737
bool noblocksnd; /* use blocking sendmsg */
738738
bool noautotune; /* do not autotune send buf sizes */
@@ -2007,7 +2007,7 @@ require use of the stronger protocol */
20072007
* GlobalCurrentXid
20082008
* GlobalTotalActiveXid
20092009
* TCP_Server_Info->srv_lock (anything in struct not protected by another lock and can change)
2010-
* TCP_Server_Info->mid_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
2010+
* TCP_Server_Info->mid_queue_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
20112011
* ->CurrentMid
20122012
* (any changes in mid_q_entry fields)
20132013
* TCP_Server_Info->req_lock TCP_Server_Info->in_flight cifs_get_tcp_session

fs/smb/client/connect.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,15 @@ cifs_abort_connection(struct TCP_Server_Info *server)
321321
/* mark submitted MIDs for retry and issue callback */
322322
INIT_LIST_HEAD(&retry_list);
323323
cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
324-
spin_lock(&server->mid_lock);
324+
spin_lock(&server->mid_queue_lock);
325325
list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {
326326
kref_get(&mid->refcount);
327327
if (mid->mid_state == MID_REQUEST_SUBMITTED)
328328
mid->mid_state = MID_RETRY_NEEDED;
329329
list_move(&mid->qhead, &retry_list);
330330
mid->mid_flags |= MID_DELETED;
331331
}
332-
spin_unlock(&server->mid_lock);
332+
spin_unlock(&server->mid_queue_lock);
333333
cifs_server_unlock(server);
334334

335335
cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
@@ -884,13 +884,13 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
884884
* server there should be exactly one pending mid
885885
* corresponding to SMB1/SMB2 Negotiate packet.
886886
*/
887-
spin_lock(&server->mid_lock);
887+
spin_lock(&server->mid_queue_lock);
888888
list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {
889889
kref_get(&mid->refcount);
890890
list_move(&mid->qhead, &dispose_list);
891891
mid->mid_flags |= MID_DELETED;
892892
}
893-
spin_unlock(&server->mid_lock);
893+
spin_unlock(&server->mid_queue_lock);
894894

895895
/* Now try to reconnect once with NetBIOS session. */
896896
server->with_rfc1001 = true;
@@ -957,7 +957,7 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
957957
#ifdef CONFIG_CIFS_STATS2
958958
mid->when_received = jiffies;
959959
#endif
960-
spin_lock(&mid->server->mid_lock);
960+
spin_lock(&mid->server->mid_queue_lock);
961961
if (!malformed)
962962
mid->mid_state = MID_RESPONSE_RECEIVED;
963963
else
@@ -967,12 +967,12 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
967967
* function has finished processing it is a bug.
968968
*/
969969
if (mid->mid_flags & MID_DELETED) {
970-
spin_unlock(&mid->server->mid_lock);
970+
spin_unlock(&mid->server->mid_queue_lock);
971971
pr_warn_once("trying to dequeue a deleted mid\n");
972972
} else {
973973
list_del_init(&mid->qhead);
974974
mid->mid_flags |= MID_DELETED;
975-
spin_unlock(&mid->server->mid_lock);
975+
spin_unlock(&mid->server->mid_queue_lock);
976976
}
977977
}
978978

@@ -1101,7 +1101,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
11011101
struct list_head *tmp, *tmp2;
11021102
LIST_HEAD(dispose_list);
11031103

1104-
spin_lock(&server->mid_lock);
1104+
spin_lock(&server->mid_queue_lock);
11051105
list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
11061106
mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
11071107
cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid);
@@ -1110,7 +1110,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
11101110
list_move(&mid_entry->qhead, &dispose_list);
11111111
mid_entry->mid_flags |= MID_DELETED;
11121112
}
1113-
spin_unlock(&server->mid_lock);
1113+
spin_unlock(&server->mid_queue_lock);
11141114

11151115
/* now walk dispose list and issue callbacks */
11161116
list_for_each_safe(tmp, tmp2, &dispose_list) {
@@ -1822,7 +1822,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
18221822
tcp_ses->compression.requested = ctx->compress;
18231823
spin_lock_init(&tcp_ses->req_lock);
18241824
spin_lock_init(&tcp_ses->srv_lock);
1825-
spin_lock_init(&tcp_ses->mid_lock);
1825+
spin_lock_init(&tcp_ses->mid_queue_lock);
18261826
INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
18271827
INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
18281828
INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);

fs/smb/client/smb1ops.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,17 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
9595
struct smb_hdr *buf = (struct smb_hdr *)buffer;
9696
struct mid_q_entry *mid;
9797

98-
spin_lock(&server->mid_lock);
98+
spin_lock(&server->mid_queue_lock);
9999
list_for_each_entry(mid, &server->pending_mid_q, qhead) {
100100
if (compare_mid(mid->mid, buf) &&
101101
mid->mid_state == MID_REQUEST_SUBMITTED &&
102102
le16_to_cpu(mid->command) == buf->Command) {
103103
kref_get(&mid->refcount);
104-
spin_unlock(&server->mid_lock);
104+
spin_unlock(&server->mid_queue_lock);
105105
return mid;
106106
}
107107
}
108-
spin_unlock(&server->mid_lock);
108+
spin_unlock(&server->mid_queue_lock);
109109
return NULL;
110110
}
111111

@@ -169,7 +169,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server)
169169
__u16 last_mid, cur_mid;
170170
bool collision, reconnect = false;
171171

172-
spin_lock(&server->mid_lock);
172+
spin_lock(&server->mid_queue_lock);
173173

174174
/* mid is 16 bit only for CIFS/SMB */
175175
cur_mid = (__u16)((server->CurrentMid) & 0xffff);
@@ -228,7 +228,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server)
228228
}
229229
cur_mid++;
230230
}
231-
spin_unlock(&server->mid_lock);
231+
spin_unlock(&server->mid_queue_lock);
232232

233233
if (reconnect) {
234234
cifs_signal_cifsd_for_reconnect(server, false);

fs/smb/client/smb2ops.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -374,19 +374,19 @@ smb2_get_next_mid(struct TCP_Server_Info *server)
374374
{
375375
__u64 mid;
376376
/* for SMB2 we need the current value */
377-
spin_lock(&server->mid_lock);
377+
spin_lock(&server->mid_queue_lock);
378378
mid = server->CurrentMid++;
379-
spin_unlock(&server->mid_lock);
379+
spin_unlock(&server->mid_queue_lock);
380380
return mid;
381381
}
382382

383383
static void
384384
smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
385385
{
386-
spin_lock(&server->mid_lock);
386+
spin_lock(&server->mid_queue_lock);
387387
if (server->CurrentMid >= val)
388388
server->CurrentMid -= val;
389-
spin_unlock(&server->mid_lock);
389+
spin_unlock(&server->mid_queue_lock);
390390
}
391391

392392
static struct mid_q_entry *
@@ -401,7 +401,7 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
401401
return NULL;
402402
}
403403

404-
spin_lock(&server->mid_lock);
404+
spin_lock(&server->mid_queue_lock);
405405
list_for_each_entry(mid, &server->pending_mid_q, qhead) {
406406
if ((mid->mid == wire_mid) &&
407407
(mid->mid_state == MID_REQUEST_SUBMITTED) &&
@@ -411,11 +411,11 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
411411
list_del_init(&mid->qhead);
412412
mid->mid_flags |= MID_DELETED;
413413
}
414-
spin_unlock(&server->mid_lock);
414+
spin_unlock(&server->mid_queue_lock);
415415
return mid;
416416
}
417417
}
418-
spin_unlock(&server->mid_lock);
418+
spin_unlock(&server->mid_queue_lock);
419419
return NULL;
420420
}
421421

@@ -460,9 +460,9 @@ smb2_negotiate(const unsigned int xid,
460460
{
461461
int rc;
462462

463-
spin_lock(&server->mid_lock);
463+
spin_lock(&server->mid_queue_lock);
464464
server->CurrentMid = 0;
465-
spin_unlock(&server->mid_lock);
465+
spin_unlock(&server->mid_queue_lock);
466466
rc = SMB2_negotiate(xid, ses, server);
467467
return rc;
468468
}
@@ -4809,18 +4809,18 @@ static void smb2_decrypt_offload(struct work_struct *work)
48094809
} else {
48104810
spin_lock(&dw->server->srv_lock);
48114811
if (dw->server->tcpStatus == CifsNeedReconnect) {
4812-
spin_lock(&dw->server->mid_lock);
4812+
spin_lock(&dw->server->mid_queue_lock);
48134813
mid->mid_state = MID_RETRY_NEEDED;
4814-
spin_unlock(&dw->server->mid_lock);
4814+
spin_unlock(&dw->server->mid_queue_lock);
48154815
spin_unlock(&dw->server->srv_lock);
48164816
mid->callback(mid);
48174817
} else {
4818-
spin_lock(&dw->server->mid_lock);
4818+
spin_lock(&dw->server->mid_queue_lock);
48194819
mid->mid_state = MID_REQUEST_SUBMITTED;
48204820
mid->mid_flags &= ~(MID_DELETED);
48214821
list_add_tail(&mid->qhead,
48224822
&dw->server->pending_mid_q);
4823-
spin_unlock(&dw->server->mid_lock);
4823+
spin_unlock(&dw->server->mid_queue_lock);
48244824
spin_unlock(&dw->server->srv_lock);
48254825
}
48264826
}

fs/smb/client/smb2transport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,9 +840,9 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
840840
*mid = smb2_mid_entry_alloc(shdr, server);
841841
if (*mid == NULL)
842842
return -ENOMEM;
843-
spin_lock(&server->mid_lock);
843+
spin_lock(&server->mid_queue_lock);
844844
list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
845-
spin_unlock(&server->mid_lock);
845+
spin_unlock(&server->mid_queue_lock);
846846

847847
return 0;
848848
}

fs/smb/client/transport.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@ void __release_mid(struct kref *refcount)
160160
void
161161
delete_mid(struct mid_q_entry *mid)
162162
{
163-
spin_lock(&mid->server->mid_lock);
163+
spin_lock(&mid->server->mid_queue_lock);
164164
if (!(mid->mid_flags & MID_DELETED)) {
165165
list_del_init(&mid->qhead);
166166
mid->mid_flags |= MID_DELETED;
167167
}
168-
spin_unlock(&mid->server->mid_lock);
168+
spin_unlock(&mid->server->mid_queue_lock);
169169

170170
release_mid(mid);
171171
}
@@ -716,9 +716,9 @@ static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
716716
*ppmidQ = alloc_mid(in_buf, ses->server);
717717
if (*ppmidQ == NULL)
718718
return -ENOMEM;
719-
spin_lock(&ses->server->mid_lock);
719+
spin_lock(&ses->server->mid_queue_lock);
720720
list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
721-
spin_unlock(&ses->server->mid_lock);
721+
spin_unlock(&ses->server->mid_queue_lock);
722722
return 0;
723723
}
724724

@@ -819,9 +819,9 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
819819
mid->mid_state = MID_REQUEST_SUBMITTED;
820820

821821
/* put it on the pending_mid_q */
822-
spin_lock(&server->mid_lock);
822+
spin_lock(&server->mid_queue_lock);
823823
list_add_tail(&mid->qhead, &server->pending_mid_q);
824-
spin_unlock(&server->mid_lock);
824+
spin_unlock(&server->mid_queue_lock);
825825

826826
/*
827827
* Need to store the time in mid before calling I/O. For call_async,
@@ -880,10 +880,10 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
880880
cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
881881
__func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
882882

883-
spin_lock(&server->mid_lock);
883+
spin_lock(&server->mid_queue_lock);
884884
switch (mid->mid_state) {
885885
case MID_RESPONSE_READY:
886-
spin_unlock(&server->mid_lock);
886+
spin_unlock(&server->mid_queue_lock);
887887
return rc;
888888
case MID_RETRY_NEEDED:
889889
rc = -EAGAIN;
@@ -902,13 +902,13 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
902902
list_del_init(&mid->qhead);
903903
mid->mid_flags |= MID_DELETED;
904904
}
905-
spin_unlock(&server->mid_lock);
905+
spin_unlock(&server->mid_queue_lock);
906906
cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
907907
__func__, mid->mid, mid->mid_state);
908908
rc = -EIO;
909909
goto sync_mid_done;
910910
}
911-
spin_unlock(&server->mid_lock);
911+
spin_unlock(&server->mid_queue_lock);
912912

913913
sync_mid_done:
914914
release_mid(mid);
@@ -1213,15 +1213,15 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
12131213
cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",
12141214
midQ[i]->mid, le16_to_cpu(midQ[i]->command));
12151215
send_cancel(server, &rqst[i], midQ[i]);
1216-
spin_lock(&server->mid_lock);
1216+
spin_lock(&server->mid_queue_lock);
12171217
midQ[i]->mid_flags |= MID_WAIT_CANCELLED;
12181218
if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED ||
12191219
midQ[i]->mid_state == MID_RESPONSE_RECEIVED) {
12201220
midQ[i]->callback = cifs_cancelled_callback;
12211221
cancelled_mid[i] = true;
12221222
credits[i].value = 0;
12231223
}
1224-
spin_unlock(&server->mid_lock);
1224+
spin_unlock(&server->mid_queue_lock);
12251225
}
12261226
}
12271227

@@ -1423,16 +1423,16 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
14231423
rc = wait_for_response(server, midQ);
14241424
if (rc != 0) {
14251425
send_cancel(server, &rqst, midQ);
1426-
spin_lock(&server->mid_lock);
1426+
spin_lock(&server->mid_queue_lock);
14271427
if (midQ->mid_state == MID_REQUEST_SUBMITTED ||
14281428
midQ->mid_state == MID_RESPONSE_RECEIVED) {
14291429
/* no longer considered to be "in-flight" */
14301430
midQ->callback = release_mid;
1431-
spin_unlock(&server->mid_lock);
1431+
spin_unlock(&server->mid_queue_lock);
14321432
add_credits(server, &credits, 0);
14331433
return rc;
14341434
}
1435-
spin_unlock(&server->mid_lock);
1435+
spin_unlock(&server->mid_queue_lock);
14361436
}
14371437

14381438
rc = cifs_sync_mid_result(midQ, server);
@@ -1605,15 +1605,15 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
16051605
rc = wait_for_response(server, midQ);
16061606
if (rc) {
16071607
send_cancel(server, &rqst, midQ);
1608-
spin_lock(&server->mid_lock);
1608+
spin_lock(&server->mid_queue_lock);
16091609
if (midQ->mid_state == MID_REQUEST_SUBMITTED ||
16101610
midQ->mid_state == MID_RESPONSE_RECEIVED) {
16111611
/* no longer considered to be "in-flight" */
16121612
midQ->callback = release_mid;
1613-
spin_unlock(&server->mid_lock);
1613+
spin_unlock(&server->mid_queue_lock);
16141614
return rc;
16151615
}
1616-
spin_unlock(&server->mid_lock);
1616+
spin_unlock(&server->mid_queue_lock);
16171617
}
16181618

16191619
/* We got the response - restart system call. */

0 commit comments

Comments
 (0)