[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