/*
 * Copyright (C) 2005, 2006
 * Avishay Traeger (avishay@gmail.com)
 * Copyright (C) 2008, 2009
 * Boaz Harrosh <bharrosh@panasas.com>
 *
 * This file is part of exofs.
 *
 * exofs is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.  Since it is based on ext2, and the only
 * valid version of GPL for the Linux kernel is version 2, the only valid
 * version of GPL for exofs is version 2.
 *
 * exofs is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with exofs; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/slab.h>
#include <asm/div64.h>
#include <linux/lcm.h>

#include "ore_raid.h"

MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
MODULE_DESCRIPTION("Objects Raid Engine ore.ko");
MODULE_LICENSE("GPL");

/* ore_verify_layout does a couple of things:
 * 1. Given a minimum number of needed parameters fixes up the rest of the
 *    members to be operatonals for the ore. The needed parameters are those
 *    that are defined by the pnfs-objects layout STD.
 * 2. Check to see if the current ore code actually supports these parameters
 *    for example stripe_unit must be a multple of the system PAGE_SIZE,
 *    and etc...
 * 3. Cache some havily used calculations that will be needed by users.
 */

enum { BIO_MAX_PAGES_KMALLOC =
		(PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),};

int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
{
	u64 stripe_length;

/* FIXME: Only raid0 is supported for now. */
	if (layout->raid_algorithm != PNFS_OSD_RAID_0) {
		ORE_ERR("Only RAID_0 for now\n");
		return -EINVAL;
	}
	if (0 != (layout->stripe_unit & ~PAGE_MASK)) {
		ORE_ERR("Stripe Unit(0x%llx)"
			  " must be Multples of PAGE_SIZE(0x%lx)\n",
			  _LLU(layout->stripe_unit), PAGE_SIZE);
		return -EINVAL;
	}
	if (layout->group_width) {
		if (!layout->group_depth) {
			ORE_ERR("group_depth == 0 && group_width != 0\n");
			return -EINVAL;
		}
		if (total_comps < (layout->group_width * layout->mirrors_p1)) {
			ORE_ERR("Data Map wrong, "
				"numdevs=%d < group_width=%d * mirrors=%d\n",
				total_comps, layout->group_width,
				layout->mirrors_p1);
			return -EINVAL;
		}
		layout->group_count = total_comps / layout->mirrors_p1 /
						layout->group_width;
	} else {
		if (layout->group_depth) {
			printk(KERN_NOTICE "Warning: group_depth ignored "
				"group_width == 0 && group_depth == %lld\n",
				_LLU(layout->group_depth));
		}
		layout->group_width = total_comps / layout->mirrors_p1;
		layout->group_depth = -1;
		layout->group_count = 1;
	}

	stripe_length = (u64)layout->group_width * layout->stripe_unit;
	if (stripe_length >= (1ULL << 32)) {
		ORE_ERR("Stripe_length(0x%llx) >= 32bit is not supported\n",
			_LLU(stripe_length));
		return -EINVAL;
	}

	layout->max_io_length =
		(BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) *
							layout->group_width;
	return 0;
}
EXPORT_SYMBOL(ore_verify_layout);

static u8 *_ios_cred(struct ore_io_state *ios, unsigned index)
{
	return ios->oc->comps[index & ios->oc->single_comp].cred;
}

static struct osd_obj_id *_ios_obj(struct ore_io_state *ios, unsigned index)
{
	return &ios->oc->comps[index & ios->oc->single_comp].obj;
}

static struct osd_dev *_ios_od(struct ore_io_state *ios, unsigned index)
{
	ORE_DBGMSG2("oc->first_dev=%d oc->numdevs=%d i=%d oc->ods=%p\n",
		    ios->oc->first_dev, ios->oc->numdevs, index,
		    ios->oc->ods);

	return ore_comp_dev(ios->oc, index);
}

static int  _ore_get_io_state(struct ore_layout *layout,
			struct ore_components *oc, unsigned numdevs,
			unsigned sgs_per_dev, unsigned num_par_pages,
			struct ore_io_state **pios)
{
	struct ore_io_state *ios;
	struct page **pages;
	struct osd_sg_entry *sgilist;
	struct __alloc_all_io_state {
		struct ore_io_state ios;
		struct ore_per_dev_state per_dev[numdevs];
		union {
			struct osd_sg_entry sglist[sgs_per_dev * numdevs];
			struct page *pages[num_par_pages];
		};
	} *_aios;

