Commit 4ca9f31a authored by Olga Kornievskaia's avatar Olga Kornievskaia Committed by Anna Schumaker
Browse files

NFSv4.1 test and add 4.1 trunking transport



For each location returned in FS_LOCATION query, establish a
transport to the server, send EXCHANGE_ID and test for trunking,
if successful, add the transport to the exiting client.

Signed-off-by: default avatarOlga Kornievskaia <kolga@netapp.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent b8a09619
Loading
Loading
Loading
Loading
+55 −1
Original line number Diff line number Diff line
@@ -3935,6 +3935,56 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
	return err;
}

static void test_fs_location_for_trunking(struct nfs4_fs_location *location,
					  struct nfs_client *clp,
					  struct nfs_server *server)
{
	int i;

	for (i = 0; i < location->nservers; i++) {
		struct nfs4_string *srv_loc = &location->servers[i];
		struct sockaddr addr;
		size_t addrlen;
		struct xprt_create xprt_args = {
			.ident = 0,
			.net = clp->cl_net,
		};
		struct nfs4_add_xprt_data xprtdata = {
			.clp = clp,
		};
		struct rpc_add_xprt_test rpcdata = {
			.add_xprt_test = clp->cl_mvops->session_trunk,
			.data = &xprtdata,
		};
		char *servername = NULL;

		if (!srv_loc->len)
			continue;

		addrlen = nfs_parse_server_name(srv_loc->data, srv_loc->len,
						&addr, sizeof(addr),
						clp->cl_net, server->port);
		if (!addrlen)
			return;
		xprt_args.dstaddr = &addr;
		xprt_args.addrlen = addrlen;
		servername = kmalloc(srv_loc->len + 1, GFP_KERNEL);
		if (!servername)
			return;
		memcpy(servername, srv_loc->data, srv_loc->len);
		servername[srv_loc->len] = '\0';
		xprt_args.servername = servername;

		xprtdata.cred = nfs4_get_clid_cred(clp);
		rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
				  rpc_clnt_setup_test_and_add_xprt,
				  &rpcdata);
		if (xprtdata.cred)
			put_cred(xprtdata.cred);
		kfree(servername);
	}
}

static int _nfs4_discover_trunking(struct nfs_server *server,
				   struct nfs_fh *fhandle)
{
@@ -3944,7 +3994,7 @@ static int _nfs4_discover_trunking(struct nfs_server *server,
	struct nfs_client *clp = server->nfs_client;
	const struct nfs4_state_maintenance_ops *ops =
		clp->cl_mvops->state_renewal_ops;
	int status = -ENOMEM;
	int status = -ENOMEM, i;

	cred = ops->get_state_renewal_cred(clp);
	if (cred == NULL) {
@@ -3962,6 +4012,10 @@ static int _nfs4_discover_trunking(struct nfs_server *server,
					 cred);
	if (status)
		goto out;

	for (i = 0; i < locations->nlocations; i++)
		test_fs_location_for_trunking(&locations->locations[i], clp,
					      server);
out:
	if (page)
		__free_page(page);