/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License version 2.
 */

#include <linux/ctype.h>
#include <linux/stat.h>

#include "lock_dlm.h"

static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name);
}

static ssize_t block_show(struct gdlm_ls *ls, char *buf)
{
	ssize_t ret;
	int val = 0;

	if (test_bit(DFL_BLOCK_LOCKS, &ls->flags))
		val = 1;
	ret = sprintf(buf, "%d\n", val);
	return ret;
}

static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len)
{
	ssize_t ret = len;
	int val;

	val = simple_strtol(buf, NULL, 0);

	if (val == 1)
		set_bit(DFL_BLOCK_LOCKS, &ls->flags);
	else if (val == 0) {
		clear_bit(DFL_BLOCK_LOCKS, &ls->flags);
		gdlm_submit_delayed(ls);
	} else {
		ret = -EINVAL;
	}
	return ret;
}

static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf)
{
	ssize_t ret;
	int val = 0;

	if (test_bit(DFL_WITHDRAW, &ls->flags))
		val = 1;
	ret = sprintf(buf, "%d\n", val);
	return ret;
}

static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len)
{
	ssize_t ret = len;
	int val;

	val = simple_strtol(buf, NULL, 0);

	if (val == 1)
		set_bit(DFL_WITHDRAW, &ls->flags);
	else
		ret = -EINVAL;
	wake_up(&ls->wait_control);
	return ret;
}

static ssize_t id_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%u\n", ls->id);
}

static ssize_t jid_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%d\n", ls->jid);
}

static ssize_t first_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%d\n", ls->first);
}

static ssize_t first_done_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%d\n", ls->first_done);
}

static ssize_t recover_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%d\n", ls->recover_jid);
}

static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len)
{
	ls->recover_jid = simple_strtol(buf, NULL, 0);
	ls->fscb(ls->sdp, LM_CB_NEED_RECOVERY, &ls->recover_jid);
	return len;
}

static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%d\n", ls->recover_jid_done);
}

static ssize_t recover_status_show(struct gdlm_ls *ls, char *buf)
{
	return sprintf(buf, "%d\n", ls->recover_jid_status);
}

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

#define GDLM_ATTR(_name,_mode,_show,_store) \
static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)

GDLM_ATTR(proto_name,     0444, proto_name_show,     NULL);
GDLM_ATTR(block,          0644, block_show,          block_store);
GDLM_ATTR(withdraw,       0644, withdraw_show,       withdraw_store);
GDLM_ATTR(id,             0444, id_show,             NULL);
GDLM_ATTR(jid,            0444, jid_show,            NULL);
GDLM_ATTR(first,          0444, first_show,          NULL);
GDLM_ATTR(first_done,     0444, first_done_show,     NULL);
GDLM_ATTR(recover,        0644, recover_show,        recover_store);
GDLM_ATTR(recover_done,   0444, recover_done_show,   NULL);
GDLM_ATTR(recover_status, 0444, recover_status_show, NULL);

static struct attribute *gdlm_attrs[] = {
	&gdlm_attr_proto_name.attr,
	&gdlm_attr_block.attr,
	&gdlm_attr_withdraw.attr,
	&gdlm_attr_id.attr,
	&gdlm_attr_jid.attr,
	&gdlm_attr_first.attr,
	&gdlm_attr_first_done.attr,
	&gdlm_attr_recover.attr,
	&gdlm_attr_recover_done.attr,
	&gdlm_attr_recover_status.attr,
	NULL,
};

static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr,
			      char *buf)
{
	struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
	struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
	return a->show ? a->show(ls, buf) : 0;
}

static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr,
			       const char *buf, size_t len)
{
	struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
	struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
	return a->store ? a->store(ls, buf, len) : len;
}

static struct sysfs_ops gdlm_attr_ops = {
	.show  = gdlm_attr_show,
	.store = gdlm_attr_store,
};

static struct kobj_type gdlm_ktype = {
	.default_attrs = gdlm_attrs,
	.sysfs_ops     = &gdlm_attr_ops,
};

static struct kset *gdlm_kset;

int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj)
{
	int error;

	ls->kobj.kset = gdlm_kset;
	error = kobject_init_and_add(&ls->kobj, &gdlm_ktype, fskobj,
				     "lock_module");
	if (error)
		log_error("can't register kobj %d", error);
	kobject_uevent(&ls->kobj, KOBJ_ADD);

	return error;
}

void gdlm_kobject_release(struct gdlm_ls *ls)
{
	kobject_put(&ls->kobj);
}

int gdlm_sysfs_init(void)
{
	gdlm_kset = kset_create_and_add("lock_dlm", NULL, kernel_kobj);
	if (!gdlm_kset) {
		printk(KERN_WARNING "%s: can not create kset\n", __func__);
		return -ENOMEM;
	}
	return 0;
}

void gdlm_sysfs_exit(void)
{
	kset_unregister(gdlm_kset);
}