	if (likely(sizeof(*_aios) <= PAGE_SIZE)) {
		_aios = kzalloc(sizeof(*_aios), GFP_KERNEL);
		if (unlikely(!_aios)) {
			ORE_DBGMSG("Failed kzalloc bytes=%zd\n",
				   sizeof(*_aios));
			*pios = NULL;
			return -ENOMEM;
		}
		pages = num_par_pages ? _aios->pages : NULL;
		sgilist = sgs_per_dev ? _aios->sglist : NULL;
		ios = &_aios->ios;
	} else {
		struct __alloc_small_io_state {
			struct ore_io_state ios;
			struct ore_per_dev_state per_dev[numdevs];
		} *_aio_small;
		union __extra_part {
			struct osd_sg_entry sglist[sgs_per_dev * numdevs];
			struct page *pages[num_par_pages];
		} *extra_part;

		_aio_small = kzalloc(sizeof(*_aio_small), GFP_KERNEL);
		if (unlikely(!_aio_small)) {
			ORE_DBGMSG("Failed alloc first part bytes=%zd\n",
				   sizeof(*_aio_small));
			*pios = NULL;
			return -ENOMEM;
		}
		extra_part = kzalloc(sizeof(*extra_part), GFP_KERNEL);
		if (unlikely(!extra_part)) {
			ORE_DBGMSG("Failed alloc second part bytes=%zd\n",
				   sizeof(*extra_part));
			kfree(_aio_small);
			*pios = NULL;
			return -ENOMEM;
		}

		pages = num_par_pages ? extra_part->pages : NULL;
		sgilist = sgs_per_dev ? extra_part->sglist : NULL;
		/* In this case the per_dev[0].sgilist holds the pointer to
		 * be freed
		 */
		ios = &_aio_small->ios;
		ios->extra_part_alloc = true;
	}

	if (pages) {
		ios->parity_pages = pages;
		ios->max_par_pages = num_par_pages;
	}
	if (sgilist) {
		unsigned d;

		for (d = 0; d < numdevs; ++d) {
			ios->per_dev[d].sglist = sgilist;
			sgilist += sgs_per_dev;
		}
		ios->sgs_per_dev = sgs_per_dev;
	}

	ios->layout = layout;
	ios->oc = oc;
	*pios = ios;
	return 0;
}

/* Allocate an io_state for only a single group of devices
 *
 * If a user needs to call ore_read/write() this version must be used becase it
 * allocates extra stuff for striping and raid.
 * The ore might decide to only IO less then @length bytes do to alignmets
 * and constrains as follows:
 * - The IO cannot cross group boundary.
 * - In raid5/6 The end of the IO must align at end of a stripe eg.
 *   (@offset + @length) % strip_size == 0. Or the complete range is within a
 *   single stripe.
 * - Memory condition only permitted a shorter IO. (A user can use @length=~0
 *   And check the returned ios->length for max_io_size.)
 *
 * The caller must check returned ios->length (and/or ios->nr_pages) and
 * re-issue these pages that fall outside of ios->length
 */
int  ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
		      bool is_reading, u64 offset, u64 length,
		      struct ore_io_state **pios)
{
	struct ore_io_state *ios;
	unsigned numdevs = layout->group_width * layout->mirrors_p1;
	unsigned sgs_per_dev = 0, max_par_pages = 0;
	int ret;

	if (layout->parity && length) {
		unsigned data_devs = layout->group_width - layout->parity;
		unsigned stripe_size = layout->stripe_unit * data_devs;
		unsigned pages_in_unit = layout->stripe_unit / PAGE_SIZE;
		u32 remainder;
		u64 num_stripes;
		u64 num_raid_units;

		num_stripes = div_u64_rem(length, stripe_size, &remainder);
		if (remainder)
			++num_stripes;

		num_raid_units =  num_stripes * layout->parity;

		if (is_reading) {
			/* For reads add per_dev sglist array */
			/* TODO: Raid 6 we need twice more. Actually:
			*         num_stripes / LCMdP(W,P);
			*         if (W%P != 0) num_stripes *= parity;
			*/

			/* first/last seg is split */
			num_raid_units += layout->group_width;
			sgs_per_dev = div_u64(num_raid_units, data_devs);
		} else {
			/* For Writes add parity pages array. */
			max_par_pages = num_raid_units * pages_in_unit *
						sizeof(struct page *);
		}
	}

