/*
 * 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)atomic_read(&k_name->kref.refcount));
	}
#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);
}
