/*
 *  Object-Based pNFS Layout XDR layer
 *
 *  Copyright (C) 2007 Panasas Inc. [year of first publication]
 *  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/pnfs_osd_xdr.h>

#define NFSDBG_FACILITY         NFSDBG_PNFS_LD

/*
 * The following implementation is based on RFC5664
 */

/*
 * struct pnfs_osd_objid {
 *	struct nfs4_deviceid	oid_device_id;
 *	u64			oid_partition_id;
 *	u64			oid_object_id;
 * }; // xdr size 32 bytes
 */
static __be32 *
_osd_xdr_decode_objid(__be32 *p, struct pnfs_osd_objid *objid)
{
	p = xdr_decode_opaque_fixed(p, objid->oid_device_id.data,
				    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_opaque_cred {
 *	u32 cred_len;
 *	void *cred;
 * }; // xdr size [variable]
 * The return pointers are from the xdr buffer
 */
static int
_osd_xdr_decode_opaque_cred(struct pnfs_osd_opaque_cred *opaque_cred,
			    struct xdr_stream *xdr)
{
	__be32 *p = xdr_inline_decode(xdr, 1);

	if (!p)
		return -EINVAL;

	opaque_cred->cred_len = be32_to_cpu(*p++);

	p = xdr_inline_decode(xdr, opaque_cred->cred_len);
	if (!p)
		return -EINVAL;

	opaque_cred->cred = p;
	return 0;
}

/*
 * 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;
 * }; // xdr size 32 + 4 + 4 + [variable] + [variable]
 */
static int
_osd_xdr_decode_object_cred(struct pnfs_osd_object_cred *comp,
			    struct xdr_stream *xdr)
{
	__be32 *p = xdr_inline_decode(xdr, 32 + 4 + 4);
	int ret;

	if (!p)
		return -EIO;

	p = _osd_xdr_decode_objid(p, &comp->oc_object_id);
	comp->oc_osd_version = be32_to_cpup(p++);
	comp->oc_cap_key_sec = be32_to_cpup(p);

	ret = _osd_xdr_decode_opaque_cred(&comp->oc_cap_key, xdr);
	if (unlikely(ret))
		return ret;

	ret = _osd_xdr_decode_opaque_cred(&comp->oc_cap, xdr);
	return ret;
}

/*
 * 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;
 * }; // xdr size 4 + 8 + 4 + 4 + 4 + 4
 */
static inline int
_osd_data_map_xdr_sz(void)
{
	return 4 + 8 + 4 + 4 + 4 + 4;
}

static __be32 *
_osd_xdr_decode_data_map(__be32 *p, struct pnfs_osd_data_map *data_map)
{
	data_map->odm_num_comps = be32_to_cpup(p++);
	p = xdr_decode_hyper(p, &data_map->odm_stripe_unit);
	data_map->odm_group_width = be32_to_cpup(p++);
	data_map->odm_group_depth = be32_to_cpup(p++);
	data_map->odm_mirror_cnt = be32_to_cpup(p++);
	data_map->odm_raid_algorithm = be32_to_cpup(p++);
	dprintk("%s: odm_num_comps=%u odm_stripe_unit=%llu odm_group_width=%u "
		"odm_group_depth=%u odm_mirror_cnt=%u odm_raid_algorithm=%u\n",
		__func__,
		data_map->odm_num_comps,
		(unsigned long long)data_map->odm_stripe_unit,
		data_map->odm_group_width,
		data_map->odm_group_depth,
		data_map->odm_mirror_cnt,
		data_map->odm_raid_algorithm);
	return p;
}

int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout,
	struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr)
{
	__be32 *p;

	memset(iter, 0, sizeof(*iter));

	p = xdr_inline_decode(xdr, _osd_data_map_xdr_sz() + 4 + 4);
	if (unlikely(!p))
		return -EINVAL;

	p = _osd_xdr_decode_data_map(p, &layout->olo_map);
	layout->olo_comps_index = be32_to_cpup(p++);
	layout->olo_num_comps = be32_to_cpup(p++);
	iter->total_comps = layout->olo_num_comps;
	return 0;
}

bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp,
	struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr,
	int *err)
{
	BUG_ON(iter->decoded_comps > iter->total_comps);
	if (iter->decoded_comps == iter->total_comps)
		return false;

	*err = _osd_xdr_decode_object_cred(comp, xdr);
	if (unlikely(*err)) {
		dprintk("%s: _osd_xdr_decode_object_cred=>%d decoded_comps=%d "
			"total_comps=%d\n", __func__, *err,
			iter->decoded_comps, iter->total_comps);
		return false; /* stop the loop */
	}
	dprintk("%s: dev(%llx:%llx) par=0x%llx obj=0x%llx "
		"key_len=%u cap_len=%u\n",
		__func__,
		_DEVID_LO(&comp->oc_object_id.oid_device_id),
		_DEVID_HI(&comp->oc_object_id.oid_device_id),
		comp->oc_object_id.oid_partition_id,
		comp->oc_object_id.oid_object_id,
		comp->oc_cap_key.cred_len, comp->oc_cap.cred_len);

	iter->decoded_comps++;
	return true;
}

/*
 * Get Device Information Decoding
 *
 * Note: since Device Information is currently done synchronously, all
 *       variable strings fields are left inside the rpc buffer and are only
 *       pointed to by the pnfs_osd_deviceaddr members. So the read buffer
 *       should not be freed while the returned information is in use.
 */
/*
 *struct nfs4_string {
 *	unsigned int len;
 *	char *data;
 *}; // size [variable]
 * NOTE: Returned string points to inside the XDR buffer
 */