	ret = _ore_get_io_state(layout, oc, numdevs, sgs_per_dev, max_par_pages,
				pios);
	if (unlikely(ret))
		return ret;

	ios = *pios;
	ios->reading = is_reading;
	ios->offset = offset;

	if (length) {
		ore_calc_stripe_info(layout, offset, length, &ios->si);
		ios->length = ios->si.length;
		ios->nr_pages = (ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
		if (layout->parity)
			_ore_post_alloc_raid_stuff(ios);
	}

	return 0;
}
EXPORT_SYMBOL(ore_get_rw_state);

/* Allocate an io_state for all the devices in the comps array
 *
 * This version of io_state allocation is used mostly by create/remove
 * and trunc where we currently need all the devices. The only wastful
 * bit is the read/write_attributes with no IO. Those sites should
 * be converted to use ore_get_rw_state() with length=0
 */
int  ore_get_io_state(struct ore_layout *layout, struct ore_components *oc,
		      struct ore_io_state **pios)
{
	return _ore_get_io_state(layout, oc, oc->numdevs, 0, 0, pios);
}
EXPORT_SYMBOL(ore_get_io_state);

void ore_put_io_state(struct ore_io_state *ios)
{
	if (ios) {
		unsigned i;

		for (i = 0; i < ios->numdevs; i++) {
			struct ore_per_dev_state *per_dev = &ios->per_dev[i];

			if (per_dev->or)
				osd_end_request(per_dev->or);
			if (per_dev->bio)
				bio_put(per_dev->bio);
		}

		_ore_free_raid_stuff(ios);
		kfree(ios);
	}
}
EXPORT_SYMBOL(ore_put_io_state);

static void _sync_done(struct ore_io_state *ios, void *p)
{
	struct completion *waiting = p;

	complete(waiting);
}

static void _last_io(struct kref *kref)
{
	struct ore_io_state *ios = container_of(
					kref, struct ore_io_state, kref);

	ios->done(ios, ios->private);
}

static void _done_io(struct osd_request *or, void *p)
{
	struct ore_io_state *ios = p;

	kref_put(&ios->kref, _last_io);
}

static int ore_io_execute(struct ore_io_state *ios)
{
	DECLARE_COMPLETION_ONSTACK(wait);
	bool sync = (ios->done == NULL);
	int i, ret;

	if (sync) {
		ios->done = _sync_done;
		ios->private = &wait;
	}

	for (i = 0; i < ios->numdevs; i++) {
		struct osd_request *or = ios->per_dev[i].or;
		if (unlikely(!or))
			continue;

		ret = osd_finalize_request(or, 0, _ios_cred(ios, i), NULL);
		if (unlikely(ret)) {
			ORE_DBGMSG("Failed to osd_finalize_request() => %d\n",
				     ret);
			return ret;
		}
	}

	kref_init(&ios->kref);

	for (i = 0; i < ios->numdevs; i++) {
		struct osd_request *or = ios->per_dev[i].or;
		if (unlikely(!or))
			continue;

		kref_get(&ios->kref);
		osd_execute_request_async(or, _done_io, ios);
	}

	kref_put(&ios->kref, _last_io);
	ret = 0;

	if (sync) {
		wait_for_completion(&wait);
		ret = ore_check_io(ios, NULL);
	}
	return ret;
}

static void _clear_bio(struct bio *bio)
{
	struct bio_vec *bv;
	unsigned i;

	__bio_for_each_segment(bv, bio, i, 0) {
		unsigned this_count = bv->bv_len;

		if (likely(PAGE_SIZE == this_count))
			clear_highpage(bv->bv_page);
		else
			zero_user(bv->bv_page, bv->bv_offset, this_count);
	}
}

int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error)
{
	enum osd_err_priority acumulated_osd_err = 0;
	int acumulated_lin_err = 0;
	int i;

	for (i = 0; i < ios->numdevs; i++) {
		struct osd_sense_info osi;
		struct ore_per_dev_state *per_dev = &ios->per_dev[i];
		struct osd_request *or = per_dev->or;
		int ret;

		if (unlikely(!or))
			continue;

		ret = osd_req_decode_sense(or, &osi);
		if (likely(!ret))
			continue;

		if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) {
			/* start read offset passed endof file */
			_clear_bio(per_dev->bio);
			ORE_DBGMSG("start read offset passed end of file "
				"offset=0x%llx, length=0x%llx\n",
				_LLU(per_dev->offset),
				_LLU(per_dev->length));

			continue; /* we recovered */
		}

		if (on_dev_error) {
			u64 residual = ios->reading ?
					or->in.residual : or->out.residual;
			u64 offset = (ios->offset + ios->length) - residual;
			struct ore_dev *od = ios->oc->ods[
					per_dev->dev - ios->oc->first_dev];

			on_dev_error(ios, od, per_dev->dev, osi.osd_err_pri,
				     offset, residual);
		}
		if (osi.osd_err_pri >= acumulated_osd_err) {
			acumulated_osd_err = osi.osd_err_pri;
			acumulated_lin_err = ret;
		}
	}

	return acumulated_lin_err;
}
EXPORT_SYMBOL(ore_check_io);

/*
 * L - logical offset into the file
 *
 * D - number of Data devices
 *	D = group_width - parity
 *
 * U - The number of bytes in a stripe within a group
 *	U =  stripe_unit * D
 *
 * T - The number of bytes striped within a group of component objects
 *     (before advancing to the next group)
 *	T = U * group_depth
 *
 * S - The number of bytes striped across all component objects
 *     before the pattern repeats
 *	S = T * group_count
 *
 * M - The "major" (i.e., across all components) cycle number
 *	M = L / S
 *
 * G - Counts the groups from the beginning of the major cycle
 *	G = (L - (M * S)) / T	[or (L % S) / T]
 *
 * H - The byte offset within the group
 *	H = (L - (M * S)) % T	[or (L % S) % T]
 *
 * N - The "minor" (i.e., across the group) stripe number
 *	N = H / U
 *
 * C - The component index coresponding to L
 *
 *	C = (H - (N * U)) / stripe_unit + G * D
 *	[or (L % U) / stripe_unit + G * D]
 *
 * O - The component offset coresponding to L
 *	O = L % stripe_unit + N * stripe_unit + M * group_depth * stripe_unit
 *
 * LCMdP – Parity cycle: Lowest Common Multiple of group_width, parity
 *          divide by parity
 *	LCMdP = lcm(group_width, parity) / parity
 *
 * R - The parity Rotation stripe
 *     (Note parity cycle always starts at a group's boundary)
 *	R = N % LCMdP
 *
 * I = the first parity device index
 *	I = (group_width + group_width - R*parity - parity) % group_width
 *
 * Craid - The component index Rotated
 *	Craid = (group_width + C - R*parity) % group_width
 *      (We add the group_width to avoid negative numbers modulo math)
 */
void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
			  u64 length, struct ore_striping_info *si)
{
	u32	stripe_unit = layout->stripe_unit;
	u32	group_width = layout->group_width;
	u64	group_depth = layout->group_depth;
	u32	parity      = layout->parity;

	u32	D = group_width - parity;
	u32	U = D * stripe_unit;
	u64	T = U * group_depth;
	u64	S = T * layout->group_count;
	u64	M = div64_u64(file_offset, S);

	/*
	G = (L - (M * S)) / T
	H = (L - (M * S)) % T
	*/
	u64	LmodS = file_offset - M * S;
	u32	G = div64_u64(LmodS, T);
	u64	H = LmodS - G * T;

	u32	N = div_u64(H, U);

	/* "H - (N * U)" is just "H % U" so it's bound to u32 */
	u32	C = (u32)(H - (N * U)) / stripe_unit + G * group_width;

	div_u64_rem(file_offset, stripe_unit, &si->unit_off);

	si->obj_offset = si->unit_off + (N * stripe_unit) +
				  (M * group_depth * stripe_unit);

	if (parity) {
		u32 LCMdP = lcm(group_width, parity) / parity;
		/* R     = N % LCMdP; */
		u32 RxP   = (N % LCMdP) * parity;
		u32 first_dev = C - C % group_width;

		si->par_dev = (group_width + group_width - parity - RxP) %
			      group_width + first_dev;
		si->dev = (group_width + C - RxP) % group_width + first_dev;
		si->bytes_in_stripe = U;
		si->first_stripe_start = M * S + G * T + N * U;
	} else {
		/* Make the math correct see _prepare_one_group */
		si->par_dev = group_width;
		si->dev = C;
	}

	si->dev *= layout->mirrors_p1;
	si->par_dev *= layout->mirrors_p1;
	si->offset = file_offset;
	si->length = T - H;
	if (si->length > length)
		si->length = length;
	si->M = M;
}
EXPORT_SYMBOL(ore_calc_stripe_info);

