2012-07-31 00:05:19 +04:00
# include <linux/nfs_fs.h>
# include <linux/nfs_mount.h>
2014-07-08 02:21:10 +04:00
# include <linux/sunrpc/addr.h>
2012-07-31 00:05:19 +04:00
# include "internal.h"
2014-09-26 00:28:53 +04:00
# include "nfs3_fs.h"
2012-07-31 00:05:19 +04:00
# ifdef CONFIG_NFS_V3_ACL
static struct rpc_stat nfsacl_rpcstat = { & nfsacl_program } ;
static const struct rpc_version * nfsacl_version [ ] = {
[ 3 ] = & nfsacl_version3 ,
} ;
const struct rpc_program nfsacl_program = {
. name = " nfsacl " ,
. number = NFS_ACL_PROGRAM ,
. nrvers = ARRAY_SIZE ( nfsacl_version ) ,
. version = nfsacl_version ,
. stats = & nfsacl_rpcstat ,
} ;
/*
* Initialise an NFSv3 ACL client connection
*/
static void nfs_init_server_aclclient ( struct nfs_server * server )
{
if ( server - > flags & NFS_MOUNT_NOACL )
goto out_noacl ;
server - > client_acl = rpc_bind_new_program ( server - > client , & nfsacl_program , 3 ) ;
if ( IS_ERR ( server - > client_acl ) )
goto out_noacl ;
/* No errors! Assume that Sun nfsacls are supported */
server - > caps | = NFS_CAP_ACLS ;
return ;
out_noacl :
server - > caps & = ~ NFS_CAP_ACLS ;
}
# else
static inline void nfs_init_server_aclclient ( struct nfs_server * server )
{
server - > flags & = ~ NFS_MOUNT_NOACL ;
server - > caps & = ~ NFS_CAP_ACLS ;
}
# endif
struct nfs_server * nfs3_create_server ( struct nfs_mount_info * mount_info ,
struct nfs_subversion * nfs_mod )
{
struct nfs_server * server = nfs_create_server ( mount_info , nfs_mod ) ;
/* Create a client RPC handle for the NFS v3 ACL management interface */
if ( ! IS_ERR ( server ) )
nfs_init_server_aclclient ( server ) ;
return server ;
}
struct nfs_server * nfs3_clone_server ( struct nfs_server * source ,
struct nfs_fh * fh ,
struct nfs_fattr * fattr ,
rpc_authflavor_t flavor )
{
struct nfs_server * server = nfs_clone_server ( source , fh , fattr , flavor ) ;
if ( ! IS_ERR ( server ) & & ! IS_ERR ( source - > client_acl ) )
nfs_init_server_aclclient ( server ) ;
return server ;
}
2014-05-30 14:15:57 +04:00
/*
* Set up a pNFS Data Server client over NFSv3 .
*
* Return any existing nfs_client that matches server address , port , version
* and minorversion .
*
* For a new nfs_client , use a soft mount ( default ) , a low retrans and a
* low timeout interval so that if a connection is lost , we retry through
* the MDS .
*/
2016-06-13 21:52:00 +03:00
struct nfs_client * nfs3_set_ds_client ( struct nfs_server * mds_srv ,
2014-05-30 14:15:57 +04:00
const struct sockaddr * ds_addr , int ds_addrlen ,
2016-11-17 23:15:55 +03:00
int ds_proto , unsigned int ds_timeo , unsigned int ds_retrans )
2014-05-30 14:15:57 +04:00
{
2016-06-22 21:13:12 +03:00
struct rpc_timeout ds_timeout ;
2016-06-13 21:52:00 +03:00
struct nfs_client * mds_clp = mds_srv - > nfs_client ;
2014-05-30 14:15:57 +04:00
struct nfs_client_initdata cl_init = {
. addr = ds_addr ,
. addrlen = ds_addrlen ,
2016-06-22 21:13:12 +03:00
. nodename = mds_clp - > cl_rpcclient - > cl_nodename ,
. ip_addr = mds_clp - > cl_ipaddr ,
2014-05-30 14:15:57 +04:00
. nfs_mod = & nfs_v3 ,
. proto = ds_proto ,
. net = mds_clp - > cl_net ,
2016-06-22 21:13:12 +03:00
. timeparms = & ds_timeout ,
2019-04-25 00:46:43 +03:00
. cred = mds_srv - > cred ,
2014-05-30 14:15:57 +04:00
} ;
struct nfs_client * clp ;
2014-07-08 02:21:10 +04:00
char buf [ INET6_ADDRSTRLEN + 1 ] ;
/* fake a hostname because lockd wants it */
if ( rpc_ntop ( ds_addr , buf , sizeof ( buf ) ) < = 0 )
return ERR_PTR ( - EINVAL ) ;
cl_init . hostname = buf ;
2014-05-30 14:15:57 +04:00
2016-06-13 21:52:00 +03:00
if ( mds_srv - > flags & NFS_MOUNT_NORESVPORT )
set_bit ( NFS_CS_NORESVPORT , & cl_init . init_flags ) ;
2014-05-30 14:15:57 +04:00
/* Use the MDS nfs_client cl_ipaddr. */
nfs_init_timeout_values ( & ds_timeout , ds_proto , ds_timeo , ds_retrans ) ;
2016-11-17 23:15:55 +03:00
clp = nfs_get_client ( & cl_init ) ;
2014-05-30 14:15:57 +04:00
return clp ;
}
EXPORT_SYMBOL_GPL ( nfs3_set_ds_client ) ;