diff mbox series

[2/2] cifs: make sure server interfaces are requested only for SMB3+

Message ID 20240313104041.188204-2-sprasad@microsoft.com
State New
Headers show
Series [1/2] cifs: reduce warning log level for server not advertising interfaces | expand

Commit Message

Shyam Prasad N March 13, 2024, 10:40 a.m. UTC
From: Shyam Prasad N <sprasad@microsoft.com>

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 <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>
---
 fs/smb/client/cifsglob.h | 3 +++
 fs/smb/client/connect.c  | 6 +++++-
 fs/smb/client/smb2ops.c  | 2 ++
 fs/smb/client/smb2pdu.c  | 5 +++--
 4 files changed, 13 insertions(+), 3 deletions(-)

Comments

Steve French March 14, 2024, 3:14 a.m. UTC | #1
tentatively merged to cifs-2.6.git for-next pending testing and
additional review

On Wed, Mar 13, 2024 at 5:40 AM <nspmangalore@gmail.com> wrote:
>
> From: Shyam Prasad N <sprasad@microsoft.com>
>
> 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 <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>
> ---
>  fs/smb/client/cifsglob.h | 3 +++
>  fs/smb/client/connect.c  | 6 +++++-
>  fs/smb/client/smb2ops.c  | 2 ++
>  fs/smb/client/smb2pdu.c  | 5 +++--
>  4 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
> index 53c75cfb33ab..b29b57ab9807 100644
> --- a/fs/smb/client/cifsglob.h
> +++ b/fs/smb/client/cifsglob.h
> @@ -346,6 +346,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 *);
> diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
> index ac9595504f4b..234160460615 100644
> --- a/fs/smb/client/connect.c
> +++ b/fs/smb/client/connect.c
> @@ -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) {
> diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
> index 4695433fcf39..3b8896987197 100644
> --- a/fs/smb/client/smb2ops.c
> +++ b/fs/smb/client/smb2ops.c
> @@ -5538,6 +5538,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,
> @@ -5653,6 +5654,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,
> diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> index 608ee05491e2..4fa47c59cc04 100644
> --- a/fs/smb/client/smb2pdu.c
> +++ b/fs/smb/client/smb2pdu.c
> @@ -409,14 +409,15 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
>         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) {
> --
> 2.34.1
>
diff mbox series

Patch

diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 53c75cfb33ab..b29b57ab9807 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -346,6 +346,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 *);
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index ac9595504f4b..234160460615 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -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) {
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 4695433fcf39..3b8896987197 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -5538,6 +5538,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,
@@ -5653,6 +5654,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,
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 608ee05491e2..4fa47c59cc04 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -409,14 +409,15 @@  smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
 	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) {