Commit 37bb04e5 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French
Browse files

CIFS: Simplify connection structure search calls



Use separate functions for comparison between existing structure
and what we are requesting for to make server, session and tcon
search code easier to use on next superblock match call.

Reviewed-by: default avatarJeff Layton <jlayton@samba.org>
Signed-off-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent c02324a6
Loading
Loading
Loading
Loading
+56 −34
Original line number Diff line number Diff line
@@ -1642,24 +1642,33 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
	return true;
}

static struct TCP_Server_Info *
cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
			 struct smb_vol *vol)
{
	struct TCP_Server_Info *server;

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
	if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
			continue;
		return 0;

	if (!match_address(server, addr,
			   (struct sockaddr *)&vol->srcaddr))
			continue;
		return 0;

	if (!match_port(server, addr))
			continue;
		return 0;

	if (!match_security(server, vol))
		return 0;

	return 1;
}

static struct TCP_Server_Info *
cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
{
	struct TCP_Server_Info *server;

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
		if (!match_server(server, addr, vol))
			continue;

		++server->srv_count;
@@ -1853,32 +1862,39 @@ out_err:
	return ERR_PTR(rc);
}

static struct cifsSesInfo *
cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
static int match_session(struct cifsSesInfo *ses, struct smb_vol *vol)
{
	struct cifsSesInfo *ses;

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
		switch (server->secType) {
	switch (ses->server->secType) {
	case Kerberos:
		if (vol->cred_uid != ses->cred_uid)
				continue;
			return 0;
		break;
	default:
		/* anything else takes username/password */
		if (ses->user_name == NULL)
				continue;
			return 0;
		if (strncmp(ses->user_name, vol->username,
			    MAX_USERNAME_SIZE))
				continue;
			return 0;
		if (strlen(vol->username) != 0 &&
		    ses->password != NULL &&
		    strncmp(ses->password,
			    vol->password ? vol->password : "",
			    MAX_PASSWORD_SIZE))
				continue;
			return 0;
	}
	return 1;
}

static struct cifsSesInfo *
cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
{
	struct cifsSesInfo *ses;

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
		if (!match_session(ses, vol))
			continue;
		++ses->ses_count;
		spin_unlock(&cifs_tcp_ses_lock);
		return ses;
@@ -2021,6 +2037,15 @@ get_ses_fail:
	return ERR_PTR(rc);
}

static int match_tcon(struct cifsTconInfo *tcon, const char *unc)
{
	if (tcon->tidStatus == CifsExiting)
		return 0;
	if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
		return 0;
	return 1;
}

static struct cifsTconInfo *
cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
{
@@ -2030,11 +2055,8 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
	spin_lock(&cifs_tcp_ses_lock);
	list_for_each(tmp, &ses->tcon_list) {
		tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
		if (tcon->tidStatus == CifsExiting)
		if (!match_tcon(tcon, unc))
			continue;
		if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
			continue;

		++tcon->tc_count;
		spin_unlock(&cifs_tcp_ses_lock);
		return tcon;