diff options
Diffstat (limited to 'fs/gfs2/locking/dlm/sysfs.c')
-rw-r--r-- | fs/gfs2/locking/dlm/sysfs.c | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/fs/gfs2/locking/dlm/sysfs.c b/fs/gfs2/locking/dlm/sysfs.c new file mode 100644 index 000000000000..8964733f55e4 --- /dev/null +++ b/fs/gfs2/locking/dlm/sysfs.c | |||
@@ -0,0 +1,315 @@ | |||
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 | |||