@@ -371,7 +371,7 @@ static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num
371
371
*
372
372
*/
373
373
static int __cifs_reconnect (struct TCP_Server_Info * server ,
374
- bool mark_smb_session )
374
+ bool mark_smb_session , bool once )
375
375
{
376
376
int rc = 0 ;
377
377
@@ -399,6 +399,9 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
399
399
if (rc ) {
400
400
cifs_server_unlock (server );
401
401
cifs_dbg (FYI , "%s: reconnect error %d\n" , __func__ , rc );
402
+ /* If was asked to reconnect only once, do not try it more times */
403
+ if (once )
404
+ break ;
402
405
msleep (3000 );
403
406
} else {
404
407
atomic_inc (& tcpSesReconnectCount );
@@ -564,19 +567,33 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
564
567
return rc ;
565
568
}
566
569
567
- int cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
570
+ static int
571
+ _cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session , bool once )
568
572
{
569
573
if (!server -> leaf_fullpath )
570
- return __cifs_reconnect (server , mark_smb_session );
574
+ return __cifs_reconnect (server , mark_smb_session , once );
571
575
return reconnect_dfs_server (server );
572
576
}
573
577
#else
574
- int cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
578
+ static int
579
+ _cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session , bool once )
575
580
{
576
- return __cifs_reconnect (server , mark_smb_session );
581
+ return __cifs_reconnect (server , mark_smb_session , once );
577
582
}
578
583
#endif
579
584
585
+ int
586
+ cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
587
+ {
588
+ return _cifs_reconnect (server , mark_smb_session , false);
589
+ }
590
+
591
+ static int
592
+ cifs_reconnect_once (struct TCP_Server_Info * server )
593
+ {
594
+ return _cifs_reconnect (server , true, true);
595
+ }
596
+
580
597
static void
581
598
cifs_echo_request (struct work_struct * work )
582
599
{
@@ -803,26 +820,110 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
803
820
/* Regular SMB response */
804
821
return true;
805
822
case RFC1002_SESSION_KEEP_ALIVE :
823
+ /*
824
+ * RFC 1002 session keep alive can sent by the server only when
825
+ * we established a RFC 1002 session. But Samba servers send
826
+ * RFC 1002 session keep alive also over port 445 on which
827
+ * RFC 1002 session is not established.
828
+ */
806
829
cifs_dbg (FYI , "RFC 1002 session keep alive\n" );
807
830
break ;
808
831
case RFC1002_POSITIVE_SESSION_RESPONSE :
809
- cifs_dbg (FYI , "RFC 1002 positive session response\n" );
832
+ /*
833
+ * RFC 1002 positive session response cannot be returned
834
+ * for SMB request. RFC 1002 session response is handled
835
+ * exclusively in ip_rfc1001_connect() function.
836
+ */
837
+ cifs_server_dbg (VFS , "RFC 1002 positive session response (unexpected)\n" );
838
+ cifs_reconnect (server , true);
810
839
break ;
811
840
case RFC1002_NEGATIVE_SESSION_RESPONSE :
812
841
/*
813
842
* We get this from Windows 98 instead of an error on
814
- * SMB negprot response.
843
+ * SMB negprot response, when we have not established
844
+ * RFC 1002 session (which means ip_rfc1001_connect()
845
+ * was skipped). Note that same still happens with
846
+ * Windows Server 2022 when connecting via port 139.
847
+ * So for this case when mount option -o nonbsessinit
848
+ * was not specified, try to reconnect with establishing
849
+ * RFC 1002 session. If new socket establishment with
850
+ * RFC 1002 session was successful then return to the
851
+ * mid's caller -EAGAIN, so it can retry the request.
815
852
*/
816
- cifs_dbg (FYI , "RFC 1002 negative session response\n" );
817
- /* give server a second to clean up */
818
- msleep (1000 );
819
- /*
820
- * Always try 445 first on reconnect since we get NACK
821
- * on some if we ever connected to port 139 (the NACK
822
- * is since we do not begin with RFC1001 session
823
- * initialize frame).
824
- */
825
- cifs_set_port ((struct sockaddr * )& server -> dstaddr , CIFS_PORT );
853
+ if (!cifs_rdma_enabled (server ) &&
854
+ server -> tcpStatus == CifsInNegotiate &&
855
+ !server -> with_rfc1001 &&
856
+ server -> rfc1001_sessinit != 0 ) {
857
+ int rc , mid_rc ;
858
+ struct mid_q_entry * mid , * nmid ;
859
+ LIST_HEAD (dispose_list );
860
+
861
+ cifs_dbg (FYI , "RFC 1002 negative session response during SMB Negotiate, retrying with NetBIOS session\n" );
862
+
863
+ /*
864
+ * Before reconnect, delete all pending mids for this
865
+ * server, so reconnect would not signal connection
866
+ * aborted error to mid's callbacks. Note that for this
867
+ * server there should be exactly one pending mid
868
+ * corresponding to SMB1/SMB2 Negotiate packet.
869
+ */
870
+ spin_lock (& server -> mid_lock );
871
+ list_for_each_entry_safe (mid , nmid , & server -> pending_mid_q , qhead ) {
872
+ kref_get (& mid -> refcount );
873
+ list_move (& mid -> qhead , & dispose_list );
874
+ mid -> mid_flags |= MID_DELETED ;
875
+ }
876
+ spin_unlock (& server -> mid_lock );
877
+
878
+ /* Now try to reconnect once with NetBIOS session. */
879
+ server -> with_rfc1001 = true;
880
+ rc = cifs_reconnect_once (server );
881
+
882
+ /*
883
+ * If reconnect was successful then indicate -EAGAIN
884
+ * to mid's caller. If reconnect failed with -EAGAIN
885
+ * then mask it as -EHOSTDOWN, so mid's caller would
886
+ * know that it failed.
887
+ */
888
+ if (rc == 0 )
889
+ mid_rc = - EAGAIN ;
890
+ else if (rc == - EAGAIN )
891
+ mid_rc = - EHOSTDOWN ;
892
+ else
893
+ mid_rc = rc ;
894
+
895
+ /*
896
+ * After reconnect (either successful or unsuccessful)
897
+ * deliver reconnect status to mid's caller via mid's
898
+ * callback. Use MID_RC state which indicates that the
899
+ * return code should be read from mid_rc member.
900
+ */
901
+ list_for_each_entry_safe (mid , nmid , & dispose_list , qhead ) {
902
+ list_del_init (& mid -> qhead );
903
+ mid -> mid_rc = mid_rc ;
904
+ mid -> mid_state = MID_RC ;
905
+ mid -> callback (mid );
906
+ release_mid (mid );
907
+ }
908
+
909
+ /*
910
+ * If reconnect failed then wait two seconds. In most
911
+ * cases we were been called from the mount context and
912
+ * delivered failure to mid's callback will stop this
913
+ * receiver task thread and fails the mount process.
914
+ * So wait two seconds to prevent another reconnect
915
+ * in this task thread, which would be useless as the
916
+ * mount context will fail at all.
917
+ */
918
+ if (rc != 0 )
919
+ msleep (2000 );
920
+ } else {
921
+ cifs_server_dbg (VFS , "RFC 1002 negative session response (unexpected)\n" );
922
+ cifs_reconnect (server , true);
923
+ }
924
+ break ;
925
+ case RFC1002_RETARGET_SESSION_RESPONSE :
926
+ cifs_server_dbg (VFS , "RFC 1002 retarget session response (unexpected)\n" );
826
927
cifs_reconnect (server , true);
827
928
break ;
828
929
default :
@@ -1701,6 +1802,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
1701
1802
ctx -> source_rfc1001_name , RFC1001_NAME_LEN_WITH_NULL );
1702
1803
memcpy (tcp_ses -> server_RFC1001_name ,
1703
1804
ctx -> target_rfc1001_name , RFC1001_NAME_LEN_WITH_NULL );
1805
+ tcp_ses -> rfc1001_sessinit = ctx -> rfc1001_sessinit ;
1806
+ tcp_ses -> with_rfc1001 = false;
1704
1807
tcp_ses -> session_estab = false;
1705
1808
tcp_ses -> sequence_number = 0 ;
1706
1809
tcp_ses -> channel_sequence_num = 0 ; /* only tracked for primary channel */
@@ -1731,12 +1834,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
1731
1834
*/
1732
1835
tcp_ses -> tcpStatus = CifsNew ;
1733
1836
++ tcp_ses -> srv_count ;
1837
+ tcp_ses -> echo_interval = ctx -> echo_interval * HZ ;
1734
1838
1735
- if (ctx -> echo_interval >= SMB_ECHO_INTERVAL_MIN &&
1736
- ctx -> echo_interval <= SMB_ECHO_INTERVAL_MAX )
1737
- tcp_ses -> echo_interval = ctx -> echo_interval * HZ ;
1738
- else
1739
- tcp_ses -> echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ ;
1740
1839
if (tcp_ses -> rdma ) {
1741
1840
#ifndef CONFIG_CIFS_SMB_DIRECT
1742
1841
cifs_dbg (VFS , "CONFIG_CIFS_SMB_DIRECT is not enabled\n" );
@@ -3221,6 +3320,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
3221
3320
return - EIO ;
3222
3321
}
3223
3322
3323
+ server -> with_rfc1001 = true;
3224
3324
return 0 ;
3225
3325
}
3226
3326
@@ -3332,7 +3432,16 @@ generic_ip_connect(struct TCP_Server_Info *server)
3332
3432
return rc ;
3333
3433
}
3334
3434
trace_smb3_connect_done (server -> hostname , server -> conn_id , & server -> dstaddr );
3335
- if (sport == htons (RFC1001_PORT ))
3435
+
3436
+ /*
3437
+ * Establish RFC1001 NetBIOS session when it was explicitly requested
3438
+ * by mount option -o nbsessinit, or when connecting to default RFC1001
3439
+ * server port (139) and it was not explicitly disabled by mount option
3440
+ * -o nonbsessinit.
3441
+ */
3442
+ if (server -> with_rfc1001 ||
3443
+ server -> rfc1001_sessinit == 1 ||
3444
+ (server -> rfc1001_sessinit == -1 && sport == htons (RFC1001_PORT )))
3336
3445
rc = ip_rfc1001_connect (server );
3337
3446
3338
3447
return rc ;
@@ -3481,6 +3590,7 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
3481
3590
struct smb3_fs_context * ctx = cifs_sb -> ctx ;
3482
3591
3483
3592
INIT_DELAYED_WORK (& cifs_sb -> prune_tlinks , cifs_prune_tlinks );
3593
+ INIT_LIST_HEAD (& cifs_sb -> tcon_sb_link );
3484
3594
3485
3595
spin_lock_init (& cifs_sb -> tlink_tree_lock );
3486
3596
cifs_sb -> tlink_tree = RB_ROOT ;
@@ -3713,6 +3823,10 @@ static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
3713
3823
tlink_rb_insert (& cifs_sb -> tlink_tree , tlink );
3714
3824
spin_unlock (& cifs_sb -> tlink_tree_lock );
3715
3825
3826
+ spin_lock (& tcon -> sb_list_lock );
3827
+ list_add (& cifs_sb -> tcon_sb_link , & tcon -> cifs_sb_list );
3828
+ spin_unlock (& tcon -> sb_list_lock );
3829
+
3716
3830
queue_delayed_work (cifsiod_wq , & cifs_sb -> prune_tlinks ,
3717
3831
TLINK_IDLE_EXPIRE );
3718
3832
return 0 ;
@@ -4054,9 +4168,19 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
4054
4168
struct rb_root * root = & cifs_sb -> tlink_tree ;
4055
4169
struct rb_node * node ;
4056
4170
struct tcon_link * tlink ;
4171
+ struct cifs_tcon * tcon = NULL ;
4057
4172
4058
4173
cancel_delayed_work_sync (& cifs_sb -> prune_tlinks );
4059
4174
4175
+ if (cifs_sb -> master_tlink ) {
4176
+ tcon = cifs_sb -> master_tlink -> tl_tcon ;
4177
+ if (tcon ) {
4178
+ spin_lock (& tcon -> sb_list_lock );
4179
+ list_del_init (& cifs_sb -> tcon_sb_link );
4180
+ spin_unlock (& tcon -> sb_list_lock );
4181
+ }
4182
+ }
4183
+
4060
4184
spin_lock (& cifs_sb -> tlink_tree_lock );
4061
4185
while ((node = rb_first (root ))) {
4062
4186
tlink = rb_entry (node , struct tcon_link , tl_rbnode );
@@ -4078,11 +4202,13 @@ int
4078
4202
cifs_negotiate_protocol (const unsigned int xid , struct cifs_ses * ses ,
4079
4203
struct TCP_Server_Info * server )
4080
4204
{
4205
+ bool in_retry = false;
4081
4206
int rc = 0 ;
4082
4207
4083
4208
if (!server -> ops -> need_neg || !server -> ops -> negotiate )
4084
4209
return - ENOSYS ;
4085
4210
4211
+ retry :
4086
4212
/* only send once per connect */
4087
4213
spin_lock (& server -> srv_lock );
4088
4214
if (server -> tcpStatus != CifsGood &&
@@ -4102,6 +4228,14 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
4102
4228
spin_unlock (& server -> srv_lock );
4103
4229
4104
4230
rc = server -> ops -> negotiate (xid , ses , server );
4231
+ if (rc == - EAGAIN ) {
4232
+ /* Allow one retry attempt */
4233
+ if (!in_retry ) {
4234
+ in_retry = true;
4235
+ goto retry ;
4236
+ }
4237
+ rc = - EHOSTDOWN ;
4238
+ }
4105
4239
if (rc == 0 ) {
4106
4240
spin_lock (& server -> srv_lock );
4107
4241
if (server -> tcpStatus == CifsInNegotiate )
0 commit comments