[GFS2] The lock modules for GFS2
[linux-2.6] / fs / gfs2 / locking / dlm / sysfs.c
1 /******************************************************************************
2 *******************************************************************************
3 **
4 **  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
5 **
6 **  This copyrighted material is made available to anyone wishing to use,
7 **  modify, copy, or redistribute it subject to the terms and conditions
8 **  of the GNU General Public License v.2.
9 **
10 *******************************************************************************
11 ******************************************************************************/
12
13 #include <linux/ctype.h>
14 #include <linux/stat.h>
15
16 #include "lock_dlm.h"
17
18 static ssize_t gdlm_block_show(struct gdlm_ls *ls, char *buf)
19 {
20         ssize_t ret;
21         int val = 0;
22
23         if (test_bit(DFL_BLOCK_LOCKS, &ls->flags))
24                 val = 1;
25         ret = sprintf(buf, "%d\n", val);
26         return ret;
27 }
28
29 static ssize_t gdlm_block_store(struct gdlm_ls *ls, const char *buf, size_t len)
30 {
31         ssize_t ret = len;
32         int val;
33
34         val = simple_strtol(buf, NULL, 0);
35
36         if (val == 1)
37                 set_bit(DFL_BLOCK_LOCKS, &ls->flags);
38         else if (val == 0) {
39                 clear_bit(DFL_BLOCK_LOCKS, &ls->flags);
40                 gdlm_submit_delayed(ls);
41         } else
42                 ret = -EINVAL;
43         return ret;
44 }
45
46 static ssize_t gdlm_mounted_show(struct gdlm_ls *ls, char *buf)
47 {
48         ssize_t ret;
49         int val = -2;
50
51         if (test_bit(DFL_TERMINATE, &ls->flags))
52                 val = -1;
53         else if (test_bit(DFL_LEAVE_DONE, &ls->flags))
54                 val = 0;
55         else if (test_bit(DFL_JOIN_DONE, &ls->flags))
56                 val = 1;
57         ret = sprintf(buf, "%d\n", val);
58         return ret;
59 }
60
61 static ssize_t gdlm_mounted_store(struct gdlm_ls *ls, const char *buf, size_t len)
62 {
63         ssize_t ret = len;
64         int val;
65
66         val = simple_strtol(buf, NULL, 0);
67
68         if (val == 1)
69                 set_bit(DFL_JOIN_DONE, &ls->flags);
70         else if (val == 0)
71                 set_bit(DFL_LEAVE_DONE, &ls->flags);
72         else if (val == -1) {
73                 set_bit(DFL_TERMINATE, &ls->flags);
74                 set_bit(DFL_JOIN_DONE, &ls->flags);
75                 set_bit(DFL_LEAVE_DONE, &ls->flags);
76         } else
77                 ret = -EINVAL;
78         wake_up(&ls->wait_control);
79         return ret;
80 }
81
82 static ssize_t gdlm_withdraw_show(struct gdlm_ls *ls, char *buf)
83 {
84         ssize_t ret;
85         int val = 0;
86
87         if (test_bit(DFL_WITHDRAW, &ls->flags))
88                 val = 1;
89         ret = sprintf(buf, "%d\n", val);
90         return ret;
91 }
92
93 static ssize_t gdlm_withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len)
94 {
95         ssize_t ret = len;
96         int val;
97
98         val = simple_strtol(buf, NULL, 0);
99
100         if (val == 1)
101                 set_bit(DFL_WITHDRAW, &ls->flags);
102         else
103                 ret = -EINVAL;
104         wake_up(&ls->wait_control);
105         return ret;
106 }
107
108 static ssize_t gdlm_jid_show(struct gdlm_ls *ls, char *buf)
109 {
110         return sprintf(buf, "%u\n", ls->jid);
111 }
112
113 static ssize_t gdlm_jid_store(struct gdlm_ls *ls, const char *buf, size_t len)
114 {
115         ls->jid = simple_strtol(buf, NULL, 0);
116         return len;
117 }
118
119 static ssize_t gdlm_first_show(struct gdlm_ls *ls, char *buf)
120 {
121         return sprintf(buf, "%u\n", ls->first);
122 }
123
124 static ssize_t gdlm_first_store(struct gdlm_ls *ls, const char *buf, size_t len)
125 {
126         ls->first = simple_strtol(buf, NULL, 0);
127         return len;
128 }
129
130 static ssize_t gdlm_first_done_show(struct gdlm_ls *ls, char *buf)
131 {
132         return sprintf(buf, "%d\n", ls->first_done);
133 }
134
135 static ssize_t gdlm_recover_show(struct gdlm_ls *ls, char *buf)
136 {
137         return sprintf(buf, "%u\n", ls->recover_jid);
138 }
139
140 static ssize_t gdlm_recover_store(struct gdlm_ls *ls, const char *buf, size_t len)
141 {
142         ls->recover_jid = simple_strtol(buf, NULL, 0);
143         ls->fscb(ls->fsdata, LM_CB_NEED_RECOVERY, &ls->recover_jid);
144         return len;
145 }
146
147 static ssize_t gdlm_recover_done_show(struct gdlm_ls *ls, char *buf)
148 {
149         ssize_t ret;
150         ret = sprintf(buf, "%d\n", ls->recover_done);
151         return ret;
152 }
153
154 static ssize_t gdlm_cluster_show(struct gdlm_ls *ls, char *buf)
155 {
156         ssize_t ret;
157         ret = sprintf(buf, "%s\n", ls->clustername);
158         return ret;
159 }
160
161 static ssize_t gdlm_options_show(struct gdlm_ls *ls, char *buf)
162 {
163         ssize_t ret = 0;
164
165         if (ls->fsflags & LM_MFLAG_SPECTATOR)
166                 ret += sprintf(buf, "spectator ");
167
168         return ret;
169 }
170
171 struct gdlm_attr {
172         struct attribute attr;
173         ssize_t (*show)(struct gdlm_ls *, char *);
174         ssize_t (*store)(struct gdlm_ls *, const char *, size_t);
175 };
176
177 static struct gdlm_attr gdlm_attr_block = {
178         .attr  = {.name = "block", .mode = S_IRUGO | S_IWUSR},
179         .show  = gdlm_block_show,
180         .store = gdlm_block_store
181 };
182
183 static struct gdlm_attr gdlm_attr_mounted = {
184         .attr  = {.name = "mounted", .mode = S_IRUGO | S_IWUSR},
185         .show  = gdlm_mounted_show,
186         .store = gdlm_mounted_store
187 };
188
189 static struct gdlm_attr gdlm_attr_withdraw = {
190         .attr  = {.name = "withdraw", .mode = S_IRUGO | S_IWUSR},
191         .show  = gdlm_withdraw_show,
192         .store = gdlm_withdraw_store
193 };
194
195 static struct gdlm_attr gdlm_attr_jid = {
196         .attr  = {.name = "jid", .mode = S_IRUGO | S_IWUSR},
197         .show  = gdlm_jid_show,
198         .store = gdlm_jid_store
199 };
200
201 static struct gdlm_attr gdlm_attr_first = {
202         .attr  = {.name = "first", .mode = S_IRUGO | S_IWUSR},
203         .show  = gdlm_first_show,
204         .store = gdlm_first_store
205 };
206
207 static struct gdlm_attr gdlm_attr_first_done = {
208         .attr  = {.name = "first_done", .mode = S_IRUGO},
209         .show  = gdlm_first_done_show,
210 };
211
212 static struct gdlm_attr gdlm_attr_recover = {
213         .attr  = {.name = "recover", .mode = S_IRUGO | S_IWUSR},
214         .show  = gdlm_recover_show,
215         .store = gdlm_recover_store
216 };
217
218 static struct gdlm_attr gdlm_attr_recover_done = {
219         .attr  = {.name = "recover_done", .mode = S_IRUGO | S_IWUSR},
220         .show  = gdlm_recover_done_show,
221 };
222
223 static struct gdlm_attr gdlm_attr_cluster = {
224         .attr  = {.name = "cluster", .mode = S_IRUGO | S_IWUSR},
225         .show  = gdlm_cluster_show,
226 };
227
228 static struct gdlm_attr gdlm_attr_options = {
229         .attr  = {.name = "options", .mode = S_IRUGO | S_IWUSR},
230         .show  = gdlm_options_show,
231 };
232
233 static struct attribute *gdlm_attrs[] = {
234         &gdlm_attr_block.attr,
235         &gdlm_attr_mounted.attr,
236         &gdlm_attr_withdraw.attr,
237         &gdlm_attr_jid.attr,
238         &gdlm_attr_first.attr,
239         &gdlm_attr_first_done.attr,
240         &gdlm_attr_recover.attr,
241         &gdlm_attr_recover_done.attr,
242         &gdlm_attr_cluster.attr,
243         &gdlm_attr_options.attr,
244         NULL,
245 };
246
247 static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr,
248                               char *buf)
249 {
250         struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
251         struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
252         return a->show ? a->show(ls, buf) : 0;
253 }
254
255 static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr,
256                                const char *buf, size_t len)
257 {
258         struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
259         struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
260         return a->store ? a->store(ls, buf, len) : len;
261 }
262
263 static struct sysfs_ops gdlm_attr_ops = {
264         .show  = gdlm_attr_show,
265         .store = gdlm_attr_store,
266 };
267
268 static struct kobj_type gdlm_ktype = {
269         .default_attrs = gdlm_attrs,
270         .sysfs_ops     = &gdlm_attr_ops,
271 };
272
273 static struct kset gdlm_kset = {
274         .subsys = &kernel_subsys,
275         .kobj   = {.name = "lock_dlm",},
276         .ktype  = &gdlm_ktype,
277 };
278
279 int gdlm_kobject_setup(struct gdlm_ls *ls)
280 {
281         int error;
282
283         error = kobject_set_name(&ls->kobj, "%s", ls->fsname);
284         if (error)
285                 return error;
286
287         ls->kobj.kset = &gdlm_kset;
288         ls->kobj.ktype = &gdlm_ktype;
289
290         error = kobject_register(&ls->kobj);
291
292         return 0;
293 }
294
295 void gdlm_kobject_release(struct gdlm_ls *ls)
296 {
297         kobject_unregister(&ls->kobj);
298 }
299
300 int gdlm_sysfs_init(void)
301 {
302         int error;
303
304         error = kset_register(&gdlm_kset);
305         if (error)
306                 printk("lock_dlm: cannot register kset %d\n", error);
307
308         return error;
309 }
310
311 void gdlm_sysfs_exit(void)
312 {
313         kset_unregister(&gdlm_kset);
314 }
315