Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/nfs_fs.h>
0003 #include <linux/nfs_mount.h>
0004 #include <linux/sunrpc/addr.h>
0005 #include "internal.h"
0006 #include "nfs3_fs.h"
0007 
0008 #ifdef CONFIG_NFS_V3_ACL
0009 static struct rpc_stat      nfsacl_rpcstat = { &nfsacl_program };
0010 static const struct rpc_version *nfsacl_version[] = {
0011     [3]         = &nfsacl_version3,
0012 };
0013 
0014 const struct rpc_program nfsacl_program = {
0015     .name           = "nfsacl",
0016     .number         = NFS_ACL_PROGRAM,
0017     .nrvers         = ARRAY_SIZE(nfsacl_version),
0018     .version        = nfsacl_version,
0019     .stats          = &nfsacl_rpcstat,
0020 };
0021 
0022 /*
0023  * Initialise an NFSv3 ACL client connection
0024  */
0025 static void nfs_init_server_aclclient(struct nfs_server *server)
0026 {
0027     if (server->flags & NFS_MOUNT_NOACL)
0028         goto out_noacl;
0029 
0030     server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
0031     if (IS_ERR(server->client_acl))
0032         goto out_noacl;
0033 
0034     /* No errors! Assume that Sun nfsacls are supported */
0035     server->caps |= NFS_CAP_ACLS;
0036     return;
0037 
0038 out_noacl:
0039     server->caps &= ~NFS_CAP_ACLS;
0040 }
0041 #else
0042 static inline void nfs_init_server_aclclient(struct nfs_server *server)
0043 {
0044     server->flags &= ~NFS_MOUNT_NOACL;
0045     server->caps &= ~NFS_CAP_ACLS;
0046 }
0047 #endif
0048 
0049 struct nfs_server *nfs3_create_server(struct fs_context *fc)
0050 {
0051     struct nfs_server *server = nfs_create_server(fc);
0052 
0053     /* Create a client RPC handle for the NFS v3 ACL management interface */
0054     if (!IS_ERR(server))
0055         nfs_init_server_aclclient(server);
0056     return server;
0057 }
0058 
0059 struct nfs_server *nfs3_clone_server(struct nfs_server *source,
0060                      struct nfs_fh *fh,
0061                      struct nfs_fattr *fattr,
0062                      rpc_authflavor_t flavor)
0063 {
0064     struct nfs_server *server = nfs_clone_server(source, fh, fattr, flavor);
0065     if (!IS_ERR(server) && !IS_ERR(source->client_acl))
0066         nfs_init_server_aclclient(server);
0067     return server;
0068 }
0069 
0070 /*
0071  * Set up a pNFS Data Server client over NFSv3.
0072  *
0073  * Return any existing nfs_client that matches server address,port,version
0074  * and minorversion.
0075  *
0076  * For a new nfs_client, use a soft mount (default), a low retrans and a
0077  * low timeout interval so that if a connection is lost, we retry through
0078  * the MDS.
0079  */
0080 struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
0081         const struct sockaddr *ds_addr, int ds_addrlen,
0082         int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans)
0083 {
0084     struct rpc_timeout ds_timeout;
0085     struct nfs_client *mds_clp = mds_srv->nfs_client;
0086     struct nfs_client_initdata cl_init = {
0087         .addr = ds_addr,
0088         .addrlen = ds_addrlen,
0089         .nodename = mds_clp->cl_rpcclient->cl_nodename,
0090         .ip_addr = mds_clp->cl_ipaddr,
0091         .nfs_mod = &nfs_v3,
0092         .proto = ds_proto,
0093         .net = mds_clp->cl_net,
0094         .timeparms = &ds_timeout,
0095         .cred = mds_srv->cred,
0096     };
0097     struct nfs_client *clp;
0098     char buf[INET6_ADDRSTRLEN + 1];
0099 
0100     /* fake a hostname because lockd wants it */
0101     if (rpc_ntop(ds_addr, buf, sizeof(buf)) <= 0)
0102         return ERR_PTR(-EINVAL);
0103     cl_init.hostname = buf;
0104 
0105     if (mds_clp->cl_nconnect > 1 && ds_proto == XPRT_TRANSPORT_TCP)
0106         cl_init.nconnect = mds_clp->cl_nconnect;
0107 
0108     if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
0109         __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
0110 
0111     __set_bit(NFS_CS_DS, &cl_init.init_flags);
0112 
0113     /* Use the MDS nfs_client cl_ipaddr. */
0114     nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
0115     clp = nfs_get_client(&cl_init);
0116 
0117     return clp;
0118 }
0119 EXPORT_SYMBOL_GPL(nfs3_set_ds_client);