int _ore_add_stripe_unit(struct ore_io_state *ios,  unsigned *cur_pg,
			 unsigned pgbase, struct page **pages,
			 struct ore_per_dev_state *per_dev, int cur_len)
{
	unsigned pg = *cur_pg;
	struct request_queue *q =
			osd_request_queue(_ios_od(ios, per_dev->dev));
	unsigned len = cur_len;
	int ret;

	if (per_dev->bio == NULL) {
		unsigned pages_in_stripe = ios->layout->group_width *
					(ios->layout->stripe_unit / PAGE_SIZE);
		unsigned nr_pages = ios->nr_pages * ios->layout->group_width /
					(ios->layout->group_width -
					 ios->layout->parity);
		unsigned bio_size = (nr_pages + pages_in_stripe) /
					ios->layout->group_width;

		per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
		if (unlikely(!per_dev->bio)) {
			ORE_DBGMSG("Failed to allocate BIO size=%u\n",
				     bio_size);
			ret = -ENOMEM;
			goto out;
		}
	}

	while (cur_len > 0) {
		unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len);
		unsigned added_len;

		cur_len -= pglen;

		added_len = bio_add_pc_page(q, per_dev->bio, pages[pg],
					    pglen, pgbase);
		if (unlikely(pglen != added_len)) {
			ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=%u\n",
				   per_dev->bio->bi_vcnt);
			ret = -ENOMEM;
			goto out;
		}
		pgbase = 0;
		++pg;
	}
	BUG_ON(cur_len);

	per_dev->length += len;
	*cur_pg = pg;
	ret = 0;
out:	/* we fail the complete unit on an error eg don't advance
	 * per_dev->length and cur_pg. This means that we might have a bigger
	 * bio than the CDB requested length (per_dev->length). That's fine
	 * only the oposite is fatal.
	 */
	return ret;
}

static int _prepare_for_striping(struct ore_io_state *ios)
{
	struct ore_striping_info *si = &ios->si;
	unsigned stripe_unit = ios->layout->stripe_unit;
	unsigned mirrors_p1 = ios->layout->mirrors_p1;
	unsigned group_width = ios->layout->group_width;
	unsigned devs_in_group = group_width * mirrors_p1;
	unsigned dev = si->dev;
	unsigned first_dev = dev - (dev % devs_in_group);
	unsigned dev_order;
	unsigned cur_pg = ios->pages_consumed;
	u64 length = ios->length;
	int ret = 0;

	if (!ios->pages) {
		ios->numdevs = ios->layout->mirrors_p1;
		return 0;
	}

	BUG_ON(length > si->length);

	dev_order = _dev_order(devs_in_group, mirrors_p1, si->par_dev, dev);
	si->cur_comp = dev_order;

	while (length) {
		unsigned comp = dev - first_dev;
		struct ore_per_dev_state *per_dev = &ios->per_dev[comp];
		unsigned cur_len, page_off = 0;

		if (!per_dev->length) {
			per_dev->dev = dev;
			if (dev == si->dev) {
				WARN_ON(dev == si->par_dev);
				per_dev->offset = si->obj_offset;
				cur_len = stripe_unit - si->unit_off;
				page_off = si->unit_off & ~PAGE_MASK;
				BUG_ON(page_off && (page_off != ios->pgbase));
			} else {
				if (si->cur_comp > dev_order)
					per_dev->offset =
						si->obj_offset - si->unit_off;
				else /* si->cur_comp < dev_order */
					per_dev->offset =
						si->obj_offset + stripe_unit -
								   si->unit_off;
				cur_len = stripe_unit;
			}
		} else {
			cur_len = stripe_unit;
		}
		if (cur_len >= length)
			cur_len = length;

		ret = _ore_add_stripe_unit(ios, &cur_pg, page_off, ios->pages,
					   per_dev, cur_len);
		if (unlikely(ret))
			goto out;

		dev += mirrors_p1;
		dev = (dev % devs_in_group) + first_dev;

		length -= cur_len;

		si->cur_comp = (si->cur_comp + 1) % group_width;
		if (unlikely((dev == si->par_dev) ||
			     (!length && ios->parity_pages))) {
			if (!length)
				/* If we are writing and this is the very last
				 * stripe. then operate on parity dev.
				 */
				dev = si->par_dev;
			if (ios->reading)
				/* In writes cur_len just means if it's the
				 * last one. See _ore_add_parity_unit.
				 */
				cur_len = length;
			per_dev = &ios->per_dev[dev - first_dev];
			if (!per_dev->length) {
				/* Only/always the parity unit of the first
				 * stripe will be empty. So this is a chance to
				 * initialize the per_dev info.
				 */
				per_dev->dev = dev;
				per_dev->offset = si->obj_offset - si->unit_off;
			}

			ret = _ore_add_parity_unit(ios, si, per_dev, cur_len);
			if (unlikely(ret))
					goto out;

			/* Rotate next par_dev backwards with wraping */
			si->par_dev = (devs_in_group + si->par_dev -
				       ios->layout->parity * mirrors_p1) %
				      devs_in_group + first_dev;
			/* Next stripe, start fresh */
			si->cur_comp = 0;
		}
	}
out:
	ios->numdevs = devs_in_group;
	ios->pages_consumed = cur_pg;
	if (unlikely(ret)) {
		if (length == ios->length)
			return ret;
		else
			ios->length -= length;
	}
	return 0;
}

int ore_create(struct ore_io_state *ios)
{
	int i, ret;

	for (i = 0; i < ios->oc->numdevs; i++) {
		struct osd_request *or;

		or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
		if (unlikely(!or)) {
			ORE_ERR("%s: osd_start_request failed\n", __func__);
			ret = -ENOMEM;
			goto out;
		}
		ios->per_dev[i].or = or;
		ios->numdevs++;

		osd_req_create_object(or, _ios_obj(ios, i));
	}
	ret = ore_io_execute(ios);

out:
	return ret;
}
EXPORT_SYMBOL(ore_create);

int ore_remove(struct ore_io_state *ios)
{
	int i, ret;

	for (i = 0; i < ios->oc->numdevs; i++) {
		struct osd_request *or;

		or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
		if (unlikely(!or)) {
			ORE_ERR("%s: osd_start_request failed\n", __func__);
			ret = -ENOMEM;
			goto out;
		}
		ios->per_dev[i].or = or;
		ios->numdevs++;

		osd_req_remove_object(or, _ios_obj(ios, i));
	}
	ret = ore_io_execute(ios);

out:
	return ret;
}
EXPORT_SYMBOL(ore_remove);

static int _write_mirror(struct ore_io_state *ios, int cur_comp)
{
	struct ore_per_dev_state *master_dev = &ios->per_dev[cur_comp];
	unsigned dev = ios->per_dev[cur_comp].dev;
	unsigned last_comp = cur_comp + ios->layout->mirrors_p1;
	int ret = 0;

	if (ios->pages && !master_dev->length)
		return 0; /* Just an empty slot */

	for (; cur_comp < last_comp; ++cur_comp, ++dev) {
		struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp];
		struct osd_request *or;

		or = osd_start_request(_ios_od(ios, dev), GFP_KERNEL);
		if (unlikely(!or)) {
			ORE_ERR("%s: osd_start_request failed\n", __func__);
			ret = -ENOMEM;
			goto out;
		}
		per_dev->or = or;

		if (ios->pages) {
			struct bio *bio;

			if (per_dev != master_dev) {
				bio = bio_kmalloc(GFP_KERNEL,
						  master_dev->bio->bi_max_vecs);
				if (unlikely(!bio)) {
					ORE_DBGMSG(
					      "Failed to allocate BIO size=%u\n",
					      master_dev->bio->bi_max_vecs);
					ret = -ENOMEM;
					goto out;
				}

				__bio_clone(bio, master_dev->bio);
				bio->bi_bdev = NULL;
				bio->bi_next = NULL;
				per_dev->offset = master_dev->offset;
				per_dev->length = master_dev->length;
				per_dev->bio =  bio;
				per_dev->dev = dev;
			} else {
				bio = master_dev->bio;
				/* FIXME: bio_set_dir() */
				bio->bi_rw |= REQ_WRITE;
			}

			osd_req_write(or, _ios_obj(ios, dev), per_dev->offset,
				      bio, per_dev->length);
			ORE_DBGMSG("write(0x%llx) offset=0x%llx "
				      "length=0x%llx dev=%d\n",
				     _LLU(_ios_obj(ios, dev)->id),
				     _LLU(per_dev->offset),
				     _LLU(per_dev->length), dev);
		} else if (ios->kern_buff) {
			per_dev->offset = ios->si.obj_offset;
			per_dev->dev = ios->si.dev + dev;

			/* no cross device without page array */
			BUG_ON((ios->layout->group_width > 1) &&
			       (ios->si.unit_off + ios->length >
				ios->layout->stripe_unit));

			ret = osd_req_write_kern(or, _ios_obj(ios, per_dev->dev),
						 per_dev->offset,
						 ios->kern_buff, ios->length);
			if (unlikely(ret))
				goto out;
			ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx "
				      "length=0x%llx dev=%d\n",
				     _LLU(_ios_obj(ios, dev)->id),
				     _LLU(per_dev->offset),
				     _LLU(ios->length), per_dev->dev);
		} else {
			osd_req_set_attributes(or, _ios_obj(ios, dev));
			ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n",
				     _LLU(_ios_obj(ios, dev)->id),
				     ios->out_attr_len, dev);
		}

		if (ios->out_attr)
			osd_req_add_set_attr_list(or, ios->out_attr,
						  ios->out_attr_len);

		if (ios->in_attr)
			osd_req_add_get_attr_list(or, ios->in_attr,
						  ios->in_attr_len);
	}

