/*
 * Copyright (C) 2005, 2006
 * Avishay Traeger (avishay@gmail.com)
 * Copyright (C) 2008, 2009
 * Boaz Harrosh <ooo@electrozaur.com>
 *
 * Copyrights for code taken from ext2:
 *     Copyright (C) 1992, 1993, 1994, 1995
 *     Remy Card (card@masi.ibp.fr)
 *     Laboratoire MASI - Institut Blaise Pascal
 *     Universite Pierre et Marie Curie (Paris VI)
 *     from
 *     linux/fs/minix/inode.c
 *     Copyright (C) 1991, 1992  Linus Torvalds
 *
 * 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/string.h>
#include <linux/parser.h>
#include <linux/vfs.h>
#include <linux/random.h>
#include <linux/module.h>
#include <linux/exportfs.h>
#include <linux/slab.h>
#include <linux/iversion.h>

#include "exofs.h"

#define EXOFS_DBGMSG2(M...) do {} while (0)

/******************************************************************************
 * MOUNT OPTIONS
 *****************************************************************************/

/*
 * struct to hold what we get from mount options
 */
struct exofs_mountopt {
	bool is_osdname;
	const char *dev_name;
	uint64_t pid;
	int timeout;
};

/*
 * exofs-specific mount-time options.
 */
enum { Opt_name, Opt_pid, Opt_to, Opt_err };

/*
 * Our mount-time options.  These should ideally be 64-bit unsigned, but the
 * kernel's parsing functions do not currently support that.  32-bit should be
 * sufficient for most applications now.
 */
static match_table_t tokens = {
	{Opt_name, "osdname=%s"},
	{Opt_pid, "pid=%u"},
	{Opt_to, "to=%u"},
	{Opt_err, NULL}
};

/*
 * The main option parsing method.  Also makes sure that all of the mandatory
 * mount options were set.
 */
static int parse_options(char *options, struct exofs_mountopt *opts)
{
	char *p;
	substring_t args[MAX_OPT_ARGS];
	int option;
	bool s_pid = false;

	EXOFS_DBGMSG("parse_options %s\n", options);
	/* defaults */
	memset(opts, 0, sizeof(*opts));
	opts->timeout = BLK_DEFAULT_SG_TIMEOUT;

	while ((p = strsep(&options, ",")) != NULL) {
		int token;
		char str[32];

		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_name:
			kfree(opts->dev_name);
			opts->dev_name = match_strdup(&args[0]);
			if (unlikely(!opts->dev_name)) {
				EXOFS_ERR("Error allocating dev_name");
				return -ENOMEM;
			}
			opts->is_osdname = true;
			break;
		case Opt_pid:
			if (0 == match_strlcpy(str, &args[0], sizeof(str)))
				return -EINVAL;
			opts->pid = simple_strtoull(str, NULL, 0);
			if (opts->pid < EXOFS_MIN_PID) {
				EXOFS_ERR("Partition ID must be >= %u",
					  EXOFS_MIN_PID);
				return -EINVAL;
			}
			s_pid = 1;
			break;
		case Opt_to:
			if (match_int(&args[0], &option))
				return -EINVAL;
			if (option <= 0) {
				EXOFS_ERR("Timeout must be > 0");
				return -EINVAL;
			}
			opts->timeout = option * HZ;
			break;
		}
	}

	if (!s_pid) {
		EXOFS_ERR("Need to specify the following options:\n");
		EXOFS_ERR("    -o pid=pid_no_to_use\n");
		return -EINVAL;
	}

	return 0;
}

/******************************************************************************
 * INODE CACHE
 *****************************************************************************/

/*
 * Our inode cache.  Isn't it pretty?
 */
static struct kmem_cache *exofs_inode_cachep;

/*
 * Allocate an inode in the cache
 */
static struct inode *exofs_alloc_inode(struct super_block *sb)
{
	struct exofs_i_info *oi;

	oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
	if (!oi)
		return NULL;

	inode_set_iversion(&oi->vfs_inode, 1);
	return &oi->vfs_inode;
}

static void exofs_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
}

/*
 * Remove an inode from the cache
 */
static void exofs_destroy_inode(struct inode *inode)
{
	call_rcu(&inode->i_rcu, exofs_i_callback);
}

/*
 * Initialize the inode
 */
static void exofs_init_once(void *foo)
{
	struct exofs_i_info *oi = foo;

	inode_init_once(&oi->vfs_inode);
}

/*
 * Create and initialize the inode cache
 */
static int init_inodecache(void)
{
	exofs_inode_cachep = kmem_cache_create_usercopy("exofs_inode_cache",
				sizeof(struct exofs_i_info), 0,
				SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD |
				SLAB_ACCOUNT,
				offsetof(struct exofs_i_info, i_data),
				sizeof_field(struct exofs_i_info, i_data),
				exofs_init_once);
	if (exofs_inode_cachep == NULL)
		return -ENOMEM;
	return 0;
}

/*
 * Destroy the inode cache
 */
static void destroy_inodecache(void)
{
	/*
	 * Make sure all delayed rcu free inodes are flushed before we
	 * destroy cache.
	 */
	rcu_barrier();
	kmem_cache_destroy(exofs_inode_cachep);
}

/******************************************************************************
 * Some osd helpers
 *****************************************************************************/
void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
{
	osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
}

static int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
		    u64 offset, void *p, unsigned length)
{
	struct osd_request *or = osd_start_request(od);
/*	struct osd_sense_info osi = {.key = 0};*/
	int ret;

	if (unlikely(!or)) {
		EXOFS_DBGMSG("%s: osd_start_request failed.\n", __func__);
		return -ENOMEM;
	}
	ret = osd_req_read_kern(or, obj, offset, p, length);
	if (unlikely(ret)) {
		EXOFS_DBGMSG("%s: osd_req_read_kern failed.\n", __func__);
		goto out;
	}

	ret = osd_finalize_request(or, 0, cred, NULL);
	if (unlikely(ret)) {
		EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", ret);
		goto out;
	}

	ret = osd_execute_request(or);
	if (unlikely(ret))
		EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
	/* osd_req_decode_sense(or, ret); */

out:
	osd_end_request(or);
	EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx "
		      "length=0x%llx dev=%p ret=>%d\n",
		      _LLU(obj->id), _LLU(offset), _LLU(length), od, ret);
	return ret;
}

static const struct osd_attr g_attr_sb_stats = ATTR_DEF(
	EXOFS_APAGE_SB_DATA,
	EXOFS_ATTR_SB_STATS,
	sizeof(struct exofs_sb_stats));

static int __sbi_read_stats(struct exofs_sb_info *sbi)
{
	struct osd_attr attrs[] = {
		[0] = g_attr_sb_stats,
	};
	struct ore_io_state *ios;
	int ret;

	ret = ore_get_io_state(&sbi->layout, &sbi->oc, &ios);
	if (unlikely(ret)) {
		EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__);
		return ret;
	}

	ios->in_attr = attrs;
	ios->in_attr_len = ARRAY_SIZE(attrs);

	ret = ore_read(ios);
	if (unlikely(ret)) {
		EXOFS_ERR("Error reading super_block stats => %d\n", ret);
		goto out;
	}

	ret = extract_attr_from_ios(ios, &attrs[0]);
	if (ret) {
		EXOFS_ERR("%s: extract_attr of sb_stats failed\n", __func__);
		goto out;
	}
	if (attrs[0].len) {
		struct exofs_sb_stats *ess;

		if (unlikely(attrs[0].len != sizeof(*ess))) {
			EXOFS_ERR("%s: Wrong version of exofs_sb_stats "
				  "size(%d) != expected(%zd)\n",
				  __func__, attrs[0].len, sizeof(*ess));
			goto out;
		}

		ess = attrs[0].val_ptr;
		sbi->s_nextid = le64_to_cpu(ess->s_nextid);
		sbi->s_numfiles = le32_to_cpu(ess->s_numfiles);
	}

out:
	ore_put_io_state(ios);
	return ret;
}

static void stats_done(struct ore_io_state *ios, void *p)
{
	ore_put_io_state(ios);
	/* Good thanks nothing to do anymore */
}

/* Asynchronously write the stats attribute */
int exofs_sbi_write_stats(struct exofs_sb_info *sbi)
{
	struct osd_attr attrs[] = {
		[0] = g_attr_sb_stats,
	};
	struct ore_io_state *ios;
	int ret;

	ret = ore_get_io_state(&sbi->layout, &sbi->oc, &ios);
	if (unlikely(ret)) {
		EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__);
		return ret;
	}

	sbi->s_ess.s_nextid   = cpu_to_le64(sbi->s_nextid);
	sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles);
	attrs[0].val_ptr = &sbi->s_ess;


	ios->done = stats_done;
	ios->private = sbi;
	ios->out_attr = attrs;
	ios->out_attr_len = ARRAY_SIZE(attrs);

	ret = ore_write(ios);
	if (unlikely(ret)) {
		EXOFS_ERR("%s: ore_write failed.\n", __func__);
		ore_put_io_state(ios);
	}

	return ret;
}

/******************************************************************************
 * SUPERBLOCK FUNCTIONS
 *****************************************************************************/
static const struct super_operations exofs_sops;
static const struct export_operations exofs_export_ops;

/*
 * Write the superblock to the OSD
 */
static int exofs_sync_fs(struct super_block *sb, int wait)
{
	struct exofs_sb_info *sbi;
	struct exofs_fscb *fscb;
	struct ore_comp one_comp;
	struct ore_components oc;
	struct ore_io_state *ios;
	int ret = -ENOMEM;

	fscb = kmalloc(sizeof(*fscb), GFP_KERNEL);
	if (unlikely(!fscb))
		return -ENOMEM;

	sbi = sb->s_fs_info;

	/* NOTE: We no longer dirty the super_block anywhere in exofs. The
	 * reason we write the fscb here on unmount is so we can stay backwards
	 * compatible with fscb->s_version == 1. (What we are not compatible
	 * with is if a new version FS crashed and then we try to mount an old
	 * version). Otherwise the exofs_fscb is read-only from mkfs time. All
	 * the writeable info is set in exofs_sbi_write_stats() above.
	 */

	exofs_init_comps(&oc, &one_comp, sbi, EXOFS_SUPER_ID);

	ret = ore_get_io_state(&sbi->layout, &oc, &ios);
	if (unlikely(ret))
		goto out;

	ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
	memset(fscb, 0, ios->length);
	fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
	fscb->s_numfiles = cpu_to_le64(sbi->s_numfiles);
	fscb->s_magic = cpu_to_le16(sb->s_magic);
	fscb->s_newfs = 0;
	fscb->s_version = EXOFS_FSCB_VER;

	ios->offset = 0;
	ios->kern_buff = fscb;

	ret = ore_write(ios);
	if (unlikely(ret))
		EXOFS_ERR("%s: ore_write failed.\n", __func__);

out:
	EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
	ore_put_io_state(ios);
	kfree(fscb);
	return ret;
}

static void _exofs_print_device(const char *msg, const char *dev_path,
				struct osd_dev *od, u64 pid)
{
	const struct osd_dev_info *odi = osduld_device_info(od);

	printk(KERN_NOTICE "exofs: %s %s osd_name-%s pid-0x%llx\n",
		msg, dev_path ?: "", odi->osdname, _LLU(pid));
}

static void exofs_free_sbi(struct exofs_sb_info *sbi)
{
	unsigned numdevs = sbi->oc.numdevs;

	while (numdevs) {
		unsigned i = --numdevs;
		struct osd_dev *od = ore_comp_dev(&sbi->oc, i);

		if (od) {
			ore_comp_set_dev(&sbi->oc, i, NULL);
			osduld_put_device(od);
		}
	}
	kfree(sbi->oc.ods);
	kfree(sbi);
}

/*
 * This function is called when the vfs is freeing the superblock.  We just
 * need to free our own part.
 */
static void exofs_put_super(struct super_block *sb)
{
	int num_pend;
	struct exofs_sb_info *sbi = sb->s_fs_info;

	/* make sure there are no pending commands */
	for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
	     num_pend = atomic_read(&sbi->s_curr_pending)) {
		wait_queue_head_t wq;

		printk(KERN_NOTICE "%s: !!Pending operations in flight. "
		       "This is a BUG. please report to osd-dev@open-osd.org\n",
		       __func__);
		init_waitqueue_head(&wq);
		wait_event_timeout(wq,
				  (atomic_read(&sbi->s_curr_pending) == 0),
				  msecs_to_jiffies(100));
	}

	_exofs_print_device("Unmounting", NULL, ore_comp_dev(&sbi->oc, 0),
			    sbi->one_comp.obj.partition);

	exofs_sysfs_sb_del(sbi);
	exofs_free_sbi(sbi);
	sb->s_fs_info = NULL;
}

static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
				    struct exofs_device_table *dt)
{
	int ret;

	sbi->layout.stripe_unit =
				le64_to_cpu(dt->dt_data_map.cb_stripe_unit);
	sbi->layout.group_width =
				le32_to_cpu(dt->dt_data_map.cb_group_width);
	sbi->layout.group_depth =
				le32_to_cpu(dt->dt_data_map.cb_group_depth);
	sbi->layout.mirrors_p1  =
				le32_to_cpu(dt->dt_data_map.cb_mirror_cnt) + 1;
	sbi->layout.raid_algorithm  =
				le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);

	ret = ore_verify_layout(numdevs, &sbi->layout);

	EXOFS_DBGMSG("exofs: layout: "
		"num_comps=%u stripe_unit=0x%x group_width=%u "
		"group_depth=0x%llx mirrors_p1=%u raid_algorithm=%u\n",
		numdevs,
		sbi->layout.stripe_unit,
		sbi->layout.group_width,
		_LLU(sbi->layout.group_depth),
		sbi->layout.mirrors_p1,
		sbi->layout.raid_algorithm);
	return ret;
}

static unsigned __ra_pages(struct ore_layout *layout)
{
	const unsigned _MIN_RA = 32; /* min 128K read-ahead */
	unsigned ra_pages = layout->group_width * layout->stripe_unit /
				PAGE_SIZE;
	unsigned max_io_pages = exofs_max_io_pages(layout, ~0);

	ra_pages *= 2; /* two stripes */
	if (ra_pages < _MIN_RA)
		ra_pages = roundup(_MIN_RA, ra_pages / 2);

	if (ra_pages > max_io_pages)
		ra_pages = max_io_pages;

	return ra_pages;
}

/* @odi is valid only as long as @fscb_dev is valid */
static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
			     struct osd_dev_info *odi)
{
	odi->systemid_len = le32_to_cpu(dt_dev->systemid_len);
	if (likely(odi->systemid_len))
		memcpy(odi->systemid, dt_dev->systemid, OSD_SYSTEMID_LEN);

	odi->osdname_len = le32_to_cpu(dt_dev->osdname_len);
	odi->osdname = dt_dev->osdname;

	/* FIXME support long names. Will need a _put function */
	if (dt_dev->long_name_offset)
		return -EINVAL;

	/* Make sure osdname is printable!
	 * mkexofs should give us space for a null-terminator else the
	 * device-table is invalid.
	 */
	if (unlikely(odi->osdname_len >= sizeof(dt_dev->osdname)))
		odi->osdname_len = sizeof(dt_dev->osdname) - 1;
	dt_dev->osdname[odi->osdname_len] = 0;

	/* If it's all zeros something is bad we read past end-of-obj */
	return !(odi->systemid_len || odi->osdname_len);
}

static int __alloc_dev_table(struct exofs_sb_info *sbi, unsigned numdevs,
		      struct exofs_dev **peds)
{
	/* Twice bigger table: See exofs_init_comps() and comment at
	 * exofs_read_lookup_dev_table()
	 */
	const size_t numores = numdevs * 2 - 1;
	struct exofs_dev *eds;
	unsigned i;

	sbi->oc.ods = kzalloc(numores * sizeof(struct ore_dev *) +
			      numdevs * sizeof(struct exofs_dev), GFP_KERNEL);
	if (unlikely(!sbi->oc.ods)) {
		EXOFS_ERR("ERROR: failed allocating Device array[%d]\n",
			  numdevs);
		return -ENOMEM;
	}

	/* Start of allocated struct exofs_dev entries */
	*peds = eds = (void *)sbi->oc.ods[numores];
	/* Initialize pointers into struct exofs_dev */
	for (i = 0; i < numdevs; ++i)
		sbi->oc.ods[i] = &eds[i].ored;
	return 0;
}

static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
				       struct osd_dev *fscb_od,
				       unsigned table_count)
{
	struct ore_comp comp;
	struct exofs_device_table *dt;
	struct exofs_dev *eds;
	unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) +
					     sizeof(*dt);
	unsigned numdevs, i;
	int ret;

	dt = kmalloc(table_bytes, GFP_KERNEL);
	if (unlikely(!dt)) {
		EXOFS_ERR("ERROR: allocating %x bytes for device table\n",
			  table_bytes);
		return -ENOMEM;
	}

	sbi->oc.numdevs = 0;

	comp.obj.partition = sbi->one_comp.obj.partition;
	comp.obj.id = EXOFS_DEVTABLE_ID;
	exofs_make_credential(comp.cred, &comp.obj);

	ret = exofs_read_kern(fscb_od, comp.cred, &comp.obj, 0, dt,
			      table_bytes);
	if (unlikely(ret)) {
		EXOFS_ERR("ERROR: reading device table\n");
		goto out;
	}

	numdevs = le64_to_cpu(dt->dt_num_devices);
	if (unlikely(!numdevs)) {
		ret = -EINVAL;
		goto out;
	}
	WARN_ON(table_count != numdevs);

	ret = _read_and_match_data_map(sbi, numdevs, dt);
	if (unlikely(ret))
		goto out;

	ret = __alloc_dev_table(sbi, numdevs, &eds);
	if (unlikely(ret))
		goto out;
	/* exofs round-robins the device table view according to inode
	 * number. We hold a: twice bigger table hence inodes can point
	 * to any device and have a sequential view of the table
	 * starting at this device. See exofs_init_comps()
	 */
	memcpy(&sbi->oc.ods[numdevs], &sbi->oc.ods[0],
		(numdevs - 1) * sizeof(sbi->oc.ods[0]));

	/* create sysfs subdir under which we put the device table
	 * And cluster layout. A Superblock is identified by the string:
	 *	"dev[0].osdname"_"pid"
	 */
	exofs_sysfs_sb_add(sbi, &dt->dt_dev_table[0]);

	for (i = 0; i < numdevs; i++) {
		struct exofs_fscb fscb;
		struct osd_dev_info odi;
		struct osd_dev *od;

		if (exofs_devs_2_odi(&dt->dt_dev_table[i], &odi)) {
			EXOFS_ERR("ERROR: Read all-zeros device entry\n");
			ret = -EINVAL;
			goto out;
		}

		printk(KERN_NOTICE "Add device[%d]: osd_name-%s\n",
		       i, odi.osdname);

		/* the exofs id is currently the table index */
		eds[i].did = i;

		/* On all devices the device table is identical. The user can
		 * specify any one of the participating devices on the command
		 * line. We always keep them in device-table order.
		 */
		if (fscb_od && osduld_device_same(fscb_od, &odi)) {
			eds[i].ored.od = fscb_od;
			++sbi->oc.numdevs;
			fscb_od = NULL;
			exofs_sysfs_odev_add(&eds[i], sbi);
			continue;
		}

		od = osduld_info_lookup(&odi);
		if (IS_ERR(od)) {
			ret = PTR_ERR(od);
			EXOFS_ERR("ERROR: device requested is not found "
				  "osd_name-%s =>%d\n", odi.osdname, ret);
			goto out;
		}

		eds[i].ored.od = od;
		++sbi->oc.numdevs;

		/* Read the fscb of the other devices to make sure the FS
		 * partition is there.
		 */
		ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb,
				      sizeof(fscb));
		if (unlikely(ret)) {
			EXOFS_ERR("ERROR: Malformed participating device "
				  "error reading fscb osd_name-%s\n",
				  odi.osdname);
			goto out;
		}
		exofs_sysfs_odev_add(&eds[i], sbi);

		/* TODO: verify other information is correct and FS-uuid
		 *	 matches. Benny what did you say about device table
		 *	 generation and old devices?
		 */
	}

out:
	kfree(dt);
	if (unlikely(fscb_od && !ret)) {
			EXOFS_ERR("ERROR: Bad device-table container device not present\n");
			osduld_put_device(fscb_od);
			return -EINVAL;
	}
	return ret;
}

/*
 * Read the superblock from the OSD and fill in the fields
 */
static int exofs_fill_super(struct super_block *sb,
				struct exofs_mountopt *opts,
				struct exofs_sb_info *sbi,
				int silent)
{
	struct inode *root;
	struct osd_dev *od;		/* Master device                 */
	struct exofs_fscb fscb;		/*on-disk superblock info        */
	struct ore_comp comp;
	unsigned table_count;
	int ret;

	/* use mount options to fill superblock */
	if (opts->is_osdname) {
		struct osd_dev_info odi = {.systemid_len = 0};

		odi.osdname_len = strlen(opts->dev_name);
		odi.osdname = (u8 *)opts->dev_name;
		od = osduld_info_lookup(&odi);
		kfree(opts->dev_name);
		opts->dev_name = NULL;
	} else {
		od = osduld_path_lookup(opts->dev_name);
	}
	if (IS_ERR(od)) {
		ret = -EINVAL;
		goto free_sbi;
	}

	/* Default layout in case we do not have a device-table */
	sbi->layout.stripe_unit = PAGE_SIZE;
	sbi->layout.mirrors_p1 = 1;
	sbi->layout.group_width = 1;
	sbi->layout.group_depth = -1;
	sbi->layout.group_count = 1;
	sbi->s_timeout = opts->timeout;

	sbi->one_comp.obj.partition = opts->pid;
	sbi->one_comp.obj.id = 0;
	exofs_make_credential(sbi->one_comp.cred, &sbi->one_comp.obj);
	sbi->oc.single_comp = EC_SINGLE_COMP;
	sbi->oc.comps = &sbi->one_comp;

	/* fill in some other data by hand */
	memset(sb->s_id, 0, sizeof(sb->s_id));
	strcpy(sb->s_id, "exofs");
	sb->s_blocksize = EXOFS_BLKSIZE;
	sb->s_blocksize_bits = EXOFS_BLKSHIFT;
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_max_links = EXOFS_LINK_MAX;
	atomic_set(&sbi->s_curr_pending, 0);
	sb->s_bdev = NULL;
	sb->s_dev = 0;

	comp.obj.partition = sbi->one_comp.obj.partition;
	comp.obj.id = EXOFS_SUPER_ID;
	exofs_make_credential(comp.cred, &comp.obj);

	ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb, sizeof(fscb));
	if (unlikely(ret))
		goto free_sbi;

	sb->s_magic = le16_to_cpu(fscb.s_magic);
	/* NOTE: we read below to be backward compatible with old versions */
	sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
	sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);

	/* make sure what we read from the object store is correct */
	if (sb->s_magic != EXOFS_SUPER_MAGIC) {
		if (!silent)
			EXOFS_ERR("ERROR: Bad magic value\n");
		ret = -EINVAL;
		goto free_sbi;
	}
	if (le32_to_cpu(fscb.s_version) > EXOFS_FSCB_VER) {
		EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n",
			  EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version));
		ret = -EINVAL;
		goto free_sbi;
	}

	/* start generation numbers from a random point */
	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
	spin_lock_init(&sbi->s_next_gen_lock);

	table_count = le64_to_cpu(fscb.s_dev_table_count);
	if (table_count) {
		ret = exofs_read_lookup_dev_table(sbi, od, table_count);
		if (unlikely(ret))
			goto free_sbi;
	} else {
		struct exofs_dev *eds;

		ret = __alloc_dev_table(sbi, 1, &eds);
		if (unlikely(ret))
			goto free_sbi;

		ore_comp_set_dev(&sbi->oc, 0, od);
		sbi->oc.numdevs = 1;
	}

	__sbi_read_stats(sbi);

	/* set up operation vectors */
	ret = super_setup_bdi(sb);
	if (ret) {
		EXOFS_DBGMSG("Failed to super_setup_bdi\n");
		goto free_sbi;
	}
	sb->s_bdi->ra_pages = __ra_pages(&sbi->layout);
	sb->s_fs_info = sbi;
	sb->s_op = &exofs_sops;
	sb->s_export_op = &exofs_export_ops;
	root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
	if (IS_ERR(root)) {
		EXOFS_ERR("ERROR: exofs_iget failed\n");
		ret = PTR_ERR(root);
		goto free_sbi;
	}
	sb->s_root = d_make_root(root);
	if (!sb->s_root) {
		EXOFS_ERR("ERROR: get root inode failed\n");
		ret = -ENOMEM;
		goto free_sbi;
	}

	if (!S_ISDIR(root->i_mode)) {
		dput(sb->s_root);
		sb->s_root = NULL;
		EXOFS_ERR("ERROR: corrupt root inode (mode = %hd)\n",
		       root->i_mode);
		ret = -EINVAL;
		goto free_sbi;
	}

	exofs_sysfs_dbg_print();
	_exofs_print_device("Mounting", opts->dev_name,
			    ore_comp_dev(&sbi->oc, 0),
			    sbi->one_comp.obj.partition);
	return 0;

