cifs: make sure server interfaces are requested only for SMB3+
authorShyam Prasad N <sprasad@microsoft.com>
Wed, 13 Mar 2024 10:40:41 +0000 (10:40 +0000)
committerSteve French <stfrench@microsoft.com>
Thu, 14 Mar 2024 18:54:27 +0000 (13:54 -0500)
Some code paths for querying server interfaces make a false
assumption that it will only get called for SMB3+. Since this
function now can get called from a generic code paths, the correct
thing to do is to have specific handler for this functionality
per SMB dialect, and call this handler.

This change adds such a handler and implements this handler only
for SMB 3.0 and 3.1.1.

Cc: stable@vger.kernel.org
Cc: Jan Čermák <sairon@sairon.cz>
Reported-by: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifsglob.h
fs/smb/client/connect.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c

index 8be62ed053a25e4c56018641553d10314d0f1563..3da625d532359f58bd87b8e363bbd41227f1d30e 100644 (file)
@@ -355,6 +355,9 @@ struct smb_version_operations {
        /* informational QFS call */
        void (*qfs_tcon)(const unsigned int, struct cifs_tcon *,
                         struct cifs_sb_info *);
+       /* query for server interfaces */
+       int (*query_server_interfaces)(const unsigned int, struct cifs_tcon *,
+                                      bool);
        /* check if a path is accessible or not */
        int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
                                  struct cifs_sb_info *, const char *);
index 86ae578904a269be0fd17c7d110dc1548ef2f203..4cbb79418e5063f0a5ef807785764acaaac19563 100644 (file)
@@ -123,12 +123,16 @@ static void smb2_query_server_interfaces(struct work_struct *work)
        struct cifs_tcon *tcon = container_of(work,
                                        struct cifs_tcon,
                                        query_interfaces.work);
+       struct TCP_Server_Info *server = tcon->ses->server;
 
        /*
         * query server network interfaces, in case they change
         */
+       if (!server->ops->query_server_interfaces)
+               return;
+
        xid = get_xid();
-       rc = SMB3_request_interfaces(xid, tcon, false);
+       rc = server->ops->query_server_interfaces(xid, tcon, false);
        free_xid(xid);
 
        if (rc) {
index 6ee22d0dbc006112c23ce6fea483a4db9cd00cf5..2ed456948f34ca0cd88dbe626429694456a681e2 100644 (file)
@@ -5290,6 +5290,7 @@ struct smb_version_operations smb30_operations = {
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
        .qfs_tcon = smb3_qfs_tcon,
+       .query_server_interfaces = SMB3_request_interfaces,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
@@ -5405,6 +5406,7 @@ struct smb_version_operations smb311_operations = {
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
        .qfs_tcon = smb3_qfs_tcon,
+       .query_server_interfaces = SMB3_request_interfaces,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
index e5e6b14f8cae37bb6ac470c457e34fcf437458a1..3ea688558e6c9b96f454e29197023ec74f274e2a 100644 (file)
@@ -409,14 +409,15 @@ skip_sess_setup:
        spin_unlock(&ses->ses_lock);
 
        if (!rc &&
-           (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
+           (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
+           server->ops->query_server_interfaces) {
                mutex_unlock(&ses->session_mutex);
 
                /*
                 * query server network interfaces, in case they change
                 */
                xid = get_xid();
-               rc = SMB3_request_interfaces(xid, tcon, false);
+               rc = server->ops->query_server_interfaces(xid, tcon, false);
                free_xid(xid);
 
                if (rc == -EOPNOTSUPP && ses->chan_count > 1) {