^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) }