diff mbox

[4/8] pnfsd-exofs: pnfs objects server XDR functions

Message ID 1308085389-12574-1-git-send-email-bharrosh@panasas.com (mailing list archive)
State New, archived
Headers show

Commit Message

Boaz Harrosh June 14, 2011, 9:03 p.m. UTC
* Server support for encoding a pnfs_osd_layout4 XDR stream.

* Implementation of pnfs_osd_xdr_encode_deviceaddr().
  Which takes a pnfs_osd_deviceaddr structure and encodes
  it onto an XDR stream.

* Implementation of pnfs_osd_xdr_decode_ioerr() used by
  servers in layout_return notifications.

* Implementation of pnfs_osd_xdr_decode_layoutupdate()
  used by servers in layout_commit notifications.

* Add pnfs_osd_xdr_srv.c to fs/exportfs/Makefile conditional
  on CONFIG_EXPORTFS_OSD_LAYOUT selected

* Add CONFIG_EXPORTFS_OSD_LAYOUT to fs/Kconfig. It is
  prompt-less needs to be selected by osd filesystems

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>

TODO: We can now remove the olo_comps pointer from
      struct pnfs_osd_layout neither the server nor client use
      it any more. (rename it to pnfs_osd_layout_hdr)

Signed-off-by: Boaz Harrosh <Boaz Harrosh bharrosh@panasas.com>
---
 fs/Kconfig                            |    8 +
 fs/exportfs/Makefile                  |    1 +
 fs/exportfs/pnfs_osd_xdr_srv.c        |  287 +++++++++++++++++++++++++++++++++
 include/linux/nfsd/pnfs_osd_xdr_srv.h |   40 +++++
 4 files changed, 336 insertions(+), 0 deletions(-)
 create mode 100644 fs/exportfs/pnfs_osd_xdr_srv.c
 create mode 100644 include/linux/nfsd/pnfs_osd_xdr_srv.h
diff mbox

Patch

diff --git a/fs/Kconfig b/fs/Kconfig
index 320670e..4980006 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -56,6 +56,14 @@  config EXPORTFS_FILE_LAYOUT
 	  Exportfs support for the NFSv4.1 files layout type.
 	  Must be automatically selected by supporting filesystems.
 
+config EXPORTFS_OSD_LAYOUT
+	bool
+	depends on PNFSD && EXPORTFS
+	help
+	  Exportfs support for the NFSv4.1 objects layout type.
+	  Must be automatically selected by supporting osd
+	  filesystems.
+
 config FILE_LOCKING
 	bool "Enable POSIX file locking API" if EXPERT
 	default y
diff --git a/fs/exportfs/Makefile b/fs/exportfs/Makefile
index 658207d..f6ea13f 100644
--- a/fs/exportfs/Makefile
+++ b/fs/exportfs/Makefile
@@ -5,3 +5,4 @@  obj-$(CONFIG_EXPORTFS) += exportfs.o
 
 exportfs-y				:= expfs.o
 exportfs-$(CONFIG_EXPORTFS_FILE_LAYOUT)	+= nfs4filelayoutxdr.o
