/*
 *  pNFS Objects layout implementation over open-osd initiator library
 *
 *  Copyright (C) 2009 Panasas Inc. [year of first publication]
 *  All rights reserved.
 *
 *  Benny Halevy <bhalevy@panasas.com>
 *  Boaz Harrosh <ooo@electrozaur.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/module.h>
#include <scsi/osd_ore.h>

#include "objlayout.h"
#include "../internal.h"

#define NFSDBG_FACILITY         NFSDBG_PNFS_LD

struct objio_dev_ent {
	struct nfs4_deviceid_node id_node;
	struct ore_dev od;
};

static void
objio_free_deviceid_node(struct nfs4_deviceid_node *d)
{
	struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node);

	dprintk("%s: free od=%p\n", __func__, de->od.od);
	osduld_put_device(de->od.od);
	kfree_rcu(d, rcu);
}

struct objio_segment {
	struct pnfs_layout_segment lseg;

	struct ore_layout layout;
	struct ore_components oc;
};

static inline struct objio_segment *
OBJIO_LSEG(struct pnfs_layout_segment *lseg)
{
	return container_of(lseg, struct objio_segment, lseg);
}

struct objio_state {
	/* Generic layer */
	struct objlayout_io_res oir;

	bool sync;
	/*FIXME: Support for extra_bytes at ore_get_rw_state() */
	struct ore_io_state *ios;
};

/* Send and wait for a get_device_info of devices in the layout,
   then look them up with the osd_initiator library */
struct nfs4_deviceid_node *
objio_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
			gfp_t gfp_flags)
{
	struct pnfs_osd_deviceaddr *deviceaddr;
	struct objio_dev_ent *ode = NULL;
	struct osd_dev *od;
	struct osd_dev_info odi;
	bool retry_flag = true;
	__be32 *p;
	int err;

	deviceaddr = kzalloc(sizeof(*deviceaddr), gfp_flags);
	if (!deviceaddr)
		return NULL;

	p = page_address(pdev->pages[0]);
	pnfs_osd_xdr_decode_deviceaddr(deviceaddr, p);

	odi.systemid_len = deviceaddr->oda_systemid.len;
	if (odi.systemid_len > sizeof(odi.systemid)) {
		dprintk("%s: odi.systemid_len > sizeof(systemid=%zd)\n",
			__func__, sizeof(odi.systemid));
		err = -EINVAL;
		goto out;
	} else if (odi.systemid_len)
		memcpy(odi.systemid, deviceaddr->oda_systemid.data,
		       odi.systemid_len);
	odi.osdname_len	 = deviceaddr->oda_osdname.len;
	odi.osdname	 = (u8 *)deviceaddr->oda_osdname.data;

	if (!odi.osdname_len && !odi.systemid_len) {
		dprintk("%s: !odi.osdname_len && !odi.systemid_len\n",
			__func__);
		err = -ENODEV;
		goto out;
	}

retry_lookup:
	od = osduld_info_lookup(&odi);
	if (IS_ERR(od)) {
		err = PTR_ERR(od);
		dprintk("%s: osduld_info_lookup => %d\n", __func__, err);
		if (err == -ENODEV && retry_flag) {
			err = objlayout_autologin(deviceaddr);
			if (likely(!err)) {
				retry_flag = false;
				goto retry_lookup;
			}
		}
		goto out;
	}

	dprintk("Adding new dev_id(%llx:%llx)\n",
		_DEVID_LO(&pdev->dev_id), _DEVID_HI(&pdev->dev_id));

	ode = kzalloc(sizeof(*ode), gfp_flags);
	if (!ode) {
		dprintk("%s: -ENOMEM od=%p\n", __func__, od);
		goto out;
	}

	nfs4_init_deviceid_node(&ode->id_node, server, &pdev->dev_id);
	kfree(deviceaddr);

	ode->od.od = od;
	return &ode->id_node;

out:
	kfree(deviceaddr);
	return NULL;
}

static void copy_single_comp(struct ore_components *oc, unsigned c,
			     struct pnfs_osd_object_cred *src_comp)
{
	struct ore_comp *ocomp = &oc->comps[c];

	WARN_ON(src_comp->oc_cap_key.cred_len > 0); /* libosd is NO_SEC only */
	WARN_ON(src_comp->oc_cap.cred_len > sizeof(ocomp->cred));

	ocomp->obj.partition = src_comp->oc_object_id.oid_partition_id;
	ocomp->obj.id = src_comp->oc_object_id.oid_object_id;

	memcpy(ocomp->cred, src_comp->oc_cap.cred, sizeof(ocomp->cred));
}

static int __alloc_objio_seg(unsigned numdevs, gfp_t gfp_flags,
		       struct objio_segment **pseg)
{
/*	This is the in memory structure of the objio_segment
 *
 *	struct __alloc_objio_segment {
 *		struct objio_segment olseg;
 *		struct ore_dev *ods[numdevs];
 *		struct ore_comp	comps[numdevs];
 *	} *aolseg;
 *	NOTE: The code as above compiles and runs perfectly. It is elegant,
 *	type safe and compact. At some Past time Linus has decided he does not
 *	like variable length arrays, For the sake of this principal we uglify
 *	the code as below.
 */
	struct objio_segment *lseg;
	size_t lseg_size = sizeof(*lseg) +
			numdevs * sizeof(lseg->oc.ods[0]) +
			numdevs * sizeof(*lseg->oc.comps);

	lseg = kzalloc(lseg_size, gfp_flags);
	if (unlikely(!lseg)) {
		dprintk("%s: Failed allocation numdevs=%d size=%zd\n", __func__,
			numdevs, lseg_size);
		return -ENOMEM;
	}

	lseg->oc.numdevs = numdevs;
	lseg->oc.single_comp = EC_MULTPLE_COMPS;
	lseg->oc.ods = (void *)(lseg + 1);
	lseg->oc.comps = (void *)(lseg->oc.ods + numdevs);

	*pseg = lseg;
	return 0;
}

int objio_alloc_lseg(struct pnfs_layout_segment **outp,
	struct pnfs_layout_hdr *pnfslay,
	struct pnfs_layout_range *range,
	struct xdr_stream *xdr,
	gfp_t gfp_flags)
{
	struct nfs_server *server = NFS_SERVER(pnfslay->plh_inode);
	struct objio_segment *objio_seg;
	struct pnfs_osd_xdr_decode_layout_iter iter;
	struct pnfs_osd_layout layout;
	struct pnfs_osd_object_cred src_comp;
	unsigned cur_comp;
	int err;

	err = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr);
	if (unlikely(err))
		return err;

	err = __alloc_objio_seg(layout.olo_num_comps, gfp_flags, &objio_seg);
	if (unlikely(err))
		return err;

	objio_seg->layout.stripe_unit = layout.olo_map.odm_stripe_unit;
	objio_seg->layout.group_width = layout.olo_map.odm_group_width;
	objio_seg->layout.group_depth = layout.olo_map.odm_group_depth;
	objio_seg->layout.mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1;
	objio_seg->layout.raid_algorithm = layout.olo_map.odm_raid_algorithm;

	err = ore_verify_layout(layout.olo_map.odm_num_comps,
					  &objio_seg->layout);
	if (unlikely(err))
		goto err;

	objio_seg->oc.first_dev = layout.olo_comps_index;
	cur_comp = 0;
	while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) {
		struct nfs4_deviceid_node *d;
		struct objio_dev_ent *ode;

		copy_single_comp(&objio_seg->oc, cur_comp, &src_comp);

		d = nfs4_find_get_deviceid(server,
				&src_comp.oc_object_id.oid_device_id,
				pnfslay->plh_lc_cred, gfp_flags);
		if (!d) {
			err = -ENXIO;
			goto err;
		}

		ode = container_of(d, struct objio_dev_ent, id_node);
		objio_seg->oc.ods[cur_comp++] = &ode->od;
	}
	/* pnfs_osd_xdr_decode_layout_comp returns false on error */
	if (unlikely(err))
		goto err;

	*outp = &objio_seg->lseg;
	return 0;

err:
	kfree(objio_seg);
	dprintk("%s: Error: return %d\n", __func__, err);
	*outp = NULL;
	return err;
}

void objio_free_lseg(struct pnfs_layout_segment *lseg)
{
	int i;
	struct objio_segment *objio_seg = OBJIO_LSEG(lseg);

	for (i = 0; i < objio_seg->oc.numdevs; i++) {
		struct ore_dev *od = objio_seg->oc.ods[i];
		struct objio_dev_ent *ode;

		if (!od)
			break;
		ode = container_of(od, typeof(*ode), od);
		nfs4_put_deviceid_node(&ode->id_node);
	}
	kfree(objio_seg);
}

static int
objio_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type, bool is_reading,
	struct pnfs_layout_segment *lseg, struct page **pages, unsigned pgbase,
	loff_t offset, size_t count, void *rpcdata, gfp_t gfp_flags,
	struct objio_state **outp)
{
	struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
	struct ore_io_state *ios;
	int ret;
	struct __alloc_objio_state {
		struct objio_state objios;
		struct pnfs_osd_ioerr ioerrs[objio_seg->oc.numdevs];
	} *aos;

	aos = kzalloc(sizeof(*aos), gfp_flags);
	if (unlikely(!aos))
		return -ENOMEM;

	objlayout_init_ioerrs(&aos->objios.oir, objio_seg->oc.numdevs,
			aos->ioerrs, rpcdata, pnfs_layout_type);

	ret = ore_get_rw_state(&objio_seg->layout, &objio_seg->oc, is_reading,
			       offset, count, &ios);
	if (unlikely(ret)) {
		kfree(aos);
		return ret;
	}

	ios->pages = pages;
	ios->pgbase = pgbase;
	ios->private = aos;
	BUG_ON(ios->nr_pages > (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT);

	aos->objios.sync = 0;
	aos->objios.ios = ios;
	*outp = &aos->objios;
	return 0;
}

void objio_free_result(struct objlayout_io_res *oir)
{
	struct objio_state *objios = container_of(oir, struct objio_state, oir);

	ore_put_io_state(objios->ios);
	kfree(objios);
}

static enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
{
	switch (oep) {
	case OSD_ERR_PRI_NO_ERROR:
		return (enum pnfs_osd_errno)0;

	case OSD_ERR_PRI_CLEAR_PAGES:
		BUG_ON(1);
		return 0;

	case OSD_ERR_PRI_RESOURCE:
		return PNFS_OSD_ERR_RESOURCE;
	case OSD_ERR_PRI_BAD_CRED:
		return PNFS_OSD_ERR_BAD_CRED;
	case OSD_ERR_PRI_NO_ACCESS:
		return PNFS_OSD_ERR_NO_ACCESS;
	case OSD_ERR_PRI_UNREACHABLE:
		return PNFS_OSD_ERR_UNREACHABLE;
	case OSD_ERR_PRI_NOT_FOUND:
		return PNFS_OSD_ERR_NOT_FOUND;
	case OSD_ERR_PRI_NO_SPACE:
		return PNFS_OSD_ERR_NO_SPACE;
	default:
		WARN_ON(1);
		/* fallthrough */
	case OSD_ERR_PRI_EIO:
		return PNFS_OSD_ERR_EIO;
	}
}

static void __on_dev_error(struct ore_io_state *ios,
	struct ore_dev *od, unsigned dev_index, enum osd_err_priority oep,
	u64 dev_offset, u64  dev_len)
{
	struct objio_state *objios = ios->private;
	struct pnfs_osd_objid pooid;
	struct objio_dev_ent *ode = container_of(od, typeof(*ode), od);
	/* FIXME: what to do with more-then-one-group layouts. We need to
	 * translate from ore_io_state index to oc->comps index
	 */
	unsigned comp = dev_index;

	pooid.oid_device_id = ode->id_node.deviceid;
	pooid.oid_partition_id = ios->oc->comps[comp].obj.partition;
	pooid.oid_object_id = ios->oc->comps[comp].obj.id;

	objlayout_io_set_result(&objios->oir, comp,
				&pooid, osd_pri_2_pnfs_err(oep),
				dev_offset, dev_len, !ios->reading);
}

/*
 * read
 */
static void _read_done(struct ore_io_state *ios, void *private)
{
	struct objio_state *objios = private;
	ssize_t status;
	int ret = ore_check_io(ios, &__on_dev_error);

	/* FIXME: _io_free(ios) can we dealocate the libosd resources; */

	if (likely(!ret))
		status = ios->length;
	else
		status = ret;

	objlayout_read_done(&objios->oir, status, objios->sync);
}

int objio_read_pagelist(struct nfs_pgio_header *hdr)
{
	struct objio_state *objios;
	int ret;

	ret = objio_alloc_io_state(NFS_I(hdr->inode)->layout, true,
			hdr->lseg, hdr->args.pages, hdr->args.pgbase,
			hdr->args.offset, hdr->args.count, hdr,
			GFP_KERNEL, &objios);
	if (unlikely(ret))
		return ret;

	objios->ios->done = _read_done;
	dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
		hdr->args.offset, hdr->args.count);
	ret = ore_read(objios->ios);
	if (unlikely(ret))
		objio_free_result(&objios->oir);
	return ret;
}

/*
 * write
 */
static void _write_done(struct ore_io_state *ios, void *private)
{
	struct objio_state *objios = private;
	ssize_t status;
	int ret = ore_check_io(ios, &__on_dev_error);

	/* FIXME: _io_free(ios) can we dealocate the libosd resources; */

	if (likely(!ret)) {
		/* FIXME: should be based on the OSD's persistence model
		 * See OSD2r05 Section 4.13 Data persistence model */
		objios->oir.committed = NFS_FILE_SYNC;
		status = ios->length;
	} else {
		status = ret;
	}

	objlayout_write_done(&objios->oir, status, objios->sync);
}

static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
{
	struct objio_state *objios = priv;
	struct nfs_pgio_header *hdr = objios->oir.rpcdata;
	struct address_space *mapping = hdr->inode->i_mapping;
	pgoff_t index = offset / PAGE_SIZE;
	struct page *page;
	loff_t i_size = i_size_read(hdr->inode);

	if (offset >= i_size) {
		*uptodate = true;
		dprintk("%s: g_zero_page index=0x%lx\n", __func__, index);
		return ZERO_PAGE(0);
	}

	page = find_get_page(mapping, index);
	if (!page) {
		page = find_or_create_page(mapping, index, GFP_NOFS);
		if (unlikely(!page)) {
			dprintk("%s: grab_cache_page Failed index=0x%lx\n",
				__func__, index);
			return NULL;
		}
		unlock_page(page);
	}
	*uptodate = PageUptodate(page);
	dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate);
	return page;
}

static void __r4w_put_page(void *priv, struct page *page)
{
	dprintk("%s: index=0x%lx\n", __func__,
		(page == ZERO_PAGE(0)) ? -1UL : page->index);
	if (ZERO_PAGE(0) != page)
		put_page(page);
	return;
}

static const struct _ore_r4w_op _r4w_op = {
	.get_page = &__r4w_get_page,
	.put_page = &__r4w_put_page,
};

int objio_write_pagelist(struct nfs_pgio_header *hdr, int how)
{
	struct objio_state *objios;
	int ret;

	ret = objio_alloc_io_state(NFS_I(hdr->inode)->layout, false,
			hdr->lseg, hdr->args.pages, hdr->args.pgbase,
			hdr->args.offset, hdr->args.count, hdr, GFP_NOFS,
			&objios);
	if (unlikely(ret))
		return ret;

	objios->sync = 0 != (how & FLUSH_SYNC);
	objios->ios->r4w = &_r4w_op;

	if (!objios->sync)
		objios->ios->done = _write_done;

	dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
		hdr->args.offset, hdr->args.count);
	ret = ore_write(objios->ios);
	if (unlikely(ret)) {
		objio_free_result(&objios->oir);
		return ret;
	}

	if (objios->sync)
		_write_done(objios->ios, objios);

	return 0;
}

/*
 * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number
 * of bytes (maximum @req->wb_bytes) that can be coalesced.
 */
static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio,
			  struct nfs_page *prev, struct nfs_page *req)
{
	struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(pgio);
	unsigned int size;

	size = pnfs_generic_pg_test(pgio, prev, req);

	if (!size || mirror->pg_count + req->wb_bytes >
	    (unsigned long)pgio->pg_layout_private)
		return 0;

	return min(size, req->wb_bytes);
}

static void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
	pnfs_generic_pg_init_read(pgio, req);
	if (unlikely(pgio->pg_lseg == NULL))
		return; /* Not pNFS */

	pgio->pg_layout_private = (void *)
				OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
}

static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout,
				   unsigned long *stripe_end)
{
	u32 stripe_off;
	unsigned stripe_size;

	if (layout->raid_algorithm == PNFS_OSD_RAID_0)
		return true;

	stripe_size = layout->stripe_unit *
				(layout->group_width - layout->parity);

	div_u64_rem(offset, stripe_size, &stripe_off);
	if (!stripe_off)
		return true;

	*stripe_end = stripe_size - stripe_off;
	return false;
}

static void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
	unsigned long stripe_end = 0;
	u64 wb_size;

	if (pgio->pg_dreq == NULL)
		wb_size = i_size_read(pgio->pg_inode) - req_offset(req);
	else
		wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);

	pnfs_generic_pg_init_write(pgio, req, wb_size);
	if (unlikely(pgio->pg_lseg == NULL))
		return; /* Not pNFS */

	if (req->wb_offset ||
	    !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE,
			       &OBJIO_LSEG(pgio->pg_lseg)->layout,
			       &stripe_end)) {
		pgio->pg_layout_private = (void *)stripe_end;
	} else {
		pgio->pg_layout_private = (void *)
				OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
	}
}

static const struct nfs_pageio_ops objio_pg_read_ops = {
	.pg_init = objio_init_read,
	.pg_test = objio_pg_test,
	.pg_doio = pnfs_generic_pg_readpages,
	.pg_cleanup = pnfs_generic_pg_cleanup,
};

static const struct nfs_pageio_ops objio_pg_write_ops = {
	.pg_init = objio_init_write,
	.pg_test = objio_pg_test,
	.pg_doio = pnfs_generic_pg_writepages,
	.pg_cleanup = pnfs_generic_pg_cleanup,
};

static struct pnfs_layoutdriver_type objlayout_type = {
	.id = LAYOUT_OSD2_OBJECTS,
	.name = "LAYOUT_OSD2_OBJECTS",
	.flags                   = PNFS_LAYOUTRET_ON_SETATTR |
				   PNFS_LAYOUTRET_ON_ERROR,

	.max_deviceinfo_size	 = PAGE_SIZE,
	.owner		       	 = THIS_MODULE,
	.alloc_layout_hdr        = objlayout_alloc_layout_hdr,
	.free_layout_hdr         = objlayout_free_layout_hdr,

	.alloc_lseg              = objlayout_alloc_lseg,
	.free_lseg               = objlayout_free_lseg,

	.read_pagelist           = objlayout_read_pagelist,
	.write_pagelist          = objlayout_write_pagelist,
	.pg_read_ops             = &objio_pg_read_ops,
	.pg_write_ops            = &objio_pg_write_ops,

	.sync			 = pnfs_generic_sync,

	.free_deviceid_node	 = objio_free_deviceid_node,

	.encode_layoutcommit	 = objlayout_encode_layoutcommit,
	.encode_layoutreturn     = objlayout_encode_layoutreturn,
};

MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects");
MODULE_AUTHOR("Benny Halevy <bhalevy@panasas.com>");
MODULE_LICENSE("GPL");

static int __init
objlayout_init(void)
{
	int ret = pnfs_register_layoutdriver(&objlayout_type);

	if (ret)
		printk(KERN_INFO
			"NFS: %s: Registering OSD pNFS Layout Driver failed: error=%d\n",
			__func__, ret);
	else
		printk(KERN_INFO "NFS: %s: Registered OSD pNFS Layout Driver\n",
			__func__);
	return ret;
}

static void __exit
objlayout_exit(void)
{
	pnfs_unregister_layoutdriver(&objlayout_type);
	printk(KERN_INFO "NFS: %s: Unregistered OSD pNFS Layout Driver\n",
	       __func__);
}

MODULE_ALIAS("nfs-layouttype4-2");

module_init(objlayout_init);
module_exit(objlayout_exit);
