/*
 * Copyright (C) 2012
 * Sachin Bhamare <sbhamare@panasas.com>
 * 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 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);
}
