Commit 13c0a747 authored by Shyam Prasad N's avatar Shyam Prasad N Committed by Steve French
Browse files

cifs: make sure server interfaces are requested only for SMB3+



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: default avatarPaulo Alcantara <pc@manguebit.com>
Signed-off-by: default avatarShyam Prasad N <sprasad@microsoft.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent dc528770
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 *);
+5 −1
Original line number Diff line number Diff line
@@ -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) {
+2 −0
Original line number Diff line number Diff line
@@ -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,
+3 −2
Original line number Diff line number Diff line
@@ -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) {