[pnfs] [PATCH 4/6] 2.6-latest-pnfs-client-device-create
andros at umich.edu
andros at umich.edu
Fri Oct 19 14:13:20 EDT 2007
From: Andy Adamson <andros at umich.edu>
Initialize data server struct nfs_client and use it to create a session to the
data server in decode GETDEVICELIST.
Notes:
- Need to extract the session management fields from struct nfs_client
into a new structure to use for all session management - use this strucure
for nfs4_proc_exchange_id() etc instead of struct nfs_client.
- Need to wait to setup a data server session until needed.
Signed-off by: Andy Adamson<andros at umich.edu>
---
fs/nfs/client.c | 3 +-
fs/nfs/nfs4filelayoutdev.c | 100 ++++++++++++++++++++++++++++++--------------
fs/nfs/nfs4state.c | 1 +
3 files changed, 72 insertions(+), 32 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 79374ca..1688f1d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -924,7 +924,7 @@ error:
/*
* Set up an NFS4 client
*/
-static int nfs4_set_client(struct nfs_server *server,
+int nfs4_set_client(struct nfs_server *server,
const char *hostname, const struct sockaddr_in *addr,
const char *ip_addr,
rpc_authflavor_t authflavour,
@@ -956,6 +956,7 @@ error:
return error;
}
+EXPORT_SYMBOL(nfs4_set_client);
/*
* Create a version 4 volume record
*/
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 569361f..96f87d7 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -47,13 +47,19 @@
#include <asm/div64.h>
#ifdef CONFIG_PNFS
-
+#include <linux/utsname.h>
#include <linux/pnfs_xdr.h>
#include "nfs4filelayout.h"
#include "nfs4_fs.h"
#define NFSDBG_FACILITY NFSDBG_FILELAYOUT
+extern int nfs4_set_client(struct nfs_server *server,
+ const char *hostname, const struct sockaddr_in *addr,
+ const char *ip_addr,
+ rpc_authflavor_t authflavour,
+ int proto, int timeo, int retrans);
+
extern struct pnfs_client_operations * pnfs_callback_ops;
struct rpc_clnt*
@@ -168,45 +174,65 @@ _data_server_add(struct nfs4_pnfs_dev_hlist *hlist, struct nfs4_pnfs_ds *ds)
/* Create an rpc to the data server defined in 'dev_list' */
static int
-device_create(struct rpc_clnt *mds_rpc, struct nfs4_pnfs_dev *dev)
+nfs4_pnfs_ds_create(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
{
- //struct rpc_clnt *clnt;
- //struct rpc_xprt *xprt;
- struct nfs4_pnfs_ds *ds;
+ struct nfs_server tmp = {
+ .nfs_client = NULL,
+ };
struct sockaddr_in sin;
+ struct rpc_clnt *mds_clnt = mds_srv->client;
+ char ip_addr[16];
int err = 0;
- /* just use the first ds in ds list...*/
- ds = dev->ds_list[0];
-
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ds->ds_ip_addr;
sin.sin_port = ds->ds_port;
- dprintk("device_create: ip=%x, port=%hu, rpcclient %p\n",
- ntohl(ds->ds_ip_addr), ntohs(ds->ds_port), mds_rpc);
-
- /*
- * XXX Need to implement.
- * XXXX Need to port. See fs/nfs/client.c:nfs_create_rpc_client()
- xprt = xprt_create_proto(IPPROTO_TCP, &sin,
- &mds_rpc->cl_xprt->timeout);
- if (IS_ERR(xprt)) {
- err = PTR_ERR(xprt);
- goto out;
- }
+ /* Set timeout to the mds rpc clnt value.
+ * XXX - find the correct authflavor....
+ *
+ * Initialize client ipaddr (used for sessionid) with hostname
+ * Use hostname since it might be more unique than ipaddr (which
+ * could be set to the loopback 127.0.0/1.1
+ *
+ * XXX: Should sessions continue to use the cl_ipaddr field?
+ */
+ memcpy(ip_addr, utsname()->nodename, sizeof(ip_addr));
+
+ /* XXX need a non-nfs_client struct interface to set up
+ * data server sessions
+ *
+ * tmp: nfs4_set_client sets the nfs_server->nfs_client.
+ *
+ * We specify a retrans and timeout interval equual to MDS. ??
+ */
+ err = nfs4_set_client(&tmp,
+ mds_srv->nfs_client->cl_hostname,
+ &sin,
+ ip_addr,
+ RPC_AUTH_UNIX,
+ IPPROTO_TCP,
+ mds_clnt->cl_xprt->timeout.to_initval,
+ mds_clnt->cl_xprt->timeout.to_retries);
+ if (err < 0)
+ goto out;
- clp->cl_rpcclient = create_nfs_rpcclient(xprt, "nfs4_pnfs_dserver", mds_rpc->cl_vers, mds_rpc->cl_auth->au_flavor, &err);
- if (clp->cl_rpcclient == NULL) {
- printk("%s: Can't create nfs rpc client!\n",
- __FUNCTION__);
- goto out;
- }
- }
- dev->clp = clp;
+ dprintk("%s: cl_ipaddr %s\n", __func__, tmp.nfs_client->cl_ipaddr);
+
+ dprintk("%s: ip=%x, port=%hu, rpcclient %p\n", __func__,
+ ntohl(ds->ds_ip_addr), ntohs(ds->ds_port),
+ tmp.nfs_client->cl_rpcclient);
+
+ if (tmp.nfs_client->cl_ds_session == NULL) {
+ /* Set exchange id and create session flags */
+ tmp.nfs_client->cl_exchange_flags = EXCHGID4_FLAG_USE_PNFS_DS;
+
+ nfs4_schedule_state_recovery(tmp.nfs_client);
+ }
+ ds->ds_clp = tmp.nfs_client;
out:
-*/
+ dprintk("%s Returns %d\n", __func__, err);
return err;
}
@@ -375,9 +401,10 @@ nfs4_pnfs_ds_add(struct filelayout_mount_type *mt, struct nfs4_pnfs_ds **dsp, u3
static struct nfs4_pnfs_ds *
decode_and_add_ds(uint32_t **pp, struct filelayout_mount_type *mt)
{
+ struct nfs_server *mds_srv = NFS_SB(mt->fl_sb);
struct nfs4_pnfs_ds *ds = NULL;
char r_addr[29]; /* max size of ip/port string */
- int len;
+ int len, err;
u32 ip_addr, port;
int tmp[6];
uint32_t *p = *pp;
@@ -390,7 +417,7 @@ decode_and_add_ds(uint32_t **pp, struct filelayout_mount_type *mt)
goto out_err;
}
/* Read the bytes into a temporary buffer */
- /* TODO: should probably sanity check them */
+ /* XXX: should probably sanity check them */
READ32(tmp[0]);
READ32(len);
@@ -410,6 +437,17 @@ decode_and_add_ds(uint32_t **pp, struct filelayout_mount_type *mt)
nfs4_pnfs_ds_add(mt, &ds, ip_addr, port);
+ /* XXX: Do we connect to data servers here?
+ * Don't want a lot of un-used (never used!) connections....
+ * Do we wait until LAYOUTGET which will be called on OPEN?
+ */
+ if (!ds->ds_clp) {
+ err = nfs4_pnfs_ds_create(mds_srv, ds);
+ printk("%s nfs4_pnfs_ds_create returned %d\n", __func__, err);
+ if (err)
+ goto out_err;
+ }
+
/* adding ds to stripe */
atomic_inc(&ds->ds_count);
dprintk("%s: addr:port string = %s\n",__FUNCTION__, r_addr);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 505260a..3ab8ca3 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -804,6 +804,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp)
if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
nfs4_recover_state(clp);
}
+EXPORT_SYMBOL(nfs4_schedule_state_recovery);
static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state)
{
--
1.5.0.2
More information about the pNFS
mailing list