/*
 * Copyright (C) 2011
 * Boaz Harrosh <ooo@electrozaur.com>
 *
 * Public Declarations of the ORE API
 *
 * This file is part of the ORE (Object Raid Engine) library.
 *
 * ORE is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation. (GPL v2)
 *
 * ORE 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 the ORE; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#ifndef __ORE_H__
#define __ORE_H__

#include <scsi/osd_initiator.h>
#include <scsi/osd_attributes.h>
#include <scsi/osd_sec.h>
#include <linux/pnfs_osd_xdr.h>
#include <linux/bug.h>

struct ore_comp {
	struct osd_obj_id	obj;
	u8			cred[OSD_CAP_LEN];
};

struct ore_layout {
	/* Our way of looking at the data_map */
	enum pnfs_osd_raid_algorithm4
		 raid_algorithm;
	unsigned stripe_unit;
	unsigned mirrors_p1;

	unsigned group_width;
	unsigned parity;
	u64	 group_depth;
	unsigned group_count;

	/* Cached often needed calculations filled in by
	 * ore_verify_layout
	 */
	unsigned long max_io_length;	/* Max length that should be passed to
					 * ore_get_rw_state
					 */
};

struct ore_dev {
	struct osd_dev *od;
};

struct ore_components {
	unsigned	first_dev;		/* First logical device no    */
	unsigned	numdevs;		/* Num of devices in array    */
	/* If @single_comp == EC_SINGLE_COMP, @comps points to a single
	 * component. else there are @numdevs components
	 */
	enum EC_COMP_USAGE {
		EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff
	}		single_comp;
	struct ore_comp	*comps;

	/* Array of pointers to ore_dev-* . User will usually have these pointed
	 * too a bigger struct which contain an "ore_dev ored" member and use
	 * container_of(oc->ods[i], struct foo_dev, ored) to access the bigger
	 * structure.
	 */
	struct ore_dev	**ods;
};

/* ore_comp_dev Recievies a logical device index */
static inline struct osd_dev *ore_comp_dev(
	const struct ore_components *oc, unsigned i)
{
	BUG_ON((i < oc->first_dev) || (oc->first_dev + oc->numdevs <= i));
	return oc->ods[i - oc->first_dev]->od;
}

static inline void ore_comp_set_dev(
	struct ore_components *oc, unsigned i, struct osd_dev *od)
{
	oc->ods[i - oc->first_dev]->od = od;
}

struct ore_striping_info {
	u64 offset;
	u64 obj_offset;
	u64 length;
	u64 first_stripe_start; /* only used in raid writes */
	u64 M; /* for truncate */
	unsigned bytes_in_stripe;
	unsigned dev;
	unsigned par_dev;
	unsigned unit_off;
	unsigned cur_pg;
	unsigned cur_comp;
	unsigned maxdevUnits;
};

struct ore_io_state;
typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private);
struct _ore_r4w_op {
	/* @Priv given here is passed ios->private */
	struct page * (*get_page)(void *priv, u64 page_index, bool *uptodate);
	void (*put_page)(void *priv, struct page *page);
};

struct ore_io_state {
	struct kref		kref;
	struct ore_striping_info si;

	void			*private;
	ore_io_done_fn	done;

	struct ore_layout	*layout;
	struct ore_components	*oc;

	/* Global read/write IO*/
	loff_t			offset;
	unsigned long		length;
	void			*kern_buff;

	struct page		**pages;
	unsigned		nr_pages;
	unsigned		pgbase;
	unsigned		pages_consumed;

	/* Attributes */
	unsigned		in_attr_len;
	struct osd_attr		*in_attr;
	unsigned		out_attr_len;
	struct osd_attr		*out_attr;

	bool			reading;

	/* House keeping of Parity pages */
	bool			extra_part_alloc;
	struct page		**parity_pages;
	unsigned		max_par_pages;
	unsigned		cur_par_page;
	unsigned		sgs_per_dev;
	struct __stripe_pages_2d *sp2d;
	struct ore_io_state	 *ios_read_4_write;
	const struct _ore_r4w_op *r4w;

	/* Variable array of size numdevs */
	unsigned numdevs;
	struct ore_per_dev_state {
		struct osd_request *or;
		struct bio *bio;
		loff_t offset;
		unsigned length;
		unsigned last_sgs_total;
		unsigned dev;
		struct osd_sg_entry *sglist;
		unsigned cur_sg;
	} per_dev[];
};

static inline unsigned ore_io_state_size(unsigned numdevs)
{
	return sizeof(struct ore_io_state) +
		sizeof(struct ore_per_dev_state) * numdevs;
}

/* ore.c */
int ore_verify_layout(unsigned total_comps, struct ore_layout *layout);
void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
			  u64 length, struct ore_striping_info *si);
int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps,
		     bool is_reading, u64 offset, u64 length,
		     struct ore_io_state **ios);
int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps,
		     struct ore_io_state **ios);
void ore_put_io_state(struct ore_io_state *ios);

typedef void (*ore_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);
int ore_check_io(struct ore_io_state *ios, ore_on_dev_error rep);

int ore_create(struct ore_io_state *ios);
int ore_remove(struct ore_io_state *ios);
int ore_write(struct ore_io_state *ios);
int ore_read(struct ore_io_state *ios);
int ore_truncate(struct ore_layout *layout, struct ore_components *comps,
		 u64 size);

int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr);

extern const struct osd_attr g_attr_logical_length;

#endif