+exportfs-$(CONFIG_EXPORTFS_OSD_LAYOUT)	+= pnfs_osd_xdr_srv.o
diff --git a/fs/exportfs/pnfs_osd_xdr_srv.c b/fs/exportfs/pnfs_osd_xdr_srv.c
new file mode 100644
index 0000000..12a3bda
--- /dev/null
+++ b/fs/exportfs/pnfs_osd_xdr_srv.c
@@ -0,0 +1,287 @@ 
+/*
+ *  Object-Based pNFS Layout XDR layer for the Server side
+ *
+ *  Copyright (C) 2007 and on Panasas Inc.
+ *  All rights reserved.
+ *
+ *  Benny Halevy <bhalevy@panasas.com>
+ *  Boaz Harrosh <bharrosh@panasas.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  See the file COPYING included with this distribution for more details.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the Panasas company nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/nfsd/nfsd4_pnfs.h>
+
+#include "linux/nfsd/pnfs_osd_xdr_srv.h"
+
+/*
+ * struct pnfs_osd_data_map {
+ *	u32	odm_num_comps;
+ *	u64	odm_stripe_unit;
+ *	u32	odm_group_width;
+ *	u32	odm_group_depth;
+ *	u32	odm_mirror_cnt;
+ *	u32	odm_raid_algorithm;
+ * };
+ */
+static enum nfsstat4 pnfs_osd_xdr_encode_data_map(
+	struct exp_xdr_stream *xdr,
+	struct pnfs_osd_data_map *data_map)
+{
+	__be32 *p = exp_xdr_reserve_qwords(xdr, 1+2+1+1+1+1);
+
+	if (!p)
+		return NFS4ERR_TOOSMALL;
+
+	p = exp_xdr_encode_u32(p, data_map->odm_num_comps);
+	p = exp_xdr_encode_u64(p, data_map->odm_stripe_unit);
+	p = exp_xdr_encode_u32(p, data_map->odm_group_width);
+	p = exp_xdr_encode_u32(p, data_map->odm_group_depth);
+	p = exp_xdr_encode_u32(p, data_map->odm_mirror_cnt);
+	p = exp_xdr_encode_u32(p, data_map->odm_raid_algorithm);
+
+	return 0;
+}
+
+/*
+ * struct pnfs_osd_objid {
+ *	struct nfs4_deviceid	oid_device_id;
+ *	u64			oid_partition_id;
+ *	u64			oid_object_id;
+ * };
+ */
+static inline enum nfsstat4 pnfs_osd_xdr_encode_objid(
+	struct exp_xdr_stream *xdr,
+	struct pnfs_osd_objid *object_id)
+{
+	__be32 *p = exp_xdr_reserve_qwords(xdr, 2+2+2+2);
+	struct nfsd4_pnfs_deviceid *dev_id =
+		(struct nfsd4_pnfs_deviceid *)&object_id->oid_device_id;
+
+	if (!p)
+		return NFS4ERR_TOOSMALL;
+
+	p = exp_xdr_encode_u64(p, dev_id->sbid);
+	p = exp_xdr_encode_u64(p, dev_id->devid);
+	p = exp_xdr_encode_u64(p, object_id->oid_partition_id);
+	p = exp_xdr_encode_u64(p, object_id->oid_object_id);
+
+	return 0;
+}
+
+/*
+ * enum pnfs_osd_cap_key_sec4 {
+ *	PNFS_OSD_CAP_KEY_SEC_NONE = 0,
+ *	PNFS_OSD_CAP_KEY_SEC_SSV  = 1
+ * };
+ *
+ * struct pnfs_osd_object_cred {
+ *	struct pnfs_osd_objid		oc_object_id;
+ *	u32				oc_osd_version;
+ *	u32				oc_cap_key_sec;
+ *	struct pnfs_osd_opaque_cred	oc_cap_key
+ *	struct pnfs_osd_opaque_cred	oc_cap;
+ * };
+ */
+enum nfsstat4 pnfs_osd_xdr_encode_layout_cred(
+	struct exp_xdr_stream *xdr,
+	struct pnfs_osd_object_cred *olo_comp)
+{
+	__be32 *p;
+	enum nfsstat4 err;
+
+	err = pnfs_osd_xdr_encode_objid(xdr, &olo_comp->oc_object_id);
+	if (err)
+		return err;
+
+	p = exp_xdr_reserve_space(xdr, 3*4 + 4+olo_comp->oc_cap.cred_len);
+	if (!p)
+		return NFS4ERR_TOOSMALL;
+
+	p = exp_xdr_encode_u32(p, olo_comp->oc_osd_version);
+
+	/* No sec for now */
+	p = exp_xdr_encode_u32(p, PNFS_OSD_CAP_KEY_SEC_NONE);
+	p = exp_xdr_encode_u32(p, 0); /* opaque oc_capability_key<> */
+
+	exp_xdr_encode_opaque(p, olo_comp->oc_cap.cred,
+			      olo_comp->oc_cap.cred_len);
+
+	return 0;
+}
+EXPORT_SYMBOL(pnfs_osd_xdr_encode_layout_cred);
+
+/*
+ * struct pnfs_osd_layout {
+ *	struct pnfs_osd_data_map	olo_map;
+ *	u32				olo_comps_index;
+ *	u32				olo_num_comps;
+ *	struct pnfs_osd_object_cred	*olo_comps;
+ * };
+ */
+enum nfsstat4 pnfs_osd_xdr_encode_layout_hdr(
+	struct exp_xdr_stream *xdr,
+	struct pnfs_osd_layout *pol)
+{
+	__be32 *p;
+	enum nfsstat4 err;
+
+	err = pnfs_osd_xdr_encode_data_map(xdr, &pol->olo_map);
+	if (err)
+		return err;
+
+	p = exp_xdr_reserve_qwords(xdr, 2);
+	if (!p)
+		return NFS4ERR_TOOSMALL;
+
+	p = exp_xdr_encode_u32(p, pol->olo_comps_index);
+	p = exp_xdr_encode_u32(p, pol->olo_num_comps);
+
+	return 0;
+}
+EXPORT_SYMBOL(pnfs_osd_xdr_encode_layout_hdr);
+
+static enum nfsstat4 _encode_string(struct exp_xdr_stream *xdr,
+			  const struct nfs4_string *str)
+{
+	__be32 *p = exp_xdr_reserve_space(xdr, 4 + str->len);
+
+	if (!p)
+		return NFS4ERR_TOOSMALL;
+	exp_xdr_encode_opaque(p, str->data, str->len);
+	return 0;
+}
+
+/* struct pnfs_osd_deviceaddr {
+ *	struct pnfs_osd_targetid	oda_targetid;
+ *	struct pnfs_osd_targetaddr	oda_targetaddr;
+ *	u8				oda_lun[8];
+ *	struct nfs4_string		oda_systemid;
+ *	struct pnfs_osd_object_cred	oda_root_obj_cred;
+ *	struct nfs4_string		oda_osdname;
+ * };
+ */
+enum nfsstat4 pnfs_osd_xdr_encode_deviceaddr(
+	struct exp_xdr_stream *xdr, struct pnfs_osd_deviceaddr *devaddr)
+{
+	__be32 *p;
+	enum nfsstat4 err;
+
+	p = exp_xdr_reserve_space(xdr, 4 + 4 + sizeof(devaddr->oda_lun));
+	if (!p)
+		return NFS4ERR_TOOSMALL;
+
+	/* Empty oda_targetid */
+	p = exp_xdr_encode_u32(p, OBJ_TARGET_ANON);
+
+	/* Empty oda_targetaddr for now */
+	p = exp_xdr_encode_u32(p, 0);
+
+	/* oda_lun */
+	exp_xdr_encode_bytes(p, devaddr->oda_lun, sizeof(devaddr->oda_lun));
+
+	err = _encode_string(xdr, &devaddr->oda_systemid);
+	if (err)
+		return err;
+
+	err = pnfs_osd_xdr_encode_layout_cred(xdr,
+					      &devaddr->oda_root_obj_cred);
+	if (err)
+		return err;
+
+	err = _encode_string(xdr, &devaddr->oda_osdname);
+	if (err)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL(pnfs_osd_xdr_encode_deviceaddr);
+
+/*
+ * struct pnfs_osd_layoutupdate {
+ *	u32	dsu_valid;
+ *	s64	dsu_delta;
+ *	u32	olu_ioerr_flag;
+ * };
+ */
+__be32 *
+pnfs_osd_xdr_decode_layoutupdate(struct pnfs_osd_layoutupdate *lou, __be32 *p)
+{
+	lou->dsu_valid = be32_to_cpu(*p++);
+	if (lou->dsu_valid)
+		p = xdr_decode_hyper(p, &lou->dsu_delta);
+	lou->olu_ioerr_flag = be32_to_cpu(*p++);
+	return p;
+}
+EXPORT_SYMBOL(pnfs_osd_xdr_decode_layoutupdate);
+
+/*
+ * struct pnfs_osd_objid {
+ *	struct nfs4_deviceid	oid_device_id;
+ *	u64			oid_partition_id;
+ *	u64			oid_object_id;
+ * }; xdr size 32
+ */
+static inline __be32 *
+pnfs_osd_xdr_decode_objid(__be32 *p, struct pnfs_osd_objid *objid)
+{
+	/* FIXME: p = xdr_decode_fixed(...) */
+	memcpy(objid->oid_device_id.data, p, sizeof(objid->oid_device_id.data));
+	p += XDR_QUADLEN(sizeof(objid->oid_device_id.data));
+
+	p = xdr_decode_hyper(p, &objid->oid_partition_id);
+	p = xdr_decode_hyper(p, &objid->oid_object_id);
+	return p;
+}
+
+/*
+ * struct pnfs_osd_ioerr {
+ *	struct pnfs_osd_objid	oer_component;
+ *	u64			oer_comp_offset;
+ *	u64			oer_comp_length;
+ *	u32			oer_iswrite;
+ *	u32			oer_errno;
+ * }; xdr size 32 + 24
+ */
+bool pnfs_osd_xdr_decode_ioerr(struct pnfs_osd_ioerr *ioerr,
+			       struct exp_xdr_stream *xdr)
+{
+	__be32 *p = exp_xdr_reserve_space(xdr, 32 + 24);
+	if (!p)
+		return false;
+
+	p = pnfs_osd_xdr_decode_objid(p, &ioerr->oer_component);
+	p = xdr_decode_hyper(p, &ioerr->oer_comp_offset);
+	p = xdr_decode_hyper(p, &ioerr->oer_comp_length);
+	ioerr->oer_iswrite = be32_to_cpu(*p++);
+	ioerr->oer_errno = be32_to_cpu(*p);
+	return true;
+}
+EXPORT_SYMBOL(pnfs_osd_xdr_decode_ioerr);
diff --git a/include/linux/nfsd/pnfs_osd_xdr_srv.h b/include/linux/nfsd/pnfs_osd_xdr_srv.h
new file mode 100644
index 0000000..fab244e
--- /dev/null
+++ b/include/linux/nfsd/pnfs_osd_xdr_srv.h
@@ -0,0 +1,40 @@ 
+/*
+ * pnfs-objects Server XDR definitions and API
+ *
+ * Copyright (C) from 2011 Panasas Inc.  All rights reserved.
+ *
+ * Authors:
+ *   Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ *
+ */
+#ifndef __PNFS_OSD_XDR_SRV_H__
+#define __PNFS_OSD_XDR_SRV_H__
+
+#include <linux/pnfs_osd_xdr.h>
+#include <linux/exp_xdr.h>
+
+/* Layout encoding */
+enum nfsstat4 pnfs_osd_xdr_encode_layout_hdr(
+	struct exp_xdr_stream *xdr,
+	struct pnfs_osd_layout *layout);
+
+enum nfsstat4 pnfs_osd_xdr_encode_layout_cred(
+	struct exp_xdr_stream *xdr,
+	struct pnfs_osd_object_cred *cred);
+
+/* deviceaddr encoding */
+enum nfsstat4 pnfs_osd_xdr_encode_deviceaddr(
+	struct exp_xdr_stream *xdr, struct pnfs_osd_deviceaddr *devaddr);
+
+/* layout_commit decoding */
+__be32 *pnfs_osd_xdr_decode_layoutupdate(
+	struct pnfs_osd_layoutupdate *lou, __be32 *p);
+
+/* layout_return decoding */
+bool pnfs_osd_xdr_decode_ioerr(
+	struct pnfs_osd_ioerr *ioerr, struct exp_xdr_stream *xdr);
+
+#endif /* __PNFS_OSD_XDR_SRV_H__ */