Commit 5006a76c authored by David Howells's avatar David Howells Committed by Trond Myklebust

NFS: Eliminate client_sys in favour of cl_rpcclient

Eliminate nfs_server::client_sys in favour of nfs_client::cl_rpcclient as we
only really need one per server that we're talking to since it doesn't have any
security on it.

The retransmission management variables are also moved to the common struct as
they're required to set up the cl_rpcclient connection.

The NFS2/3 client and client_acl connections are thenceforth derived by cloning
the cl_rpcclient connection and post-applying the authorisation flavour.

The code for setting up the initial common connection has been moved to
client.c as nfs_create_rpc_client().  All the NFS program definition tables are
also moved there as that's where they're now required rather than super.c.
Signed-Off-By: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 8fa5c000
......@@ -50,6 +50,48 @@ static DEFINE_SPINLOCK(nfs_client_lock);
static LIST_HEAD(nfs_client_list);
static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
/*
* RPC cruft for NFS
*/
static struct rpc_version *nfs_version[5] = {
[2] = &nfs_version2,
#ifdef CONFIG_NFS_V3
[3] = &nfs_version3,
#endif
#ifdef CONFIG_NFS_V4
[4] = &nfs_version4,
#endif
};
struct rpc_program nfs_program = {
.name = "nfs",
.number = NFS_PROGRAM,
.nrvers = ARRAY_SIZE(nfs_version),
.version = nfs_version,
.stats = &nfs_rpcstat,
.pipe_dir_name = "/nfs",
};
struct rpc_stat nfs_rpcstat = {
.program = &nfs_program
};
#ifdef CONFIG_NFS_V3_ACL
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
static struct rpc_version * nfsacl_version[] = {
[3] = &nfsacl_version3,
};
struct rpc_program nfsacl_program = {
.name = "nfsacl",
.number = NFS_ACL_PROGRAM,
.nrvers = ARRAY_SIZE(nfsacl_version),
.version = nfsacl_version,
.stats = &nfsacl_rpcstat,
};
#endif /* CONFIG_NFS_V3_ACL */
/*
* Allocate a shared client record
*
......@@ -310,3 +352,80 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state)
clp->cl_cons_state = state;
wake_up_all(&nfs_client_active_wq);
}
/*
* Initialise the timeout values for a connection
*/
static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
unsigned int timeo, unsigned int retrans)
{
to->to_initval = timeo * HZ / 10;
to->to_retries = retrans;
if (!to->to_retries)
to->to_retries = 2;
switch (proto) {
case IPPROTO_TCP:
if (!to->to_initval)
to->to_initval = 60 * HZ;
if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
to->to_initval = NFS_MAX_TCP_TIMEOUT;
to->to_increment = to->to_initval;
to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
to->to_exponential = 0;
break;
case IPPROTO_UDP:
default:
if (!to->to_initval)
to->to_initval = 11 * HZ / 10;
if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
to->to_initval = NFS_MAX_UDP_TIMEOUT;
to->to_maxval = NFS_MAX_UDP_TIMEOUT;
to->to_exponential = 1;
break;
}
}
/*
* Create an RPC client handle
*/
int nfs_create_rpc_client(struct nfs_client *clp, int proto,
unsigned int timeo,
unsigned int retrans,
rpc_authflavor_t flavor)
{
struct rpc_timeout timeparms;
struct rpc_xprt *xprt = NULL;
struct rpc_clnt *clnt = NULL;
if (!IS_ERR(clp->cl_rpcclient))
return 0;
nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
clp->retrans_timeo = timeparms.to_initval;
clp->retrans_count = timeparms.to_retries;
/* create transport and client */
xprt = xprt_create_proto(proto, &clp->cl_addr, &timeparms);
if (IS_ERR(xprt)) {
dprintk("%s: cannot create RPC transport. Error = %ld\n",
__FUNCTION__, PTR_ERR(xprt));
return PTR_ERR(xprt);
}
/* Bind to a reserved port! */
xprt->resvport = 1;
/* Create the client RPC handle */
clnt = rpc_create_client(xprt, clp->cl_hostname, &nfs_program,
clp->rpc_ops->version, RPC_AUTH_UNIX);
if (IS_ERR(clnt)) {
dprintk("%s: cannot create RPC client. Error = %ld\n",
__FUNCTION__, PTR_ERR(clnt));
return PTR_ERR(clnt);
}
clnt->cl_intr = 1;
clnt->cl_softrtry = 1;
clp->cl_rpcclient = clnt;
return 0;
}
......@@ -20,6 +20,8 @@ extern void nfs_put_client(struct nfs_client *);
extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
extern struct nfs_client *nfs_get_client(const char *, const struct sockaddr_in *, int);
extern void nfs_mark_client_ready(struct nfs_client *, int);
extern int nfs_create_rpc_client(struct nfs_client *, int, unsigned int,
unsigned int, rpc_authflavor_t);
/* nfs4namespace.c */
#ifdef CONFIG_NFS_V4
......
......@@ -90,8 +90,8 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
status = do_proc_get_root(server->client, fhandle, info);
if (status && server->client_sys != server->client)
status = do_proc_get_root(server->client_sys, fhandle, info);
if (status && server->nfs_client->cl_rpcclient != server->client)
status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info);
return status;
}
......@@ -785,7 +785,7 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
dprintk("NFS call fsinfo\n");
nfs_fattr_init(info->fattr);
status = rpc_call_sync(server->client_sys, &msg, 0);
status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
dprintk("NFS reply fsinfo: %d\n", status);
return status;
}
......
......@@ -66,14 +66,14 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
dprintk("%s: call getattr\n", __FUNCTION__);
nfs_fattr_init(fattr);
status = rpc_call_sync(server->client_sys, &msg, 0);
status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
if (status)
return status;
dprintk("%s: call statfs\n", __FUNCTION__);
msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS];
msg.rpc_resp = &fsinfo;
status = rpc_call_sync(server->client_sys, &msg, 0);
status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
dprintk("%s: reply statfs: %d\n", __FUNCTION__, status);
if (status)
return status;
......
This diff is collapsed.
......@@ -26,6 +26,8 @@ struct nfs_client {
struct rpc_clnt * cl_rpcclient;
const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
unsigned long retrans_timeo; /* retransmit timeout */
unsigned int retrans_count; /* number of retransmit tries */
#ifdef CONFIG_NFS_V4
u64 cl_clientid; /* constant */
......@@ -73,7 +75,6 @@ struct nfs_client {
struct nfs_server {
struct nfs_client * nfs_client; /* shared client and NFS4 state */
struct rpc_clnt * client; /* RPC client handle */
struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */
struct rpc_clnt * client_acl; /* ACL RPC client handle */
struct nfs_iostats * io_stats; /* I/O statistics */
struct backing_dev_info backing_dev_info;
......@@ -90,8 +91,6 @@ struct nfs_server {
unsigned int acregmax;
unsigned int acdirmin;
unsigned int acdirmax;
unsigned long retrans_timeo; /* retransmit timeout */
unsigned int retrans_count; /* number of retransmit tries */
unsigned int namelen;
char * hostname; /* remote hostname */
struct nfs_fh fh;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment