File Index
Files and directories
Sign in
FILE

nfs3client.c

File preview with syntax highlighting.

linux-6.19.14/fs/nfs/nfs3client.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2#include <linux/nfs_fs.h>
  3#include <linux/nfs_mount.h>
  4#include <linux/sunrpc/addr.h>
  5#include <net/handshake.h>
  6#include "internal.h"
  7#include "nfs3_fs.h"
  8#include "netns.h"
  9#include "sysfs.h"
 10
 11#ifdef CONFIG_NFS_V3_ACL
 12static struct rpc_stat		nfsacl_rpcstat = { &nfsacl_program };
 13static const struct rpc_version *nfsacl_version[] = {
 14	[3]			= &nfsacl_version3,
 15};
 16
 17const struct rpc_program nfsacl_program = {
 18	.name			= "nfsacl",
 19	.number			= NFS_ACL_PROGRAM,
 20	.nrvers			= ARRAY_SIZE(nfsacl_version),
 21	.version		= nfsacl_version,
 22	.stats			= &nfsacl_rpcstat,
 23};
 24
 25/*
 26 * Initialise an NFSv3 ACL client connection
 27 */
 28static void nfs_init_server_aclclient(struct nfs_server *server)
 29{
 30	if (server->flags & NFS_MOUNT_NOACL)
 31		goto out_noacl;
 32
 33	server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
 34	if (IS_ERR(server->client_acl))
 35		goto out_noacl;
 36
 37	nfs_sysfs_link_rpc_client(server, server->client_acl, NULL);
 38
 39	/* No errors! Assume that Sun nfsacls are supported */
 40	server->caps |= NFS_CAP_ACLS;
 41	return;
 42
 43out_noacl:
 44	server->caps &= ~NFS_CAP_ACLS;
 45}
 46#else
 47static inline void nfs_init_server_aclclient(struct nfs_server *server)
 48{
 49	server->flags &= ~NFS_MOUNT_NOACL;
 50	server->caps &= ~NFS_CAP_ACLS;
 51}
 52#endif
 53
 54struct nfs_server *nfs3_create_server(struct fs_context *fc)
 55{
 56	struct nfs_server *server = nfs_create_server(fc);
 57
 58	/* Create a client RPC handle for the NFS v3 ACL management interface */
 59	if (!IS_ERR(server))
 60		nfs_init_server_aclclient(server);
 61	return server;
 62}
 63
 64struct nfs_server *nfs3_clone_server(struct nfs_server *source,
 65				     struct nfs_fh *fh,
 66				     struct nfs_fattr *fattr,
 67				     rpc_authflavor_t flavor)
 68{
 69	struct nfs_server *server = nfs_clone_server(source, fh, fattr, flavor);
 70	if (!IS_ERR(server) && !IS_ERR(source->client_acl))
 71		nfs_init_server_aclclient(server);
 72	return server;
 73}
 74
 75/*
 76 * Set up a pNFS Data Server client over NFSv3.
 77 *
 78 * Return any existing nfs_client that matches server address,port,version
 79 * and minorversion.
 80 *
 81 * For a new nfs_client, use a soft mount (default), a low retrans and a
 82 * low timeout interval so that if a connection is lost, we retry through
 83 * the MDS.
 84 */
 85struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
 86		const struct sockaddr_storage *ds_addr, int ds_addrlen,
 87		int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans)
 88{
 89	struct rpc_timeout ds_timeout;
 90	unsigned long connect_timeout = ds_timeo * (ds_retrans + 1) * HZ / 10;
 91	struct nfs_client *mds_clp = mds_srv->nfs_client;
 92	struct nfs_client_initdata cl_init = {
 93		.addr = ds_addr,
 94		.addrlen = ds_addrlen,
 95		.nodename = mds_clp->cl_rpcclient->cl_nodename,
 96		.ip_addr = mds_clp->cl_ipaddr,
 97		.nfs_mod = &nfs_v3,
 98		.proto = ds_proto,
 99		.net = mds_clp->cl_net,
100		.timeparms = &ds_timeout,
101		.cred = mds_srv->cred,
102		.xprtsec = {
103			.policy = RPC_XPRTSEC_NONE,
104			.cert_serial = TLS_NO_CERT,
105			.privkey_serial = TLS_NO_PRIVKEY,
106		},
107		.connect_timeout = connect_timeout,
108		.reconnect_timeout = connect_timeout,
109	};
110	struct nfs_client *clp;
111	char buf[INET6_ADDRSTRLEN + 1];
112
113	/* fake a hostname because lockd wants it */
114	if (rpc_ntop((struct sockaddr *)ds_addr, buf, sizeof(buf)) <= 0)
115		return ERR_PTR(-EINVAL);
116	cl_init.hostname = buf;
117
118	switch (ds_proto) {
119	case XPRT_TRANSPORT_TCP_TLS:
120		if (mds_clp->cl_xprtsec.policy != RPC_XPRTSEC_NONE)
121			cl_init.xprtsec = mds_clp->cl_xprtsec;
122		else
123			ds_proto = XPRT_TRANSPORT_TCP;
124		fallthrough;
125	case XPRT_TRANSPORT_RDMA:
126	case XPRT_TRANSPORT_TCP:
127		if (mds_clp->cl_nconnect > 1)
128			cl_init.nconnect = mds_clp->cl_nconnect;
129	}
130
131	if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
132		__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
133	if (test_bit(NFS_CS_NETUNREACH_FATAL, &mds_clp->cl_flags))
134		__set_bit(NFS_CS_NETUNREACH_FATAL, &cl_init.init_flags);
135
136	__set_bit(NFS_CS_DS, &cl_init.init_flags);
137
138	/* Use the MDS nfs_client cl_ipaddr. */
139	nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
140	clp = nfs_get_client(&cl_init);
141
142	return clp;
143}
144EXPORT_SYMBOL_GPL(nfs3_set_ds_client);
~/ Read-only file preview.