
Create XDR and surrounding functions on the client for the GETDEVICEINFO
command. 


---

 linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4proc.c        |   37 ++++
 linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4xdr.c         |   98 ++++++++++++
 linux-2.6.14-pnfs-current-dhildebz/fs/nfs/pnfs.c            |   14 +
 linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs4.h     |    1 
 linux-2.6.14-pnfs-current-dhildebz/include/linux/pnfs_xdr.h |    6 
 5 files changed, 156 insertions(+)

diff -puN fs/nfs/nfs4proc.c~client-deviceinfo fs/nfs/nfs4proc.c
--- linux-2.6.14-pnfs-current/fs/nfs/nfs4proc.c~client-deviceinfo	2006-01-13 17:39:44.061239000 -0500
+++ linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4proc.c	2006-01-13 17:39:44.123239000 -0500
@@ -1543,6 +1543,43 @@ int nfs4_pnfs_getdevicelist(struct nfs_s
 	return err;
 }
 
+/* DH: Retrieve information for a particular storage device.
+ */
+static int _nfs4_pnfs_getdeviceinfo(struct nfs_server *server,
+				    u32 dev_id,
+				    struct pnfs_device *res)
+{
+	struct nfs4_pnfs_getdeviceinfo_arg args = {
+		.fh = &server->fh,
+		.dev_id = dev_id,
+	};
+
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PNFS_GETDEVICEINFO],
+		.rpc_argp = &args,
+		.rpc_resp = res,
+	};
+
+	return rpc_call_sync(server->client, &msg, 0);
+}
+
+int nfs4_pnfs_getdeviceinfo(struct nfs_server *server,
+			    u32 dev_id,
+			    struct pnfs_device* res)
+{
+	struct nfs4_exception exception = { };
+	int err;
+	do {
+		err = nfs4_handle_exception(server,
+					    _nfs4_pnfs_getdeviceinfo(server, dev_id, res),
+					    &exception);
+	} while (exception.retry);
+
+	dprintk("nfs4_pnfs_getdevinfo: err=%d dev_id=%d\n", err, dev_id);
+
+	return err;
+}
+
 static int nfs4_proc_read(struct nfs_read_data *rdata)
 {
 	struct nfs4_exception exception = { };
diff -puN fs/nfs/nfs4xdr.c~client-deviceinfo fs/nfs/nfs4xdr.c
--- linux-2.6.14-pnfs-current/fs/nfs/nfs4xdr.c~client-deviceinfo	2006-01-13 17:39:44.077239000 -0500
+++ linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4xdr.c	2006-01-13 17:39:44.152239000 -0500
@@ -448,6 +448,15 @@ static int nfs_stat_to_errno(int);
 #define NFS4_dec_pnfs_getdevicelist_sz (compound_decode_hdr_maxsz +	\
 					decode_putfh_maxsz +		\
 					decode_getdevicelist_maxsz)
+#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 2)
+#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + 3 + \
+				    NFS4_PNFS_DEV_MAXSIZE)
+#define NFS4_enc_pnfs_getdeviceinfo_sz (compound_encode_hdr_maxsz +	\
+					encode_putfh_maxsz +		\
+					encode_getdeviceinfo_maxsz)
+#define NFS4_dec_pnfs_getdeviceinfo_sz (compound_decode_hdr_maxsz +	\
+					decode_putfh_maxsz +		\
+					decode_getdeviceinfo_maxsz)
 
 static struct {
 	unsigned int	mode;
@@ -1318,6 +1327,18 @@ static int encode_getdevicelist(struct x
 	return 0;
 }
 
+/* DH:  Encode request to get information for a specific device.
+*/
+static int encode_getdeviceinfo(struct xdr_stream *xdr, const struct nfs4_pnfs_getdeviceinfo_arg *args)
+{
+	uint32_t *p;
+	RESERVE_SPACE(12);
+	WRITE32(OP_GETDEVICEINFO);
+	WRITE32(args->layoutclass);
+	WRITE32(args->dev_id);
+	return 0;
+}
+
 /*
  * END OF "GENERIC" ENCODE ROUTINES.
  */
@@ -3579,6 +3600,38 @@ static int decode_getdevicelist(struct x
 	return 0;
 }
 
+/* DH: decode device info arguments
+*/
+static int decode_getdeviceinfo(struct xdr_stream *xdr,
+				struct pnfs_device *res)
+{
+	uint32_t *p;
+	uint32_t len;
+	int status;
+
+	status = decode_op_hdr(xdr, OP_GETDEVICEINFO);
+	if (status)
+		return status;
+
+	READ_BUF(4);
+	READ32(res->dev_id);  /* device id */
+
+	READ_BUF(4);
+	READ32(res->layoutclass);
+
+	READ_BUF(4);
+	READ32(len);
+	READ_BUF(len);
+
+	/* DH-TODO: Can I decode this inline?  Is the xdr_stream
+	 * memory valid after the completion of this function?
+	 */
+/*		decode_opaque_inline(xdr, &len, &r_addr); */
+	COPYMEM(&res->dev_addr_buf, len);
+	res->dev_addr_len = len;
+	return 0;
+}
+
 /*
  * Decode OPEN_DOWNGRADE response
  */
@@ -4613,6 +4666,50 @@ static int nfs4_xdr_dec_pnfs_getdeviceli
 	return status;
 }
 
+/*
+ * DH: Encode GETDEVICEINFO request
+ */
+static int nfs4_xdr_enc_pnfs_getdeviceinfo(struct rpc_rqst *req,
+					   uint32_t *p,
+					   struct nfs4_pnfs_getdeviceinfo_arg *args)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr = {
+		.nops = 1,
+	};
+	int status;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_compound_hdr(&xdr, &hdr);
+	if ((status = encode_putfh(&xdr, args->fh)) == 0)
+		status = encode_getdeviceinfo(&xdr, args);
+	return status;
+}
+
+/*
+ * DH: Decode GETDEVICEINFO response
+ */
+/*
+ * GETDEVINFO
+ */
+static int nfs4_xdr_dec_pnfs_getdeviceinfo(struct rpc_rqst *rqstp,
+					   uint32_t *p,
+					   struct pnfs_device *res)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status == 0) {
+		status = decode_putfh(&xdr);
+		if (status == 0)
+			status = decode_getdeviceinfo(&xdr, res);
+	}
+	return status;
+}
+
 uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
 {
 	uint32_t bitmap[2] = {0};
@@ -4786,6 +4883,7 @@ struct rpc_procinfo	nfs4_procedures[] = 
   PROC(PNFS_LAYOUTCOMMIT,	enc_pnfs_layoutcommit,	dec_pnfs_layoutcommit),
   PROC(PNFS_LAYOUTRETURN,	enc_pnfs_layoutreturn,	dec_pnfs_layoutreturn),
   PROC(PNFS_GETDEVICELIST,	enc_pnfs_getdevicelist,	dec_pnfs_getdevicelist),
+  PROC(PNFS_GETDEVICEINFO,	enc_pnfs_getdeviceinfo,	dec_pnfs_getdeviceinfo),
 };
 
 struct rpc_version		nfs_version4 = {
diff -puN include/linux/nfs4.h~client-deviceinfo include/linux/nfs4.h
--- linux-2.6.14-pnfs-current/include/linux/nfs4.h~client-deviceinfo	2006-01-13 17:39:44.094239000 -0500
+++ linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs4.h	2006-01-13 17:39:44.158239000 -0500
@@ -394,6 +394,7 @@ enum {
 	NFSPROC4_CLNT_PNFS_LAYOUTCOMMIT,
 	NFSPROC4_CLNT_PNFS_LAYOUTRETURN,
 	NFSPROC4_CLNT_PNFS_GETDEVICELIST,
+	NFSPROC4_CLNT_PNFS_GETDEVICEINFO,
 };
 
 #endif
diff -puN fs/nfs/pnfs.c~client-deviceinfo fs/nfs/pnfs.c
--- linux-2.6.14-pnfs-current/fs/nfs/pnfs.c~client-deviceinfo	2006-01-13 17:39:44.101239000 -0500
+++ linux-2.6.14-pnfs-current-dhildebz/fs/nfs/pnfs.c	2006-01-13 17:39:44.165239000 -0500
@@ -58,6 +58,7 @@ extern void nfs_mark_request_commit(stru
 extern void nfs_writeback_done_full(struct nfs_write_data *data, int status);
 extern int nfs_fsync(struct file *file, struct dentry *dentry, int datasync);
 extern int nfs4_pnfs_getdevicelist(struct nfs_server *server, struct pnfs_devicelist* devlist);
+extern int nfs4_pnfs_getdeviceinfo(struct nfs_server *server, u32 dev_id, struct pnfs_device *res);
 
 /* Locking:
  *
@@ -873,5 +874,18 @@ pnfs_getdevicelist(struct super_block *s
 	return nfs4_pnfs_getdevicelist(server, devlist);
 }
 
+/* Retrieve the device information for a device.
+ */
+int
+pnfs_getdeviceinfo(struct super_block *sb, u32 dev_id, struct pnfs_device* dev)
+{
+	struct nfs_server *server = NFS_SB(sb);
+	int rc;
+
+	rc = nfs4_pnfs_getdeviceinfo(server, dev_id, dev);
+
+	return rc;
+}
+
 EXPORT_SYMBOL(pnfs_unregister_layoutdriver);
 EXPORT_SYMBOL(pnfs_register_layoutdriver);
diff -puN include/linux/pnfs_xdr.h~client-deviceinfo include/linux/pnfs_xdr.h
--- linux-2.6.14-pnfs-current/include/linux/pnfs_xdr.h~client-deviceinfo	2006-01-13 17:39:44.106240000 -0500
+++ linux-2.6.14-pnfs-current-dhildebz/include/linux/pnfs_xdr.h	2006-01-13 17:39:44.169240000 -0500
@@ -86,4 +86,10 @@ struct nfs4_pnfs_getdevicelist_arg {
 	u32                             layoutclass;
 };
 
+struct nfs4_pnfs_getdeviceinfo_arg {
+	const struct nfs_fh *            fh;
+	u32                              layoutclass;
+	u32                              dev_id;
+};
+
 #endif /* LINUX_PNFS_XDR_H */
_
