1bdad60633
There are several reasons why this is undesirable: 1. It never happens during normal operation anyway 2. If it does happen it causes performance to be very, very poor 3. It isn't likely to solve the original problem (memory shortage on remote DLM node) it was supposed to solve 4. It uses a bunch of arbitrary constants which are unlikely to be correct for any particular situation and for which the tuning seems to be a black art. 5. In an N node cluster, only 1/N of the dropped locked will actually contribute to solving the problem on average. So all in all we are better off without it. This also makes merging the lock_dlm module into GFS2 a bit easier. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
212 lines
5.1 KiB
C
212 lines
5.1 KiB
C
/*
|
|
* 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);
|
|
}
|
|
|