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