static __be32 *
__read_u8_opaque(__be32 *p, struct nfs4_string *str)
{
	str->len = be32_to_cpup(p++);
	str->data = (char *)p;

	p += XDR_QUADLEN(str->len);
	return p;
}

/*
 * struct pnfs_osd_targetid {
 *	u32			oti_type;
 *	struct nfs4_string	oti_scsi_device_id;
 * };// size 4 + [variable]
 */
static __be32 *
__read_targetid(__be32 *p, struct pnfs_osd_targetid* targetid)
{
	u32 oti_type;

	oti_type = be32_to_cpup(p++);
	targetid->oti_type = oti_type;

	switch (oti_type) {
	case OBJ_TARGET_SCSI_NAME:
	case OBJ_TARGET_SCSI_DEVICE_ID:
		p = __read_u8_opaque(p, &targetid->oti_scsi_device_id);
	}

	return p;
}

/*
 * struct pnfs_osd_net_addr {
 *	struct nfs4_string	r_netid;
 *	struct nfs4_string	r_addr;
 * };
 */
static __be32 *
__read_net_addr(__be32 *p, struct pnfs_osd_net_addr* netaddr)
{
	p = __read_u8_opaque(p, &netaddr->r_netid);
	p = __read_u8_opaque(p, &netaddr->r_addr);

	return p;
}

/*
 * struct pnfs_osd_targetaddr {
 *	u32				ota_available;
 *	struct pnfs_osd_net_addr	ota_netaddr;
 * };
 */
static __be32 *
__read_targetaddr(__be32 *p, struct pnfs_osd_targetaddr *targetaddr)
{
	u32 ota_available;

	ota_available = be32_to_cpup(p++);
	targetaddr->ota_available = ota_available;

	if (ota_available)
		p = __read_net_addr(p, &targetaddr->ota_netaddr);


	return p;
}

/*
 * 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;
 * };
 */

/* We need this version for the pnfs_osd_xdr_decode_deviceaddr which does
 * not have an xdr_stream
 */
static __be32 *
__read_opaque_cred(__be32 *p,
			      struct pnfs_osd_opaque_cred *opaque_cred)
{
	opaque_cred->cred_len = be32_to_cpu(*p++);
	opaque_cred->cred = p;
	return p + XDR_QUADLEN(opaque_cred->cred_len);
}

static __be32 *
__read_object_cred(__be32 *p, struct pnfs_osd_object_cred *comp)
{
	p = _osd_xdr_decode_objid(p, &comp->oc_object_id);
	comp->oc_osd_version = be32_to_cpup(p++);
	comp->oc_cap_key_sec = be32_to_cpup(p++);

	p = __read_opaque_cred(p, &comp->oc_cap_key);
	p = __read_opaque_cred(p, &comp->oc_cap);
	return p;
}

void pnfs_osd_xdr_decode_deviceaddr(
	struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p)
{
	p = __read_targetid(p, &deviceaddr->oda_targetid);

	p = __read_targetaddr(p, &deviceaddr->oda_targetaddr);

	p = xdr_decode_opaque_fixed(p, deviceaddr->oda_lun,
				    sizeof(deviceaddr->oda_lun));

	p = __read_u8_opaque(p, &deviceaddr->oda_systemid);

	p = __read_object_cred(p, &deviceaddr->oda_root_obj_cred);

	p = __read_u8_opaque(p, &deviceaddr->oda_osdname);

	/* libosd likes this terminated in dbg. It's last, so no problems */
	deviceaddr->oda_osdname.data[deviceaddr->oda_osdname.len] = 0;
}

/*
 * struct pnfs_osd_layoutupdate {
 *	u32	dsu_valid;
 *	s64	dsu_delta;
 *	u32	olu_ioerr_flag;
 * }; xdr size 4 + 8 + 4
 */
int
pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr,
				 struct pnfs_osd_layoutupdate *lou)
{
	__be32 *p = xdr_reserve_space(xdr,  4 + 8 + 4);

	if (!p)
		return -E2BIG;

	*p++ = cpu_to_be32(lou->dsu_valid);
	if (lou->dsu_valid)
		p = xdr_encode_hyper(p, lou->dsu_delta);
	*p++ = cpu_to_be32(lou->olu_ioerr_flag);
	return 0;
}

/*
 * struct pnfs_osd_objid {
 *	struct nfs4_deviceid	oid_device_id;
 *	u64			oid_partition_id;
 *	u64			oid_object_id;
 * }; // xdr size 32 bytes
 */
static inline __be32 *
pnfs_osd_xdr_encode_objid(__be32 *p, struct pnfs_osd_objid *object_id)
{
	p = xdr_encode_opaque_fixed(p, &object_id->oid_device_id.data,
				    sizeof(object_id->oid_device_id.data));
	p = xdr_encode_hyper(p, object_id->oid_partition_id);
	p = xdr_encode_hyper(p, object_id->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 bytes
 */
void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr)
{
	p = pnfs_osd_xdr_encode_objid(p, &ioerr->oer_component);
	p = xdr_encode_hyper(p, ioerr->oer_comp_offset);
	p = xdr_encode_hyper(p, ioerr->oer_comp_length);
	*p++ = cpu_to_be32(ioerr->oer_iswrite);
	*p   = cpu_to_be32(ioerr->oer_errno);
}

__be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr)
{
	__be32 *p;

	p = xdr_reserve_space(xdr, 32 + 24);
	if (unlikely(!p))
		dprintk("%s: out of xdr space\n", __func__);

	return p;
}
