Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/nfs_mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/sunrpc/addr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/sunrpc/auth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/sunrpc/xprt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/sunrpc/bc_xprt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/sunrpc/rpc_pipe_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include "callback.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include "delegation.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include "nfs4session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "nfs4idmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "pnfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #define NFSDBG_FACILITY		NFSDBG_CLIENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * Get a unique NFSv4.0 callback identifier which will be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * by the V4.0 callback service to lookup the nfs_client struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	if (clp->rpc_ops->version != 4 || minorversion != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	idr_preload(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 		clp->cl_cb_ident = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	idr_preload_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  * Per auth flavor data server rpc clients
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) struct nfs4_ds_server {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	struct list_head	list;   /* ds_clp->cl_ds_clients */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	struct rpc_clnt		*rpc_clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * nfs4_find_ds_client - Common lookup case for DS I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * @ds_clp: pointer to the DS's nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  * @flavor: rpc auth flavour to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) static struct nfs4_ds_server *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) nfs4_find_ds_client(struct nfs_client *ds_clp, rpc_authflavor_t flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	struct nfs4_ds_server *dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	list_for_each_entry_rcu(dss, &ds_clp->cl_ds_clients, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 		if (dss->rpc_clnt->cl_auth->au_flavor != flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	dss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	return dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) static struct nfs4_ds_server *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) nfs4_add_ds_client(struct nfs_client *ds_clp, rpc_authflavor_t flavor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 			   struct nfs4_ds_server *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	struct nfs4_ds_server *dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	spin_lock(&ds_clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	list_for_each_entry(dss, &ds_clp->cl_ds_clients, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		if (dss->rpc_clnt->cl_auth->au_flavor != flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	if (new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		list_add_rcu(&new->list, &ds_clp->cl_ds_clients);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	dss = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	spin_unlock(&ds_clp->cl_lock); /* need some lock to protect list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	return dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) static struct nfs4_ds_server *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) nfs4_alloc_ds_server(struct nfs_client *ds_clp, rpc_authflavor_t flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	struct nfs4_ds_server *dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	dss = kmalloc(sizeof(*dss), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	if (dss == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	dss->rpc_clnt = rpc_clone_client_set_auth(ds_clp->cl_rpcclient, flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	if (IS_ERR(dss->rpc_clnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		int err = PTR_ERR(dss->rpc_clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		kfree (dss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	INIT_LIST_HEAD(&dss->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	return dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) nfs4_free_ds_server(struct nfs4_ds_server *dss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	rpc_release_client(dss->rpc_clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	kfree(dss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * nfs4_find_or_create_ds_client - Find or create a DS rpc client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * @ds_clp: pointer to the DS's nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  * @inode: pointer to the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * Find or create a DS rpc client with th MDS server rpc client auth flavor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  * in the nfs_client cl_ds_clients list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) struct rpc_clnt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) nfs4_find_or_create_ds_client(struct nfs_client *ds_clp, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	struct nfs4_ds_server *dss, *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	rpc_authflavor_t flavor = NFS_SERVER(inode)->client->cl_auth->au_flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	dss = nfs4_find_ds_client(ds_clp, flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	if (dss != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	new = nfs4_alloc_ds_server(ds_clp, flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	if (IS_ERR(new))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		return ERR_CAST(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	dss = nfs4_add_ds_client(ds_clp, flavor, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	if (dss != new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		nfs4_free_ds_server(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	return dss->rpc_clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) EXPORT_SYMBOL_GPL(nfs4_find_or_create_ds_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) nfs4_shutdown_ds_clients(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	struct nfs4_ds_server *dss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	while (!list_empty(&clp->cl_ds_clients)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		dss = list_entry(clp->cl_ds_clients.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 					struct nfs4_ds_server, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		list_del(&dss->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		rpc_shutdown_client(dss->rpc_clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		kfree (dss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) nfs4_cleanup_callback(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	struct nfs4_copy_state *cp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	while (!list_empty(&clp->pending_cb_stateids)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		cp_state = list_entry(clp->pending_cb_stateids.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 					struct nfs4_copy_state, copies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		list_del(&cp_state->copies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		kfree(cp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) void nfs41_shutdown_client(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	if (nfs4_has_session(clp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		nfs4_cleanup_callback(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		nfs4_shutdown_ds_clients(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		nfs4_destroy_session(clp->cl_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		nfs4_destroy_clientid(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #endif	/* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) void nfs40_shutdown_client(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	if (clp->cl_slot_tbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		nfs4_shutdown_slot_table(clp->cl_slot_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		kfree(clp->cl_slot_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	char buf[INET6_ADDRSTRLEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	const char *ip_addr = cl_init->ip_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	struct nfs_client *clp = nfs_alloc_client(cl_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	if (IS_ERR(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	err = nfs_get_cb_ident_idr(clp, cl_init->minorversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	if (cl_init->minorversion > NFS4_MAX_MINOR_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	spin_lock_init(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	INIT_LIST_HEAD(&clp->cl_ds_clients);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	clp->cl_mig_gen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) #if IS_ENABLED(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	init_waitqueue_head(&clp->cl_lock_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	INIT_LIST_HEAD(&clp->pending_cb_stateids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	if (cl_init->minorversion != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		__set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	__set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	 * Set up the connection to the server before we add add to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	 * global list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	err = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_GSS_KRB5I);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	if (err == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		err = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	/* If no clientaddr= option was specified, find a usable cb address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	if (ip_addr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		struct sockaddr_storage cb_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		struct sockaddr *sap = (struct sockaddr *)&cb_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		err = rpc_localaddr(clp->cl_rpcclient, sap, sizeof(cb_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		err = rpc_ntop(sap, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		ip_addr = (const char *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	err = nfs_idmap_new(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		dprintk("%s: failed to create idmapper. Error = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	nfs_free_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274)  * Destroy the NFS4 callback service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) static void nfs4_destroy_callback(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) static void nfs4_shutdown_client(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		nfs4_kill_renewd(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	clp->cl_mvops->shutdown_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	nfs4_destroy_callback(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		nfs_idmap_delete(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	kfree(clp->cl_serverowner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	kfree(clp->cl_serverscope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	kfree(clp->cl_implid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	kfree(clp->cl_owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) void nfs4_free_client(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	nfs4_shutdown_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	nfs_free_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)  * Initialize the NFS4 callback service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) static int nfs4_init_callback(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	struct rpc_xprt *xprt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	if (nfs4_has_session(clp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		error = xprt_setup_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	error = nfs_callback_up(clp->cl_mvops->minor_version, xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		dprintk("%s: failed to start callback. Error = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			__func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	__set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332)  * nfs40_init_client - nfs_client initialization tasks for NFSv4.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333)  * @clp: nfs_client to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335)  * Returns zero on success, or a negative errno if some error occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) int nfs40_init_client(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	struct nfs4_slot_table *tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	tbl = kzalloc(sizeof(*tbl), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	if (tbl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 					"NFSv4.0 transport Slot table");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		kfree(tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	clp->cl_slot_tbl = tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360)  * nfs41_init_client - nfs_client initialization tasks for NFSv4.1+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)  * @clp: nfs_client to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * Returns zero on success, or a negative errno if some error occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) int nfs41_init_client(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	struct nfs4_session *session = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	 * Create the session and mark it expired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	 * When a SEQUENCE operation encounters the expired session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	 * it will do session recovery to initialize it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	session = nfs4_alloc_session(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	clp->cl_session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	 * The create session reply races with the server back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	 * channel probe. Mark the client NFS_CS_SESSION_INITING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	 * so that the client back channel can find the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	 * nfs_client struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) #endif	/* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)  * Initialize the minor version specific parts of an NFS4 client record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) static int nfs4_init_client_minor_version(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	ret = clp->cl_mvops->init_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	return nfs4_init_callback(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406)  * nfs4_init_client - Initialise an NFS4 client record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408)  * @clp: nfs_client to initialise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409)  * @cl_init: pointer to nfs_client_initdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411)  * Returns pointer to an NFS client, or an ERR_PTR value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) struct nfs_client *nfs4_init_client(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 				    const struct nfs_client_initdata *cl_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	struct nfs_client *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	if (clp->cl_cons_state == NFS_CS_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		/* the client is initialised already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	error = nfs4_init_client_minor_version(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	error = nfs4_discover_server_trunking(clp, &old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	if (clp != old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		clp->cl_preserve_clid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		 * Mark the client as having failed initialization so other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		 * processes walking the nfs_client_list in nfs_match_client()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		 * won't try to use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		nfs_mark_client_ready(clp, -EPERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	return old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	nfs_mark_client_ready(clp, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451)  * SETCLIENTID just did a callback update with the callback ident in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452)  * "drop," but server trunking discovery claims "drop" and "keep" are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  * actually the same server.  Swap the callback IDs so that "keep"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  * will continue to use the callback ident the server now knows about,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  * and so that "keep"'s original callback ident is destroyed when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  * "drop" is freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) static void nfs4_swap_callback_idents(struct nfs_client *keep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 				      struct nfs_client *drop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	struct nfs_net *nn = net_generic(keep->cl_net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	unsigned int save = keep->cl_cb_ident;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	if (keep->cl_cb_ident == drop->cl_cb_ident)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	dprintk("%s: keeping callback ident %u and dropping ident %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		__func__, keep->cl_cb_ident, drop->cl_cb_ident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	idr_replace(&nn->cb_ident_idr, keep, drop->cl_cb_ident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	keep->cl_cb_ident = drop->cl_cb_ident;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	idr_replace(&nn->cb_ident_idr, drop, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	drop->cl_cb_ident = save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) static bool nfs4_match_client_owner_id(const struct nfs_client *clp1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		const struct nfs_client *clp2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	if (clp1->cl_owner_id == NULL || clp2->cl_owner_id == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	return strcmp(clp1->cl_owner_id, clp2->cl_owner_id) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) static bool nfs4_same_verifier(nfs4_verifier *v1, nfs4_verifier *v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	return memcmp(v1->data, v2->data, sizeof(v1->data)) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) static int nfs4_match_client(struct nfs_client  *pos,  struct nfs_client *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			     struct nfs_client **prev, struct nfs_net *nn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	if (pos->rpc_ops != new->rpc_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	if (pos->cl_minorversion != new->cl_minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	/* If "pos" isn't marked ready, we can't trust the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	 * remaining fields in "pos", especially the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	 * ID and serverowner fields.  Wait for CREATE_SESSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	 * to finish. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	if (pos->cl_cons_state > NFS_CS_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		refcount_inc(&pos->cl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		nfs_put_client(*prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		*prev = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		status = nfs_wait_client_init_complete(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	if (pos->cl_cons_state != NFS_CS_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	if (pos->cl_clientid != new->cl_clientid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	/* NFSv4.1 always uses the uniform string, however someone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	 * might switch the uniquifier string on us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	if (!nfs4_match_client_owner_id(pos, new))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539)  * nfs40_walk_client_list - Find server that recognizes a client ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  * @new: nfs_client with client ID to test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  * @result: OUT: found nfs_client, or new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  * @cred: credential to use for trunking test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545)  * Returns zero, a negative errno, or a negative NFS4ERR status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546)  * If zero is returned, an nfs_client pointer is planted in "result."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548)  * NB: nfs40_walk_client_list() relies on the new nfs_client being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549)  *     the last nfs_client on the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) int nfs40_walk_client_list(struct nfs_client *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 			   struct nfs_client **result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 			   const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	struct nfs_client *pos, *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	struct nfs4_setclientid_res clid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		.clientid	= new->cl_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		.confirm	= new->cl_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	int status = -NFS4ERR_STALE_CLIENTID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		if (pos == new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		status = nfs4_match_client(pos, new, &prev, nn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		 * We just sent a new SETCLIENTID, which should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		 * caused the server to return a new cl_confirm.  So if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		 * cl_confirm is the same, then this is a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		 * server that just returned the same cl_confirm by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		 * coincidence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		if ((new != pos) && nfs4_same_verifier(&pos->cl_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 						       &new->cl_confirm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		 * But if the cl_confirm's are different, then the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		 * way that a SETCLIENTID_CONFIRM to pos can succeed is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		 * if new and pos point to the same server:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		refcount_inc(&pos->cl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		nfs_put_client(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		prev = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		case -NFS4ERR_STALE_CLIENTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 			nfs4_swap_callback_idents(pos, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			pos->cl_confirm = new->cl_confirm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			nfs_mark_client_ready(pos, NFS_CS_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 			*result = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		case -ERESTARTSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			/* The callback path may have been inadvertently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			 * changed. Schedule recovery!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			nfs4_schedule_path_down_recovery(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	/* No match found. The server lost our clientid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	nfs_put_client(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * Returns true if the server major ids match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 				struct nfs41_server_owner *o2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	if (o1->major_id_sz != o2->major_id_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	return memcmp(o1->major_id, o2->major_id, o1->major_id_sz) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  * Returns true if the server scopes match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) nfs4_check_server_scope(struct nfs41_server_scope *s1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			struct nfs41_server_scope *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	if (s1->server_scope_sz != s2->server_scope_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	return memcmp(s1->server_scope, s2->server_scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 					s1->server_scope_sz) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  * nfs4_detect_session_trunking - Checks for session trunking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657)  * @clp:    original mount nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658)  * @res:    result structure from an exchange_id using the original mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)  *          nfs_client with a new multi_addr transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)  * @xprt:   pointer to the transport to add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  * Called after a successful EXCHANGE_ID on a multi-addr connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663)  * Upon success, add the transport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665)  * Returns zero on success, otherwise -EINVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  * Note: since the exchange_id for the new multi_addr transport uses the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668)  * same nfs_client from the original mount, the cl_owner_id is reused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)  * so eir_clientowner is the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) int nfs4_detect_session_trunking(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 				 struct nfs41_exchange_id_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 				 struct rpc_xprt *xprt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	/* Check eir_clientid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	if (clp->cl_clientid != res->clientid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	/* Check eir_server_owner so_major_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	if (!nfs4_check_serverowner_major_id(clp->cl_serverowner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 					     res->server_owner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	/* Check eir_server_owner so_minor_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	if (clp->cl_serverowner->minor_id != res->server_owner->minor_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	/* Check eir_server_scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	if (!nfs4_check_server_scope(clp->cl_serverscope, res->server_scope))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	pr_info("NFS:  %s: Session trunking succeeded for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		clp->cl_hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		xprt->address_strings[RPC_DISPLAY_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	pr_info("NFS:  %s: Session trunking failed for %s\n", clp->cl_hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		xprt->address_strings[RPC_DISPLAY_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705)  * nfs41_walk_client_list - Find nfs_client that matches a client/server owner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)  * @new: nfs_client with client ID to test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  * @result: OUT: found nfs_client, or new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)  * @cred: credential to use for trunking test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)  * Returns zero, a negative errno, or a negative NFS4ERR status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)  * If zero is returned, an nfs_client pointer is planted in "result."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714)  * NB: nfs41_walk_client_list() relies on the new nfs_client being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715)  *     the last nfs_client on the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) int nfs41_walk_client_list(struct nfs_client *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			   struct nfs_client **result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			   const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	struct nfs_client *pos, *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	int status = -NFS4ERR_STALE_CLIENTID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		if (pos == new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		status = nfs4_match_client(pos, new, &prev, nn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		 * Note that session trunking is just a special subcase of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		 * client id trunking. In either case, we want to fall back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		 * to using the existing nfs_client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		if (!nfs4_check_serverowner_major_id(pos->cl_serverowner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 						     new->cl_serverowner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		refcount_inc(&pos->cl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		*result = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	nfs_put_client(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) #endif	/* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) static void nfs4_destroy_server(struct nfs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	LIST_HEAD(freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	nfs_server_return_all_delegations(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	unset_pnfs_layoutdriver(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	nfs4_purge_state_owners(server, &freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	nfs4_free_state_owners(&freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771)  * NFSv4.0 callback thread helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773)  * Find a client by callback identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) struct nfs_client *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) nfs4_find_client_ident(struct net *net, int cb_ident)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	struct nfs_net *nn = net_generic(net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	clp = idr_find(&nn->cb_ident_idr, cb_ident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		refcount_inc(&clp->cl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) /* Common match routine for v4.0 and v4.1 callback services */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) static bool nfs4_cb_match_client(const struct sockaddr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		struct nfs_client *clp, u32 minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	/* Don't match clients that failed to initialise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	if (!(clp->cl_cons_state == NFS_CS_READY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	    clp->cl_cons_state == NFS_CS_SESSION_INITING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	/* Match the version and minorversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (clp->rpc_ops->version != 4 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	    clp->cl_minorversion != minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	/* Match only the IP address, not the port number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	return rpc_cmp_addr(addr, clap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813)  * NFSv4.1 callback thread helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814)  * For CB_COMPOUND calls, find a client by IP address, protocol version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815)  * minorversion, and sessionID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)  * Returns NULL if no such client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) struct nfs_client *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			   struct nfs4_sessionid *sid, u32 minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	struct nfs_net *nn = net_generic(net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	spin_lock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		if (!nfs4_cb_match_client(addr, clp, minorversion))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		if (!nfs4_has_session(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		/* Match sessionid*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		if (memcmp(clp->cl_session->sess_id.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		    sid->data, NFS4_MAX_SESSIONID_LEN) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		refcount_inc(&clp->cl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	spin_unlock(&nn->nfs_client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) #else /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) struct nfs_client *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			   struct nfs4_sessionid *sid, u32 minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858)  * Set up an NFS4 client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) static int nfs4_set_client(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		const char *hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		const struct sockaddr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		const size_t addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		const char *ip_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		int proto, const struct rpc_timeout *timeparms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		u32 minorversion, unsigned int nconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	struct nfs_client_initdata cl_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		.hostname = hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		.addr = addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		.addrlen = addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		.ip_addr = ip_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		.nfs_mod = &nfs_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		.proto = proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		.minorversion = minorversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		.net = net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		.timeparms = timeparms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		.cred = server->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	if (minorversion == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		__set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	if (proto == XPRT_TRANSPORT_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		cl_init.nconnect = nconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (server->flags & NFS_MOUNT_NORESVPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	if (server->options & NFS_OPTION_MIGRATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		__set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		__set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	server->port = rpc_get_port(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	/* Allocate or find a client reference we can use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	clp = nfs_get_client(&cl_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	if (IS_ERR(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		return PTR_ERR(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (server->nfs_client == clp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		return -ELOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	 * Query for the lease time on clientid setup or renewal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	 * Note that this will be set on nfs_clients that were created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	 * only for the DS role and did not set this bit, but now will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	 * serve a dual role.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	set_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	server->nfs_client = clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920)  * Set up a pNFS Data Server client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)  * Return any existing nfs_client that matches server address,port,version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923)  * and minorversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925)  * For a new nfs_client, use a soft mount (default), a low retrans and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926)  * low timeout interval so that if a connection is lost, we retry through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927)  * the MDS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		const struct sockaddr *ds_addr, int ds_addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		u32 minor_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	struct rpc_timeout ds_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	struct nfs_client *mds_clp = mds_srv->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	struct nfs_client_initdata cl_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		.addr = ds_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		.addrlen = ds_addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		.nodename = mds_clp->cl_rpcclient->cl_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		.ip_addr = mds_clp->cl_ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		.nfs_mod = &nfs_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		.proto = ds_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		.minorversion = minor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		.net = mds_clp->cl_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		.timeparms = &ds_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		.cred = mds_srv->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	char buf[INET6_ADDRSTRLEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	if (rpc_ntop(ds_addr, buf, sizeof(buf)) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	cl_init.hostname = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	if (mds_clp->cl_nconnect > 1 && ds_proto == XPRT_TRANSPORT_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		cl_init.nconnect = mds_clp->cl_nconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	 * Set an authflavor equual to the MDS value. Use the MDS nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	 * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	 * (section 13.1 RFC 5661).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	return nfs_get_client(&cl_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) EXPORT_SYMBOL_GPL(nfs4_set_ds_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)  * Session has been established, and the client marked ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972)  * Limit the mount rsize, wsize and dtsize using negotiated fore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973)  * channel attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) static void nfs4_session_limit_rwsize(struct nfs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	struct nfs4_session *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	u32 server_resp_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	u32 server_rqst_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (!nfs4_has_session(server->nfs_client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	sess = server->nfs_client->cl_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	if (server->dtsize > server_resp_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		server->dtsize = server_resp_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (server->rsize > server_resp_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		server->rsize = server_resp_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (server->wsize > server_rqst_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		server->wsize = server_rqst_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998)  * Limit xattr sizes using the channel attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static void nfs4_session_limit_xasize(struct nfs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) #ifdef CONFIG_NFS_V4_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	struct nfs4_session *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	u32 server_gxa_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	u32 server_sxa_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	u32 server_lxa_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	if (!nfs4_has_session(server->nfs_client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	sess = server->nfs_client->cl_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	server_gxa_sz = sess->fc_attrs.max_resp_sz - nfs42_maxgetxattr_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	server_sxa_sz = sess->fc_attrs.max_rqst_sz - nfs42_maxsetxattr_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	server_lxa_sz = sess->fc_attrs.max_resp_sz -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	    nfs42_maxlistxattrs_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	if (server->gxasize > server_gxa_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		server->gxasize = server_gxa_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (server->sxasize > server_sxa_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		server->sxasize = server_sxa_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (server->lxasize > server_lxa_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		server->lxasize = server_lxa_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int nfs4_server_common_setup(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		struct nfs_fh *mntfh, bool auth_probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	struct nfs_fattr *fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	/* data servers support only a subset of NFSv4.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (is_ds_only_client(server->nfs_client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	if (fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	/* We must ensure the session is initialised first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	error = nfs4_init_session(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	/* Set the basic capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	server->caps |= server->nfs_client->cl_mvops->init_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	if (server->flags & NFS_MOUNT_NORDIRPLUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			server->caps &= ~NFS_CAP_READDIRPLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		server->caps &= ~NFS_CAP_READ_PLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	 * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	 * authentication.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (nfs4_disable_idmapping &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		server->caps |= NFS_CAP_UIDGID_NOMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	/* Probe the root fh to retrieve its FSID and filehandle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	error = nfs4_get_rootfh(server, mntfh, auth_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	dprintk("Server FSID: %llx:%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			(unsigned long long) server->fsid.major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			(unsigned long long) server->fsid.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	nfs_display_fhandle(mntfh, "Pseudo-fs root FH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	error = nfs_probe_fsinfo(server, mntfh, fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	nfs4_session_limit_rwsize(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	nfs4_session_limit_xasize(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		server->namelen = NFS4_MAXNAMLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	nfs_server_insert_lists(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	server->mount_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	server->destroy = nfs4_destroy_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	nfs_free_fattr(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)  * Create a version 4 volume record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	struct rpc_timeout timeparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 				ctx->timeo, ctx->retrans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	/* Initialise the client representation from the mount data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	server->flags = ctx->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	server->options = ctx->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	server->auth_info = ctx->auth_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	/* Use the first specified auth flavor. If this flavor isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	 * allowed by the server, use the SECINFO path to try the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	 * other specified flavors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (ctx->auth_info.flavor_len >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		ctx->selected_flavor = ctx->auth_info.flavors[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		ctx->selected_flavor = RPC_AUTH_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	/* Get a client record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	error = nfs4_set_client(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 				ctx->nfs_server.hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 				&ctx->nfs_server.address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 				ctx->nfs_server.addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				ctx->client_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 				ctx->nfs_server.protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 				&timeparms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 				ctx->minorversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 				ctx->nfs_server.nconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 				fc->net_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	if (ctx->rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		server->rsize = nfs_block_size(ctx->rsize, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (ctx->wsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		server->wsize = nfs_block_size(ctx->wsize, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	server->acregmin = ctx->acregmin * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	server->acregmax = ctx->acregmax * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	server->acdirmin = ctx->acdirmin * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	server->acdirmax = ctx->acdirmax * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	server->port     = ctx->nfs_server.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	return nfs_init_server_rpcclient(server, &timeparms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 					 ctx->selected_flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  * Create a version 4 volume record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)  * - keyed on server and FSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct nfs_server *nfs4_create_server(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	struct nfs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	bool auth_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	server = nfs_alloc_server();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	if (!server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	server->cred = get_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	auth_probe = ctx->auth_info.flavor_len < 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	/* set up the general RPC client */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	error = nfs4_init_server(server, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	error = nfs4_server_common_setup(server, ctx->mntfh, auth_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	nfs_free_server(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)  * Create an NFS4 referral server record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	struct nfs_client *parent_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	struct nfs_server *server, *parent_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	bool auth_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	server = nfs_alloc_server();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	if (!server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	parent_server = NFS_SB(ctx->clone_data.sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	parent_client = parent_server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	server->cred = get_cred(parent_server->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	/* Initialise the client representation from the parent server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	nfs_server_copy_userdata(server, parent_server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	/* Get a client representation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) #if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	rpc_set_port(&ctx->nfs_server.address, NFS_RDMA_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	error = nfs4_set_client(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 				ctx->nfs_server.hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 				&ctx->nfs_server.address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 				ctx->nfs_server.addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 				parent_client->cl_ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 				XPRT_TRANSPORT_RDMA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 				parent_server->client->cl_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 				parent_client->cl_mvops->minor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 				parent_client->cl_nconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 				parent_client->cl_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		goto init_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) #endif	/* IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	rpc_set_port(&ctx->nfs_server.address, NFS_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	error = nfs4_set_client(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 				ctx->nfs_server.hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 				&ctx->nfs_server.address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 				ctx->nfs_server.addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 				parent_client->cl_ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 				XPRT_TRANSPORT_TCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 				parent_server->client->cl_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 				parent_client->cl_mvops->minor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 				parent_client->cl_nconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 				parent_client->cl_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) #if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) init_server:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 					  ctx->selected_flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	auth_probe = parent_server->auth_info.flavor_len < 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	error = nfs4_server_common_setup(server, ctx->mntfh, auth_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	nfs_free_server(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)  * Grab the destination's particulars, including lease expiry time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)  * Returns zero if probe succeeded and retrieved FSID matches the FSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)  * we have cached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static int nfs_probe_destination(struct nfs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	struct inode *inode = d_inode(server->super->s_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	struct nfs_fattr *fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	if (fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	/* Sanity: the probe won't work if the destination server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	 * does not recognize the migrated FH. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	error = nfs_probe_fsinfo(server, NFS_FH(inode), fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	nfs_free_fattr(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)  * nfs4_update_server - Move an nfs_server to a different nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)  * @server: represents FSID to be moved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)  * @hostname: new end-point's hostname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)  * @sap: new end-point's socket address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)  * @salen: size of "sap"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)  * @net: net namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)  * The nfs_server must be quiescent before this function is invoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)  * Either its session is drained (NFSv4.1+), or its transport is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)  * plugged and drained (NFSv4.0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)  * Returns zero on success, or a negative errno value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) int nfs4_update_server(struct nfs_server *server, const char *hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		       struct sockaddr *sap, size_t salen, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	struct rpc_clnt *clnt = server->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	struct xprt_create xargs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		.ident		= clp->cl_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		.net		= net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		.dstaddr	= sap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		.addrlen	= salen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		.servername	= hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	char buf[INET6_ADDRSTRLEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	struct sockaddr_storage address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	struct sockaddr *localaddr = (struct sockaddr *)&address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	error = rpc_switch_client_transport(clnt, &xargs, clnt->cl_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	if (error != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	error = rpc_localaddr(clnt, localaddr, sizeof(address));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	if (error != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		return -EAFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	nfs_server_remove_lists(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	set_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	error = nfs4_set_client(server, hostname, sap, salen, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 				clp->cl_proto, clnt->cl_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 				clp->cl_minorversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 				clp->cl_nconnect, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	if (error != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		nfs_server_insert_lists(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	if (server->nfs_client->cl_hostname == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		if (server->nfs_client->cl_hostname == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	nfs_server_insert_lists(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	return nfs_probe_destination(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }