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>
10 #ifdef CONFIG_NFS_V3_ACL
11 static struct rpc_stat nfsacl_rpcstat
= { &nfsacl_program
};
12 static const struct rpc_version
*nfsacl_version
[] = {
13 [3] = &nfsacl_version3
,
16 const struct rpc_program nfsacl_program
= {
18 .number
= NFS_ACL_PROGRAM
,
19 .nrvers
= ARRAY_SIZE(nfsacl_version
),
20 .version
= nfsacl_version
,
21 .stats
= &nfsacl_rpcstat
,
25 * Initialise an NFSv3 ACL client connection
27 static void nfs_init_server_aclclient(struct nfs_server
*server
)
29 if (server
->flags
& NFS_MOUNT_NOACL
)
32 server
->client_acl
= rpc_bind_new_program(server
->client
, &nfsacl_program
, 3);
33 if (IS_ERR(server
->client_acl
))
36 nfs_sysfs_link_rpc_client(server
, server
->client_acl
, NULL
);
38 /* No errors! Assume that Sun nfsacls are supported */
39 server
->caps
|= NFS_CAP_ACLS
;
43 server
->caps
&= ~NFS_CAP_ACLS
;
46 static inline void nfs_init_server_aclclient(struct nfs_server
*server
)
48 server
->flags
&= ~NFS_MOUNT_NOACL
;
49 server
->caps
&= ~NFS_CAP_ACLS
;
53 struct nfs_server
*nfs3_create_server(struct fs_context
*fc
)
55 struct nfs_server
*server
= nfs_create_server(fc
);
57 /* Create a client RPC handle for the NFS v3 ACL management interface */
59 nfs_init_server_aclclient(server
);
63 struct nfs_server
*nfs3_clone_server(struct nfs_server
*source
,
65 struct nfs_fattr
*fattr
,
66 rpc_authflavor_t flavor
)
68 struct nfs_server
*server
= nfs_clone_server(source
, fh
, fattr
, flavor
);
69 if (!IS_ERR(server
) && !IS_ERR(source
->client_acl
))
70 nfs_init_server_aclclient(server
);
75 * Set up a pNFS Data Server client over NFSv3.
77 * Return any existing nfs_client that matches server address,port,version
80 * For a new nfs_client, use a soft mount (default), a low retrans and a
81 * low timeout interval so that if a connection is lost, we retry through
84 struct nfs_client
*nfs3_set_ds_client(struct nfs_server
*mds_srv
,
85 const struct sockaddr_storage
*ds_addr
, int ds_addrlen
,
86 int ds_proto
, unsigned int ds_timeo
, unsigned int ds_retrans
)
88 struct rpc_timeout ds_timeout
;
89 unsigned long connect_timeout
= ds_timeo
* (ds_retrans
+ 1) * HZ
/ 10;
90 struct nfs_client
*mds_clp
= mds_srv
->nfs_client
;
91 struct nfs_client_initdata cl_init
= {
93 .addrlen
= ds_addrlen
,
94 .nodename
= mds_clp
->cl_rpcclient
->cl_nodename
,
95 .ip_addr
= mds_clp
->cl_ipaddr
,
98 .net
= mds_clp
->cl_net
,
99 .timeparms
= &ds_timeout
,
100 .cred
= mds_srv
->cred
,
101 .xprtsec
= mds_clp
->cl_xprtsec
,
102 .connect_timeout
= connect_timeout
,
103 .reconnect_timeout
= connect_timeout
,
105 struct nfs_client
*clp
;
106 char buf
[INET6_ADDRSTRLEN
+ 1];
108 /* fake a hostname because lockd wants it */
109 if (rpc_ntop((struct sockaddr
*)ds_addr
, buf
, sizeof(buf
)) <= 0)
110 return ERR_PTR(-EINVAL
);
111 cl_init
.hostname
= buf
;
114 case XPRT_TRANSPORT_RDMA
:
115 case XPRT_TRANSPORT_TCP
:
116 case XPRT_TRANSPORT_TCP_TLS
:
117 if (mds_clp
->cl_nconnect
> 1)
118 cl_init
.nconnect
= mds_clp
->cl_nconnect
;
121 if (mds_srv
->flags
& NFS_MOUNT_NORESVPORT
)
122 __set_bit(NFS_CS_NORESVPORT
, &cl_init
.init_flags
);
124 __set_bit(NFS_CS_DS
, &cl_init
.init_flags
);
126 /* Use the MDS nfs_client cl_ipaddr. */
127 nfs_init_timeout_values(&ds_timeout
, ds_proto
, ds_timeo
, ds_retrans
);
128 clp
= nfs_get_client(&cl_init
);
132 EXPORT_SYMBOL_GPL(nfs3_set_ds_client
);