Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14d1bbb0 authored by Anna Schumaker's avatar Anna Schumaker Committed by Trond Myklebust
Browse files

NFS: Create a common nfs4_match_client() function



This puts all the common code in a single place for the
walk_client_list() functions.

Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 5b6d3ff6
Loading
Loading
Loading
Loading
+55 −64
Original line number Original line Diff line number Diff line
@@ -469,6 +469,50 @@ static bool nfs4_same_verifier(nfs4_verifier *v1, nfs4_verifier *v2)
	return memcmp(v1->data, v2->data, sizeof(v1->data)) == 0;
	return memcmp(v1->data, v2->data, sizeof(v1->data)) == 0;
}
}


static int nfs4_match_client(struct nfs_client  *pos,  struct nfs_client *new,
			     struct nfs_client **prev, struct nfs_net *nn)
{
	int status;

	if (pos->rpc_ops != new->rpc_ops)
		return 1;

	if (pos->cl_minorversion != new->cl_minorversion)
		return 1;

	/* If "pos" isn't marked ready, we can't trust the
	 * remaining fields in "pos", especially the client
	 * ID and serverowner fields.  Wait for CREATE_SESSION
	 * to finish. */
	if (pos->cl_cons_state > NFS_CS_READY) {
		atomic_inc(&pos->cl_count);
		spin_unlock(&nn->nfs_client_lock);

		nfs_put_client(*prev);
		*prev = pos;

		status = nfs_wait_client_init_complete(pos);
		spin_lock(&nn->nfs_client_lock);

		if (status < 0)
			return status;
	}

	if (pos->cl_cons_state != NFS_CS_READY)
		return 1;

	if (pos->cl_clientid != new->cl_clientid)
		return 1;

	/* NFSv4.1 always uses the uniform string, however someone
	 * might switch the uniquifier string on us.
	 */
	if (!nfs4_match_client_owner_id(pos, new))
		return 1;

	return 0;
}

/**
/**
 * nfs40_walk_client_list - Find server that recognizes a client ID
 * nfs40_walk_client_list - Find server that recognizes a client ID
 *
 *
@@ -497,34 +541,10 @@ int nfs40_walk_client_list(struct nfs_client *new,
	spin_lock(&nn->nfs_client_lock);
	spin_lock(&nn->nfs_client_lock);
	list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
	list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {


		if (pos->rpc_ops != new->rpc_ops)
		status = nfs4_match_client(pos, new, &prev, nn);
			continue;

		if (pos->cl_minorversion != new->cl_minorversion)
			continue;

		/* If "pos" isn't marked ready, we can't trust the
		 * remaining fields in "pos" */
		if (pos->cl_cons_state > NFS_CS_READY) {
			atomic_inc(&pos->cl_count);
			spin_unlock(&nn->nfs_client_lock);

			nfs_put_client(prev);
			prev = pos;

			status = nfs_wait_client_init_complete(pos);
		if (status < 0)
		if (status < 0)
				goto out;
			goto out_unlock;
			status = -NFS4ERR_STALE_CLIENTID;
		if (status != 0)
			spin_lock(&nn->nfs_client_lock);
		}
		if (pos->cl_cons_state != NFS_CS_READY)
			continue;

		if (pos->cl_clientid != new->cl_clientid)
			continue;

		if (!nfs4_match_client_owner_id(pos, new))
			continue;
			continue;
		/*
		/*
		 * We just sent a new SETCLIENTID, which should have
		 * We just sent a new SETCLIENTID, which should have
@@ -567,11 +587,13 @@ int nfs40_walk_client_list(struct nfs_client *new,
			 */
			 */
			nfs4_schedule_path_down_recovery(pos);
			nfs4_schedule_path_down_recovery(pos);
		default:
		default:
			spin_lock(&nn->nfs_client_lock);
			goto out;
			goto out;
		}
		}


		spin_lock(&nn->nfs_client_lock);
		spin_lock(&nn->nfs_client_lock);
	}
	}
out_unlock:
	spin_unlock(&nn->nfs_client_lock);
	spin_unlock(&nn->nfs_client_lock);


	/* No match found. The server lost our clientid */
	/* No match found. The server lost our clientid */
@@ -704,33 +726,10 @@ int nfs41_walk_client_list(struct nfs_client *new,
		if (pos == new)
		if (pos == new)
			goto found;
			goto found;


		if (pos->rpc_ops != new->rpc_ops)
		status = nfs4_match_client(pos, new, &prev, nn);
			continue;

		if (pos->cl_minorversion != new->cl_minorversion)
			continue;

		/* If "pos" isn't marked ready, we can't trust the
		 * remaining fields in "pos", especially the client
		 * ID and serverowner fields.  Wait for CREATE_SESSION
		 * to finish. */
		if (pos->cl_cons_state > NFS_CS_READY) {
			atomic_inc(&pos->cl_count);
			spin_unlock(&nn->nfs_client_lock);

			nfs_put_client(prev);
			prev = pos;

			status = nfs_wait_client_init_complete(pos);
			spin_lock(&nn->nfs_client_lock);
		if (status < 0)
		if (status < 0)
				break;
			goto out;
			status = -NFS4ERR_STALE_CLIENTID;
		if (status != 0)
		}
		if (pos->cl_cons_state != NFS_CS_READY)
			continue;

		if (pos->cl_clientid != new->cl_clientid)
			continue;
			continue;


		/*
		/*
@@ -742,23 +741,15 @@ int nfs41_walk_client_list(struct nfs_client *new,
						     new->cl_serverowner))
						     new->cl_serverowner))
			continue;
			continue;


		/* Unlike NFSv4.0, we know that NFSv4.1 always uses the
		 * uniform string, however someone might switch the
		 * uniquifier string on us.
		 */
		if (!nfs4_match_client_owner_id(pos, new))
			continue;
found:
found:
		atomic_inc(&pos->cl_count);
		atomic_inc(&pos->cl_count);
		*result = pos;
		*result = pos;
		status = 0;
		status = 0;
		dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
			__func__, pos, atomic_read(&pos->cl_count));
		break;
		break;
	}
	}


out:
	spin_unlock(&nn->nfs_client_lock);
	spin_unlock(&nn->nfs_client_lock);
	dprintk("NFS: <-- %s status = %d\n", __func__, status);
	nfs_put_client(prev);
	nfs_put_client(prev);
	return status;
	return status;
}
}