@@ -371,7 +371,7 @@ static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num
371371 *
372372 */
373373static int __cifs_reconnect (struct TCP_Server_Info * server ,
374- bool mark_smb_session )
374+ bool mark_smb_session , bool once )
375375{
376376 int rc = 0 ;
377377
@@ -399,6 +399,9 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
399399 if (rc ) {
400400 cifs_server_unlock (server );
401401 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 ;
402405 msleep (3000 );
403406 } else {
404407 atomic_inc (& tcpSesReconnectCount );
@@ -564,19 +567,33 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
564567 return rc ;
565568}
566569
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 )
568572{
569573 if (!server -> leaf_fullpath )
570- return __cifs_reconnect (server , mark_smb_session );
574+ return __cifs_reconnect (server , mark_smb_session , once );
571575 return reconnect_dfs_server (server );
572576}
573577#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 )
575580{
576- return __cifs_reconnect (server , mark_smb_session );
581+ return __cifs_reconnect (server , mark_smb_session , once );
577582}
578583#endif
579584
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+
580597static void
581598cifs_echo_request (struct work_struct * work )
582599{
@@ -803,26 +820,110 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
803820 /* Regular SMB response */
804821 return true;
805822 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+ */
806829 cifs_dbg (FYI , "RFC 1002 session keep alive\n" );
807830 break ;
808831 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);
810839 break ;
811840 case RFC1002_NEGATIVE_SESSION_RESPONSE :
812841 /*
813842 * 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.
815852 */
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" );
826927 cifs_reconnect (server , true);
827928 break ;
828929 default :
@@ -1701,6 +1802,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
17011802 ctx -> source_rfc1001_name , RFC1001_NAME_LEN_WITH_NULL );
17021803 memcpy (tcp_ses -> server_RFC1001_name ,
17031804 ctx -> target_rfc1001_name , RFC1001_NAME_LEN_WITH_NULL );
1805+ tcp_ses -> rfc1001_sessinit = ctx -> rfc1001_sessinit ;
1806+ tcp_ses -> with_rfc1001 = false;
17041807 tcp_ses -> session_estab = false;
17051808 tcp_ses -> sequence_number = 0 ;
17061809 tcp_ses -> channel_sequence_num = 0 ; /* only tracked for primary channel */
@@ -1731,12 +1834,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
17311834 */
17321835 tcp_ses -> tcpStatus = CifsNew ;
17331836 ++ tcp_ses -> srv_count ;
1837+ tcp_ses -> echo_interval = ctx -> echo_interval * HZ ;
17341838
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 ;
17401839 if (tcp_ses -> rdma ) {
17411840#ifndef CONFIG_CIFS_SMB_DIRECT
17421841 cifs_dbg (VFS , "CONFIG_CIFS_SMB_DIRECT is not enabled\n" );
@@ -3221,6 +3320,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
32213320 return - EIO ;
32223321 }
32233322
3323+ server -> with_rfc1001 = true;
32243324 return 0 ;
32253325}
32263326
@@ -3332,7 +3432,16 @@ generic_ip_connect(struct TCP_Server_Info *server)
33323432 return rc ;
33333433 }
33343434 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 )))
33363445 rc = ip_rfc1001_connect (server );
33373446
33383447 return rc ;
@@ -3481,6 +3590,7 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
34813590 struct smb3_fs_context * ctx = cifs_sb -> ctx ;
34823591
34833592 INIT_DELAYED_WORK (& cifs_sb -> prune_tlinks , cifs_prune_tlinks );
3593+ INIT_LIST_HEAD (& cifs_sb -> tcon_sb_link );
34843594
34853595 spin_lock_init (& cifs_sb -> tlink_tree_lock );
34863596 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,
37133823 tlink_rb_insert (& cifs_sb -> tlink_tree , tlink );
37143824 spin_unlock (& cifs_sb -> tlink_tree_lock );
37153825
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+
37163830 queue_delayed_work (cifsiod_wq , & cifs_sb -> prune_tlinks ,
37173831 TLINK_IDLE_EXPIRE );
37183832 return 0 ;
@@ -4054,9 +4168,19 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
40544168 struct rb_root * root = & cifs_sb -> tlink_tree ;
40554169 struct rb_node * node ;
40564170 struct tcon_link * tlink ;
4171+ struct cifs_tcon * tcon = NULL ;
40574172
40584173 cancel_delayed_work_sync (& cifs_sb -> prune_tlinks );
40594174
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+
40604184 spin_lock (& cifs_sb -> tlink_tree_lock );
40614185 while ((node = rb_first (root ))) {
40624186 tlink = rb_entry (node , struct tcon_link , tl_rbnode );
@@ -4078,11 +4202,13 @@ int
40784202cifs_negotiate_protocol (const unsigned int xid , struct cifs_ses * ses ,
40794203 struct TCP_Server_Info * server )
40804204{
4205+ bool in_retry = false;
40814206 int rc = 0 ;
40824207
40834208 if (!server -> ops -> need_neg || !server -> ops -> negotiate )
40844209 return - ENOSYS ;
40854210
4211+ retry :
40864212 /* only send once per connect */
40874213 spin_lock (& server -> srv_lock );
40884214 if (server -> tcpStatus != CifsGood &&
@@ -4102,6 +4228,14 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
41024228 spin_unlock (& server -> srv_lock );
41034229
41044230 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+ }
41054239 if (rc == 0 ) {
41064240 spin_lock (& server -> srv_lock );
41074241 if (server -> tcpStatus == CifsInNegotiate )
0 commit comments