smb: client: allow reconnect when sending ioctl
authorPaulo Alcantara <pc@manguebit.com>
Tue, 26 Nov 2024 20:11:47 +0000 (17:11 -0300)
committerSteve French <stfrench@microsoft.com>
Wed, 27 Nov 2024 00:46:27 +0000 (18:46 -0600)
cifs_tree_connect() no longer uses ioctl, so allow sessions to be
reconnected when sending ioctls.

Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifssmb.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c

index 98abf1492c5c7a94b094670c488d45d108e571bf..bd42a419458e324521b90f738dbd2edee46ad00a 100644 (file)
@@ -4317,8 +4317,8 @@ getDFSRetry:
         * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
         * causing an infinite recursion.
         */
-       rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
-                                  (void **)&pSMB, (void **)&pSMBr);
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
+                     (void **)&pSMB, (void **)&pSMBr);
        if (rc)
                return rc;
 
index fa96ebed831082d029e85db6373304a1a867a21e..5349b6519b15a363b9929ff3e6c34c635d9a387b 100644 (file)
@@ -2932,7 +2932,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
        struct fsctl_get_dfs_referral_req *dfs_req = NULL;
        struct get_dfs_referral_rsp *dfs_rsp = NULL;
        u32 dfs_req_size = 0, dfs_rsp_size = 0;
-       int retry_count = 0;
+       int retry_once = 0;
 
        cifs_dbg(FYI, "%s: path: %s\n", __func__, search_name);
 
@@ -2981,15 +2981,19 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
        /* Path to resolve in an UTF-16 null-terminated string */
        memcpy(dfs_req->RequestFileName, utf16_path, utf16_path_len);
 
-       do {
+       for (;;) {
                rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
                                FSCTL_DFS_GET_REFERRALS,
                                (char *)dfs_req, dfs_req_size, CIFSMaxBufSize,
                                (char **)&dfs_rsp, &dfs_rsp_size);
-               if (!is_retryable_error(rc))
+               if (fatal_signal_pending(current)) {
+                       rc = -EINTR;
+                       break;
+               }
+               if (!is_retryable_error(rc) || retry_once++)
                        break;
                usleep_range(512, 2048);
-       } while (++retry_count < 5);
+       }
 
        if (!rc && !dfs_rsp)
                rc = -EIO;
index 2f62178048abb4959cbcfae4529825c55c64e209..010eae9d6c47e24d46ddc588d8f0e17dd6445095 100644 (file)
@@ -228,11 +228,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
        if (tcon == NULL)
                return 0;
 
-       /*
-        * Need to also skip SMB2_IOCTL because it is used for checking nested dfs links in
-        * cifs_tree_connect().
-        */
-       if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)
+       if (smb2_command == SMB2_TREE_CONNECT)
                return 0;
 
        spin_lock(&tcon->tc_lock);
@@ -491,6 +487,7 @@ out:
        case SMB2_CHANGE_NOTIFY:
        case SMB2_QUERY_INFO:
        case SMB2_SET_INFO:
+       case SMB2_IOCTL:
                rc = -EAGAIN;
        }
 failed: