/*
 * Copyright (C) 2012
 * Sachin Bhamare <sbhamare@panasas.com>
 * Boaz Harrosh <ooo@electrozaur.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 2 as published by
 * the Free Software Foundation.
 *
 * 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 <licensing@fsf.org>
 */

#include <linux/kobject.h>
#include <linux/device.h>

#include "exofs.h"

struct odev_attr {
	struct attribute attr;
	ssize_t (*show)(struct exofs_dev *, char *);
	ssize_t (*store)(struct exofs_dev *, const char *, size_t);
};

static ssize_t odev_attr_show(struct kobject *kobj, struct attribute *attr,
		char *buf)
{
	struct exofs_dev *edp = container_of(kobj, struct exofs_dev, ed_kobj);
	struct odev_attr *a = container_of(attr, struct odev_attr, attr);

	return a->show ? a->show(edp, buf) : 0;
}

static ssize_t odev_attr_store(struct kobject *kobj, struct attribute *attr,
		const char *buf, size_t len)
{
	struct exofs_dev *edp = container_of(kobj, struct exofs_dev, ed_kobj);
	struct odev_attr *a = container_of(attr, struct odev_attr, attr);

	return a->store ? a->store(edp, buf, len) : len;
}

static const struct sysfs_ops odev_attr_ops = {
	.show  = odev_attr_show,
	.store = odev_attr_store,
};


static struct kset *exofs_kset;

static ssize_t osdname_show(struct exofs_dev *edp, char *buf)
{
	struct osd_dev *odev = edp->ored.od;
	const struct osd_dev_info *odi = osduld_device_info(odev);

	return snprintf(buf, odi->osdname_len + 1, "%s", odi->osdname);
}

static ssize_t systemid_show(struct exofs_dev *edp, char *buf)
{
	struct osd_dev *odev = edp->ored.od;
	const struct osd_dev_info *odi = osduld_device_info(odev);

	memcpy(buf, odi->systemid, odi->systemid_len);
	return odi->systemid_len;
}

static ssize_t uri_show(struct exofs_dev *edp, char *buf)
{
	return snprintf(buf, edp->urilen, "%s", edp->uri);
}

static ssize_t uri_store(struct exofs_dev *edp, const char *buf, size_t len)
{
	uint8_t *new_uri;

	edp->urilen = strlen(buf) + 1;
	new_uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
	if (new_uri == NULL)
		return -ENOMEM;
	edp->uri = new_uri;
	strncpy(edp->uri, buf, edp->urilen);
	return edp->urilen;
}

#define OSD_ATTR(name, mode, show, store) \
	static struct odev_attr odev_attr_##name = \
					__ATTR(name, mode, show, store)

OSD_ATTR(osdname, S_IRUGO, osdname_show, NULL);
OSD_ATTR(systemid, S_IRUGO, systemid_show, NULL);
OSD_ATTR(uri, S_IRWXU, uri_show, uri_store);

static struct attribute *odev_attrs[] = {
	&odev_attr_osdname.attr,
	&odev_attr_systemid.attr,
	&odev_attr_uri.attr,
	NULL,
};

static struct kobj_type odev_ktype = {
	.default_attrs	= odev_attrs,
	.sysfs_ops	= &odev_attr_ops,
};

static struct kobj_type uuid_ktype = {
};

void exofs_sysfs_dbg_print(void)
{
#ifdef CONFIG_EXOFS_DEBUG
	struct kobject *k_name, *k_tmp;

	list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) {
		printk(KERN_INFO "%s: name %s ref %d\n",
			__func__, kobject_name(k_name),
			(int)kref_read(&k_name->kref));
	}
#endif
}
/*
 * This function removes all kobjects under exofs_kset
 * At the end of it, exofs_kset kobject will have a refcount
 * of 1 which gets decremented only on exofs module unload
 */
void exofs_sysfs_sb_del(struct exofs_sb_info *sbi)
{
	struct kobject *k_name, *k_tmp;
	struct kobject *s_kobj = &sbi->s_kobj;

	list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) {
		/* Remove all that are children of this SBI */
		if (k_name->parent == s_kobj)
			kobject_put(k_name);
	}
	kobject_put(s_kobj);
}

/*
 * This function creates sysfs entries to hold the current exofs cluster
 * instance (uniquely identified by osdname,pid tuple).
 * This function gets called once per exofs mount instance.
 */
int exofs_sysfs_sb_add(struct exofs_sb_info *sbi,
		       struct exofs_dt_device_info *dt_dev)
{
	struct kobject *s_kobj;
	int retval = 0;
	uint64_t pid = sbi->one_comp.obj.partition;

	/* allocate new uuid dirent */
	s_kobj = &sbi->s_kobj;
	s_kobj->kset = exofs_kset;
	retval = kobject_init_and_add(s_kobj, &uuid_ktype,
			&exofs_kset->kobj,  "%s_%llx", dt_dev->osdname, pid);
	if (retval) {
		EXOFS_ERR("ERROR: Failed to create sysfs entry for "
			  "uuid-%s_%llx => %d\n", dt_dev->osdname, pid, retval);
		return -ENOMEM;
	}
	return 0;
}

int exofs_sysfs_odev_add(struct exofs_dev *edev, struct exofs_sb_info *sbi)
{
	struct kobject *d_kobj;
	int retval = 0;

	/* create osd device group which contains following attributes
	 * osdname, systemid & uri
	 */
	d_kobj = &edev->ed_kobj;
	d_kobj->kset = exofs_kset;
	retval = kobject_init_and_add(d_kobj, &odev_ktype,
			&sbi->s_kobj, "dev%u", edev->did);
	if (retval) {
		EXOFS_ERR("ERROR: Failed to create sysfs entry for "
				"device dev%u\n", edev->did);
		return retval;
	}
	return 0;
}

int exofs_sysfs_init(void)
{
	exofs_kset = kset_create_and_add("exofs", NULL, fs_kobj);
	if (!exofs_kset) {
		EXOFS_ERR("ERROR: kset_create_and_add exofs failed\n");
		return -ENOMEM;
	}
	return 0;
}

void exofs_sysfs_uninit(void)
{
	kset_unregister(exofs_kset);
}