out:
	return ret;
}

int ore_write(struct ore_io_state *ios)
{
	int i;
	int ret;

	ret = _prepare_for_striping(ios);
	if (unlikely(ret))
		return ret;

	for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
		ret = _write_mirror(ios, i);
		if (unlikely(ret))
			return ret;
	}

	ret = ore_io_execute(ios);
	return ret;
}
EXPORT_SYMBOL(ore_write);

static int _read_mirror(struct ore_io_state *ios, unsigned cur_comp)
{
	struct osd_request *or;
	struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp];
	struct osd_obj_id *obj = _ios_obj(ios, cur_comp);
	unsigned first_dev = (unsigned)obj->id;

	if (ios->pages && !per_dev->length)
		return 0; /* Just an empty slot */

	first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1;
	or = osd_start_request(_ios_od(ios, first_dev), GFP_KERNEL);
	if (unlikely(!or)) {
		ORE_ERR("%s: osd_start_request failed\n", __func__);
		return -ENOMEM;
	}
	per_dev->or = or;

	if (ios->pages) {
		if (per_dev->cur_sg) {
			/* finalize the last sg_entry */
			_ore_add_sg_seg(per_dev, 0, false);
			if (unlikely(!per_dev->cur_sg))
				return 0; /* Skip parity only device */

			osd_req_read_sg(or, obj, per_dev->bio,
					per_dev->sglist, per_dev->cur_sg);
		} else {
			/* The no raid case */
			osd_req_read(or, obj, per_dev->offset,
				     per_dev->bio, per_dev->length);
		}

		ORE_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx"
			     " dev=%d sg_len=%d\n", _LLU(obj->id),
			     _LLU(per_dev->offset), _LLU(per_dev->length),
			     first_dev, per_dev->cur_sg);
	} else {
		BUG_ON(ios->kern_buff);

		osd_req_get_attributes(or, obj);
		ORE_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n",
			      _LLU(obj->id),
			      ios->in_attr_len, first_dev);
	}
	if (ios->out_attr)
		osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len);

	if (ios->in_attr)
		osd_req_add_get_attr_list(or, ios->in_attr, ios->in_attr_len);

	return 0;
}

int ore_read(struct ore_io_state *ios)
{
	int i;
	int ret;

	ret = _prepare_for_striping(ios);
	if (unlikely(ret))
		return ret;

	for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
		ret = _read_mirror(ios, i);
		if (unlikely(ret))
			return ret;
	}

	ret = ore_io_execute(ios);
	return ret;
}
EXPORT_SYMBOL(ore_read);

int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr)
{
	struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */
	void *iter = NULL;
	int nelem;

	do {
		nelem = 1;
		osd_req_decode_get_attr_list(ios->per_dev[0].or,
					     &cur_attr, &nelem, &iter);
		if ((cur_attr.attr_page == attr->attr_page) &&
		    (cur_attr.attr_id == attr->attr_id)) {
			attr->len = cur_attr.len;
			attr->val_ptr = cur_attr.val_ptr;
			return 0;
		}
	} while (iter);

	return -EIO;
}
EXPORT_SYMBOL(extract_attr_from_ios);

static int _truncate_mirrors(struct ore_io_state *ios, unsigned cur_comp,
			     struct osd_attr *attr)
{
	int last_comp = cur_comp + ios->layout->mirrors_p1;

	for (; cur_comp < last_comp; ++cur_comp) {
		struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp];
		struct osd_request *or;

		or = osd_start_request(_ios_od(ios, cur_comp), GFP_KERNEL);
		if (unlikely(!or)) {
			ORE_ERR("%s: osd_start_request failed\n", __func__);
			return -ENOMEM;
		}
		per_dev->or = or;

		osd_req_set_attributes(or, _ios_obj(ios, cur_comp));
		osd_req_add_set_attr_list(or, attr, 1);
	}

	return 0;
}

struct _trunc_info {
	struct ore_striping_info si;
	u64 prev_group_obj_off;
	u64 next_group_obj_off;

	unsigned first_group_dev;
	unsigned nex_group_dev;
};

static void _calc_trunk_info(struct ore_layout *layout, u64 file_offset,
			     struct _trunc_info *ti)
{
	unsigned stripe_unit = layout->stripe_unit;

	ore_calc_stripe_info(layout, file_offset, 0, &ti->si);

	ti->prev_group_obj_off = ti->si.M * stripe_unit;
	ti->next_group_obj_off = ti->si.M ? (ti->si.M - 1) * stripe_unit : 0;

	ti->first_group_dev = ti->si.dev - (ti->si.dev % layout->group_width);
	ti->nex_group_dev = ti->first_group_dev + layout->group_width;
}

int ore_truncate(struct ore_layout *layout, struct ore_components *oc,
		   u64 size)
{
	struct ore_io_state *ios;
	struct exofs_trunc_attr {
		struct osd_attr attr;
		__be64 newsize;
	} *size_attrs;
	struct _trunc_info ti;
	int i, ret;

	ret = ore_get_io_state(layout, oc, &ios);
	if (unlikely(ret))
		return ret;

	_calc_trunk_info(ios->layout, size, &ti);

	size_attrs = kcalloc(ios->oc->numdevs, sizeof(*size_attrs),
			     GFP_KERNEL);
	if (unlikely(!size_attrs)) {
		ret = -ENOMEM;
		goto out;
	}

	ios->numdevs = ios->oc->numdevs;

	for (i = 0; i < ios->numdevs; ++i) {
		struct exofs_trunc_attr *size_attr = &size_attrs[i];
		u64 obj_size;

		if (i < ti.first_group_dev)
			obj_size = ti.prev_group_obj_off;
		else if (i >= ti.nex_group_dev)
			obj_size = ti.next_group_obj_off;
		else if (i < ti.si.dev) /* dev within this group */
			obj_size = ti.si.obj_offset +
				      ios->layout->stripe_unit - ti.si.unit_off;
		else if (i == ti.si.dev)
			obj_size = ti.si.obj_offset;
		else /* i > ti.dev */
			obj_size = ti.si.obj_offset - ti.si.unit_off;

		size_attr->newsize = cpu_to_be64(obj_size);
		size_attr->attr = g_attr_logical_length;
		size_attr->attr.val_ptr = &size_attr->newsize;

		ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
			     _LLU(oc->comps->obj.id), _LLU(obj_size), i);
		ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
					&size_attr->attr);
		if (unlikely(ret))
			goto out;
	}
	ret = ore_io_execute(ios);

out:
	kfree(size_attrs);
	ore_put_io_state(ios);
	return ret;
}
EXPORT_SYMBOL(ore_truncate);

const struct osd_attr g_attr_logical_length = ATTR_DEF(
	OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
EXPORT_SYMBOL(g_attr_logical_length);