free_sbi:
	EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
		  opts->dev_name, sbi->one_comp.obj.partition, ret);
	exofs_free_sbi(sbi);
	return ret;
}

/*
 * Set up the superblock (calls exofs_fill_super eventually)
 */
static struct dentry *exofs_mount(struct file_system_type *type,
			  int flags, const char *dev_name,
			  void *data)
{
	struct super_block *s;
	struct exofs_mountopt opts;
	struct exofs_sb_info *sbi;
	int ret;

	ret = parse_options(data, &opts);
	if (ret) {
		kfree(opts.dev_name);
		return ERR_PTR(ret);
	}

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi) {
		kfree(opts.dev_name);
		return ERR_PTR(-ENOMEM);
	}

	s = sget(type, NULL, set_anon_super, flags, NULL);

	if (IS_ERR(s)) {
		kfree(opts.dev_name);
		kfree(sbi);
		return ERR_CAST(s);
	}

	if (!opts.dev_name)
		opts.dev_name = dev_name;


	ret = exofs_fill_super(s, &opts, sbi, flags & SB_SILENT ? 1 : 0);
	if (ret) {
		deactivate_locked_super(s);
		return ERR_PTR(ret);
	}
	s->s_flags |= SB_ACTIVE;
	return dget(s->s_root);
}

/*
 * Return information about the file system state in the buffer.  This is used
 * by the 'df' command, for example.
 */
