GFS2: Send some sensible sysfs stuff
[linux-2.6-block.git] / fs / gfs2 / locking / dlm / sysfs.c
CommitLineData
869d81df
DT
1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
e9fc2aa0 7 * of the GNU General Public License version 2.
869d81df 8 */
29b7998d
DT
9
10#include <linux/ctype.h>
11#include <linux/stat.h>
12
13#include "lock_dlm.h"
14
869d81df
DT
15static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf)
16{
17 return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name);
18}
19
20static ssize_t block_show(struct gdlm_ls *ls, char *buf)
29b7998d
DT
21{
22 ssize_t ret;
23 int val = 0;
24
25 if (test_bit(DFL_BLOCK_LOCKS, &ls->flags))
26 val = 1;
27 ret = sprintf(buf, "%d\n", val);
28 return ret;
29}
30
869d81df 31static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len)
29b7998d
DT
32{
33 ssize_t ret = len;
34 int val;
35
36 val = simple_strtol(buf, NULL, 0);
37
38 if (val == 1)
39 set_bit(DFL_BLOCK_LOCKS, &ls->flags);
40 else if (val == 0) {
41 clear_bit(DFL_BLOCK_LOCKS, &ls->flags);
42 gdlm_submit_delayed(ls);
62f140c1 43 } else {
29b7998d 44 ret = -EINVAL;
62f140c1 45 }
29b7998d
DT
46 return ret;
47}
48
869d81df 49static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf)
29b7998d
DT
50{
51 ssize_t ret;
52 int val = 0;
53
54 if (test_bit(DFL_WITHDRAW, &ls->flags))
55 val = 1;
56 ret = sprintf(buf, "%d\n", val);
57 return ret;
58}
59
869d81df 60static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len)
29b7998d
DT
61{
62 ssize_t ret = len;
63 int val;
64
65 val = simple_strtol(buf, NULL, 0);
66
67 if (val == 1)
68 set_bit(DFL_WITHDRAW, &ls->flags);
69 else
70 ret = -EINVAL;
71 wake_up(&ls->wait_control);
72 return ret;
73}
74
869d81df 75static ssize_t id_show(struct gdlm_ls *ls, char *buf)
29b7998d 76{
869d81df 77 return sprintf(buf, "%u\n", ls->id);
29b7998d
DT
78}
79
869d81df 80static ssize_t jid_show(struct gdlm_ls *ls, char *buf)
29b7998d 81{
869d81df 82 return sprintf(buf, "%d\n", ls->jid);
29b7998d
DT
83}
84
869d81df 85static ssize_t first_show(struct gdlm_ls *ls, char *buf)
29b7998d 86{
869d81df 87 return sprintf(buf, "%d\n", ls->first);
29b7998d
DT
88}
89
869d81df 90static ssize_t first_done_show(struct gdlm_ls *ls, char *buf)
29b7998d
DT
91{
92 return sprintf(buf, "%d\n", ls->first_done);
93}
94
869d81df 95static ssize_t recover_show(struct gdlm_ls *ls, char *buf)
29b7998d 96{
869d81df 97 return sprintf(buf, "%d\n", ls->recover_jid);
29b7998d
DT
98}
99
869d81df 100static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len)
29b7998d
DT
101{
102 ls->recover_jid = simple_strtol(buf, NULL, 0);
1c089c32 103 ls->fscb(ls->sdp, LM_CB_NEED_RECOVERY, &ls->recover_jid);
29b7998d
DT
104 return len;
105}
106
869d81df 107static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf)
29b7998d 108{
869d81df 109 return sprintf(buf, "%d\n", ls->recover_jid_done);
29b7998d
DT
110}
111
6bd70aba
DT
112static ssize_t recover_status_show(struct gdlm_ls *ls, char *buf)
113{
114 return sprintf(buf, "%d\n", ls->recover_jid_status);
115}
116
29b7998d
DT
117struct gdlm_attr {
118 struct attribute attr;
119 ssize_t (*show)(struct gdlm_ls *, char *);
120 ssize_t (*store)(struct gdlm_ls *, const char *, size_t);
121};
122
869d81df
DT
123#define GDLM_ATTR(_name,_mode,_show,_store) \
124static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
29b7998d 125
6bd70aba
DT
126GDLM_ATTR(proto_name, 0444, proto_name_show, NULL);
127GDLM_ATTR(block, 0644, block_show, block_store);
128GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store);
129GDLM_ATTR(id, 0444, id_show, NULL);
130GDLM_ATTR(jid, 0444, jid_show, NULL);
131GDLM_ATTR(first, 0444, first_show, NULL);
132GDLM_ATTR(first_done, 0444, first_done_show, NULL);
133GDLM_ATTR(recover, 0644, recover_show, recover_store);
134GDLM_ATTR(recover_done, 0444, recover_done_show, NULL);
135GDLM_ATTR(recover_status, 0444, recover_status_show, NULL);
29b7998d
DT
136
137static struct attribute *gdlm_attrs[] = {
869d81df 138 &gdlm_attr_proto_name.attr,
29b7998d 139 &gdlm_attr_block.attr,
29b7998d 140 &gdlm_attr_withdraw.attr,
869d81df 141 &gdlm_attr_id.attr,
29b7998d
DT
142 &gdlm_attr_jid.attr,
143 &gdlm_attr_first.attr,
144 &gdlm_attr_first_done.attr,
145 &gdlm_attr_recover.attr,
146 &gdlm_attr_recover_done.attr,
6bd70aba 147 &gdlm_attr_recover_status.attr,
29b7998d
DT
148 NULL,
149};
150
151static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr,
152 char *buf)
153{
154 struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
155 struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
156 return a->show ? a->show(ls, buf) : 0;
157}
158
159static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr,
160 const char *buf, size_t len)
161{
162 struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
163 struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
164 return a->store ? a->store(ls, buf, len) : len;
165}
166
167static struct sysfs_ops gdlm_attr_ops = {
168 .show = gdlm_attr_show,
169 .store = gdlm_attr_store,
170};
171
172static struct kobj_type gdlm_ktype = {
173 .default_attrs = gdlm_attrs,
174 .sysfs_ops = &gdlm_attr_ops,
175};
176
136a2750 177static struct kset *gdlm_kset;
29b7998d 178
869d81df 179int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj)
29b7998d
DT
180{
181 int error;
182
136a2750 183 ls->kobj.kset = gdlm_kset;
901195ed
GKH
184 error = kobject_init_and_add(&ls->kobj, &gdlm_ktype, fskobj,
185 "lock_module");
869d81df
DT
186 if (error)
187 log_error("can't register kobj %d", error);
901195ed 188 kobject_uevent(&ls->kobj, KOBJ_ADD);
29b7998d 189
869d81df 190 return error;
29b7998d
DT
191}
192
193void gdlm_kobject_release(struct gdlm_ls *ls)
194{
197b12d6 195 kobject_put(&ls->kobj);
29b7998d
DT
196}
197
fdd1062e
SW
198static int gdlm_uevent(struct kset *kset, struct kobject *kobj,
199 struct kobj_uevent_env *env)
200{
201 struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
202 add_uevent_var(env, "LOCKTABLE=%s:%s", ls->clustername, ls->fsname);
203 add_uevent_var(env, "LOCKPROTO=lock_dlm");
204 return 0;
205}
206
207static struct kset_uevent_ops gdlm_uevent_ops = {
208 .uevent = gdlm_uevent,
209};
210
211
29b7998d
DT
212int gdlm_sysfs_init(void)
213{
fdd1062e 214 gdlm_kset = kset_create_and_add("lock_dlm", &gdlm_uevent_ops, kernel_kobj);
136a2750 215 if (!gdlm_kset) {
8e24eea7 216 printk(KERN_WARNING "%s: can not create kset\n", __func__);
136a2750
GKH
217 return -ENOMEM;
218 }
219 return 0;
29b7998d
DT
220}
221
222void gdlm_sysfs_exit(void)
223{
136a2750 224 kset_unregister(gdlm_kset);
29b7998d
DT
225}
226