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 | list_del_init(&ses->smb_ses_list); | 1918 | list_del_init(&ses->smb_ses_list); |
| 1919 | spin_unlock(&cifs_tcp_ses_lock); | 1919 | spin_unlock(&cifs_tcp_ses_lock); |
| 1920 | 1920 | ||
| 1921 | spin_lock(&ses->chan_lock); | ||
| 1922 | chan_count = ses->chan_count; | 1921 | chan_count = ses->chan_count; |
| 1923 | 1922 | ||
| 1924 | /* close any extra channels */ | 1923 | /* close any extra channels */ |
| @@ -1934,7 +1933,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 9 unmodified lines | |||
| 1934 | ses->chans[i].server = NULL; | 1933 | ses->chans[i].server = NULL; |
| 1935 | } | 1934 | } |
| 1936 | } | 1935 | } |
| 1937 | spin_unlock(&ses->chan_lock); | ||
| 1938 | 1936 | ||
| 1939 | sesInfoFree(ses); | 1937 | sesInfoFree(ses); |
| 1940 | cifs_put_tcp_session(server, 0); | 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 | out: | 475 | out: |
| 476 | if (rc && chan->server) { | 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 | spin_lock(&ses->chan_lock); | 485 | spin_lock(&ses->chan_lock); |
| 478 | /* we rely on all bits beyond chan_count to be clear */ | 486 | /* we rely on all bits beyond chan_count to be clear */ |
| 479 | cifs_chan_clear_need_reconnect(ses, chan->server); | 487 | cifs_chan_clear_need_reconnect(ses, chan->server); |
| @@ -484,10 +492,9 @@ out: · 4 unmodified lines | |||
| 484 | */ | 492 | */ |
| 485 | WARN_ON(ses->chan_count < 1); | 493 | WARN_ON(ses->chan_count < 1); |
| 486 | spin_unlock(&ses->chan_lock); | 494 | spin_unlock(&ses->chan_lock); |
| 487 | } | ||
| 488 | 495 | ||
| 489 | if (rc && chan->server) | ||
| 490 | cifs_put_tcp_session(chan->server, 0); | 496 | cifs_put_tcp_session(chan->server, 0); |
| 497 | } | ||
| 491 | 498 | ||
| 492 | return rc; | 499 | return rc; |
| 493 | } | 500 | } |
| @@ -571,10 +571,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 570 unmodified lines | |||
| 571 | *total_len += ctxt_len; | 571 | *total_len += ctxt_len; |
| 572 | pneg_ctxt += ctxt_len; | 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 | * secondary channels don't have the hostname field populated | 575 | * secondary channels don't have the hostname field populated |
| 580 | * use the hostname field in the primary channel instead | 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 | hostname); | 582 | hostname); |
| 587 | *total_len += ctxt_len; | 583 | *total_len += ctxt_len; |
| 588 | pneg_ctxt += ctxt_len; | 584 | pneg_ctxt += ctxt_len; |
| 589 | neg_context_count = 4; | ||
| 590 | } else /* second channels do not have a hostname */ | ||
| 591 | neg_context_count = 3; | 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 | if (server->compress_algorithm) { | 594 | if (server->compress_algorithm) { |
| 594 | build_compression_ctxt((struct smb2_compression_capabilities_context *) | 595 | build_compression_ctxt((struct smb2_compression_capabilities_context *) |