static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct super_block *sb = dentry->d_sb;
	struct exofs_sb_info *sbi = sb->s_fs_info;
	struct ore_io_state *ios;
	struct osd_attr attrs[] = {
		ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
			OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
		ATTR_DEF(OSD_APAGE_PARTITION_INFORMATION,
			OSD_ATTR_PI_USED_CAPACITY, sizeof(__be64)),
	};
	uint64_t capacity = ULLONG_MAX;
	uint64_t used = ULLONG_MAX;
	int ret;

	ret = ore_get_io_state(&sbi->layout, &sbi->oc, &ios);
	if (ret) {
		EXOFS_DBGMSG("ore_get_io_state failed.\n");
		return ret;
	}

	ios->in_attr = attrs;
	ios->in_attr_len = ARRAY_SIZE(attrs);

	ret = ore_read(ios);
	if (unlikely(ret))
		goto out;

	ret = extract_attr_from_ios(ios, &attrs[0]);
	if (likely(!ret)) {
		capacity = get_unaligned_be64(attrs[0].val_ptr);
		if (unlikely(!capacity))
			capacity = ULLONG_MAX;
	} else
		EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");

	ret = extract_attr_from_ios(ios, &attrs[1]);
	if (likely(!ret))
		used = get_unaligned_be64(attrs[1].val_ptr);
	else
		EXOFS_DBGMSG("exofs_statfs: get used-space failed.\n");

	/* fill in the stats buffer */
	buf->f_type = EXOFS_SUPER_MAGIC;
	buf->f_bsize = EXOFS_BLKSIZE;
	buf->f_blocks = capacity >> 9;
	buf->f_bfree = (capacity - used) >> 9;
	buf->f_bavail = buf->f_bfree;
	buf->f_files = sbi->s_numfiles;
	buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles;
	buf->f_namelen = EXOFS_NAME_LEN;

out:
	ore_put_io_state(ios);
	return ret;
}

static const struct super_operations exofs_sops = {
	.alloc_inode    = exofs_alloc_inode,
	.destroy_inode  = exofs_destroy_inode,
	.write_inode    = exofs_write_inode,
	.evict_inode    = exofs_evict_inode,
	.put_super      = exofs_put_super,
	.sync_fs	= exofs_sync_fs,
	.statfs         = exofs_statfs,
};

/******************************************************************************
 * EXPORT OPERATIONS
 *****************************************************************************/

static struct dentry *exofs_get_parent(struct dentry *child)
{
	unsigned long ino = exofs_parent_ino(child);

	if (!ino)
		return ERR_PTR(-ESTALE);

	return d_obtain_alias(exofs_iget(child->d_sb, ino));
}

static struct inode *exofs_nfs_get_inode(struct super_block *sb,
		u64 ino, u32 generation)
{
	struct inode *inode;

	inode = exofs_iget(sb, ino);
	if (IS_ERR(inode))
		return ERR_CAST(inode);
	if (generation && inode->i_generation != generation) {
		/* we didn't find the right inode.. */
		iput(inode);
		return ERR_PTR(-ESTALE);
	}
	return inode;
}

static struct dentry *exofs_fh_to_dentry(struct super_block *sb,
				struct fid *fid, int fh_len, int fh_type)
{
	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
				    exofs_nfs_get_inode);
}

static struct dentry *exofs_fh_to_parent(struct super_block *sb,
				struct fid *fid, int fh_len, int fh_type)
{
	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
				    exofs_nfs_get_inode);
}

static const struct export_operations exofs_export_ops = {
	.fh_to_dentry = exofs_fh_to_dentry,
	.fh_to_parent = exofs_fh_to_parent,
	.get_parent = exofs_get_parent,
};

/******************************************************************************
 * INSMOD/RMMOD
 *****************************************************************************/

/*
 * struct that describes this file system
 */
static struct file_system_type exofs_type = {
	.owner          = THIS_MODULE,
	.name           = "exofs",
	.mount          = exofs_mount,
	.kill_sb        = generic_shutdown_super,
};
MODULE_ALIAS_FS("exofs");

static int __init init_exofs(void)
{
	int err;

	err = init_inodecache();
	if (err)
		goto out;

	err = register_filesystem(&exofs_type);
	if (err)
		goto out_d;

	/* We don't fail if sysfs creation failed */
	exofs_sysfs_init();

	return 0;
out_d:
	destroy_inodecache();
out:
	return err;
}

static void __exit exit_exofs(void)
{
	exofs_sysfs_uninit();
	unregister_filesystem(&exofs_type);
	destroy_inodecache();
}

MODULE_AUTHOR("Avishay Traeger <avishay@gmail.com>");
MODULE_DESCRIPTION("exofs");
MODULE_LICENSE("GPL");

module_init(init_exofs)
module_exit(exit_exofs)
