Pull cifs fixes from Steve French: "Three smb3 client fixes: - two multichannel fixes: fix a potential deadlock freeing a channel, and fix a race condition on failed creation of a new channel - mount failure fix: work around a server bug in some common older Samba servers by avoiding padding at the end of the negotiate protocol request" * tag '5.19-rc6-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb3: workaround negprot bug in some Samba servers cifs: remove unnecessary locking of chan_lock while freeing session cifs: fix race condition with delayed threads
Unified · Split
| @@ -1918,7 +1918,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 1917 unmodified lines | ||
| 1918 | 1918 | list_del_init(&ses->smb_ses_list); |
| 1919 | 1919 | spin_unlock(&cifs_tcp_ses_lock); |
| 1920 | 1920 | |
| 1921 | − spin_lock(&ses->chan_lock); | |
| 1922 | 1921 | chan_count = ses->chan_count; |
| 1923 | 1922 | |
| 1924 | 1923 | /* close any extra channels */ |
| @@ -1934,7 +1933,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 9 unmodified lines | ||
| 1934 | 1933 | ses->chans[i].server = NULL; |
| 1935 | 1934 | } |
| 1936 | 1935 | } |
| 1937 | − spin_unlock(&ses->chan_lock); | |
| 1938 | 1936 | |
| 1939 | 1937 | sesInfoFree(ses); |
| 1940 | 1938 | cifs_put_tcp_session(server, 0); |
| @@ -474,6 +474,14 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, · 473 unmodified lines | ||
| 474 | 474 | |
| 475 | 475 | out: |
| 476 | 476 | if (rc && chan->server) { |
| 477 | + /* | |
| 478 | + * we should avoid race with these delayed works before we | |
| 479 | + * remove this channel | |
| 480 | + */ | |
| 481 | + cancel_delayed_work_sync(&chan->server->echo); | |
| 482 | + cancel_delayed_work_sync(&chan->server->resolve); | |
| 483 | + cancel_delayed_work_sync(&chan->server->reconnect); | |
| 484 | + | |
| 477 | 485 | spin_lock(&ses->chan_lock); |
| 478 | 486 | /* we rely on all bits beyond chan_count to be clear */ |
| 479 | 487 | cifs_chan_clear_need_reconnect(ses, chan->server); |
| @@ -484,10 +492,9 @@ out: · 4 unmodified lines | ||
| 484 | 492 | */ |
| 485 | 493 | WARN_ON(ses->chan_count < 1); |
| 486 | 494 | spin_unlock(&ses->chan_lock); |
| 487 | − } | |
| 488 | 495 | |
| 489 | − if (rc && chan->server) | |
| 490 | 496 | cifs_put_tcp_session(chan->server, 0); |
| 497 | + } | |
| 491 | 498 | |
| 492 | 499 | return rc; |
| 493 | 500 | } |
| @@ -571,10 +571,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 570 unmodified lines | ||
| 571 | 571 | *total_len += ctxt_len; |
| 572 | 572 | pneg_ctxt += ctxt_len; |
| 573 | 573 | |
| 574 | − build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); | |
| 575 | − *total_len += sizeof(struct smb2_posix_neg_context); | |
| 576 | − pneg_ctxt += sizeof(struct smb2_posix_neg_context); | |
| 577 | − | |
| 578 | 574 | /* |
| 579 | 575 | * secondary channels don't have the hostname field populated |
| 580 | 576 | * use the hostname field in the primary channel instead |
| @@ -586,9 +582,14 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 5 unmodified lines | ||
| 586 | 582 | hostname); |
| 587 | 583 | *total_len += ctxt_len; |
| 588 | 584 | pneg_ctxt += ctxt_len; |
| 589 | − neg_context_count = 4; | |
| 590 | − } else /* second channels do not have a hostname */ | |
| 591 | 585 | neg_context_count = 3; |
| 586 | + } else | |
| 587 | + neg_context_count = 2; | |
| 588 | + | |
| 589 | + build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); | |
| 590 | + *total_len += sizeof(struct smb2_posix_neg_context); | |
| 591 | + pneg_ctxt += sizeof(struct smb2_posix_neg_context); | |
| 592 | + neg_context_count++; | |
| 592 | 593 | |
| 593 | 594 | if (server->compress_algorithm) { |
| 594 | 595 | build_compression_ctxt((struct smb2_compression_capabilities_context *) |