Commit a7ea35b6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'v6.14-rc7-smb3-client-fix' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fix from Steve French:
 "smb3 client reconnect fix"

* tag 'v6.14-rc7-smb3-client-fix' of git://git.samba.org/sfrench/cifs-2.6:
  smb: client: don't retry IO on failed negprotos with soft mounts
parents a1cffe8c 7643dbd9
Loading
Loading
Loading
Loading
+27 −19
Original line number Diff line number Diff line
@@ -114,19 +114,23 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)

	mutex_lock(&ses->session_mutex);
	/*
	 * Recheck after acquire mutex. If another thread is negotiating
	 * and the server never sends an answer the socket will be closed
	 * and tcpStatus set to reconnect.
	 * Handle the case where a concurrent thread failed to negotiate or
	 * killed a channel.
	 */
	spin_lock(&server->srv_lock);
	if (server->tcpStatus == CifsNeedReconnect) {
	switch (server->tcpStatus) {
	case CifsExiting:
		spin_unlock(&server->srv_lock);
		mutex_unlock(&ses->session_mutex);

		if (tcon->retry)
		return -EHOSTDOWN;
	case CifsNeedReconnect:
		spin_unlock(&server->srv_lock);
		mutex_unlock(&ses->session_mutex);
		if (!tcon->retry)
			return -EHOSTDOWN;
		goto again;
		rc = -EHOSTDOWN;
		goto out;
	default:
		break;
	}
	spin_unlock(&server->srv_lock);

@@ -152,7 +156,12 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
	spin_unlock(&ses->ses_lock);

	rc = cifs_negotiate_protocol(0, ses, server);
	if (!rc) {
	if (rc) {
		mutex_unlock(&ses->session_mutex);
		if (!tcon->retry)
			return -EHOSTDOWN;
		goto again;
	}
	rc = cifs_setup_session(0, ses, server, ses->local_nls);
	if ((rc == -EACCES) || (rc == -EHOSTDOWN) || (rc == -EKEYREVOKED)) {
		/*
@@ -162,7 +171,6 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
		if (ses->password2)
			swap(ses->password2, ses->password);
	}
	}

	/* do we need to reconnect tcon? */
	if (rc || !tcon->need_reconnect) {
+42 −54
Original line number Diff line number Diff line
@@ -300,32 +300,23 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,

	mutex_lock(&ses->session_mutex);
	/*
	 * if this is called by delayed work, and the channel has been disabled
	 * in parallel, the delayed work can continue to execute in parallel
	 * there's a chance that this channel may not exist anymore
	 * Handle the case where a concurrent thread failed to negotiate or
	 * killed a channel.
	 */
	spin_lock(&server->srv_lock);
	if (server->tcpStatus == CifsExiting) {
	switch (server->tcpStatus) {
	case CifsExiting:
		spin_unlock(&server->srv_lock);
		mutex_unlock(&ses->session_mutex);
		rc = -EHOSTDOWN;
		goto out;
	}

	/*
	 * Recheck after acquire mutex. If another thread is negotiating
	 * and the server never sends an answer the socket will be closed
	 * and tcpStatus set to reconnect.
	 */
	if (server->tcpStatus == CifsNeedReconnect) {
		return -EHOSTDOWN;
	case CifsNeedReconnect:
		spin_unlock(&server->srv_lock);
		mutex_unlock(&ses->session_mutex);

		if (tcon->retry)
		if (!tcon->retry)
			return -EHOSTDOWN;
		goto again;

		rc = -EHOSTDOWN;
		goto out;
	default:
		break;
	}
	spin_unlock(&server->srv_lock);

@@ -350,7 +341,12 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
	spin_unlock(&ses->ses_lock);

	rc = cifs_negotiate_protocol(0, ses, server);
	if (!rc) {
	if (rc) {
		mutex_unlock(&ses->session_mutex);
		if (!tcon->retry)
			return -EHOSTDOWN;
		goto again;
	}
	/*
	 * if server stopped supporting multichannel
	 * and the first channel reconnected, disable all the others.
@@ -376,17 +372,10 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
		if (ses->password2)
			swap(ses->password2, ses->password);
	}

		if ((rc == -EACCES) && !tcon->retry) {
			mutex_unlock(&ses->session_mutex);
			rc = -EHOSTDOWN;
			goto failed;
		} else if (rc) {
			mutex_unlock(&ses->session_mutex);
			goto out;
		}
	} else {
	if (rc) {
		mutex_unlock(&ses->session_mutex);
		if (rc == -EACCES && !tcon->retry)
			return -EHOSTDOWN;
		goto out;
	}

@@ -490,7 +479,6 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
	case SMB2_IOCTL:
		rc = -EAGAIN;
	}
failed:
	return rc;
}