diff options
Diffstat (limited to 'fs/gfs2/locking/dlm/sysfs.c')
-rw-r--r-- | fs/gfs2/locking/dlm/sysfs.c | 226 |
1 files changed, 226 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..29ae06f94944 --- /dev/null +++ b/fs/gfs2/locking/dlm/sysfs.c | |||
@@ -0,0 +1,226 @@ | |||
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 | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/ctype.h> | ||
11 | #include <linux/stat.h> | ||
12 | |||
13 | #include "lock_dlm.h" | ||
14 | |||
15 | extern struct lm_lockops gdlm_ops; | ||
16 | |||
17 | static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf) | ||
18 | { | ||
19 | return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name); | ||
20 | } | ||
21 | |||
22 | static ssize_t block_show(struct gdlm_ls *ls, char *buf) | ||
23 | { | ||
24 | ssize_t ret; | ||
25 | int val = 0; | ||
26 | |||
27 | if (test_bit(DFL_BLOCK_LOCKS, &ls->flags)) | ||
28 | val = 1; | ||
29 | ret = sprintf(buf, "%d\n", val); | ||
30 | return ret; | ||
31 | } | ||
32 | |||
33 | static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len) | ||
34 | { | ||
35 | ssize_t ret = len; | ||
36 | int val; | ||
37 | |||
38 | val = simple_strtol(buf, NULL, 0); | ||
39 | |||
40 | if (val == 1) | ||
41 | set_bit(DFL_BLOCK_LOCKS, &ls->flags); | ||
42 | else if (val == 0) { | ||
43 | clear_bit(DFL_BLOCK_LOCKS, &ls->flags); | ||
44 | gdlm_submit_delayed(ls); | ||
45 | } else { | ||
46 | ret = -EINVAL; | ||
47 | } | ||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf) | ||
52 | { | ||
53 | ssize_t ret; | ||
54 | int val = 0; | ||
55 | |||
56 | if (test_bit(DFL_WITHDRAW, &ls->flags)) | ||
57 | val = 1; | ||
58 | ret = sprintf(buf, "%d\n", val); | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len) | ||
63 | { | ||
64 | ssize_t ret = len; | ||
65 | int val; | ||
66 | |||
67 | val = simple_strtol(buf, NULL, 0); | ||
68 | |||
69 | if (val == 1) | ||
70 | set_bit(DFL_WITHDRAW, &ls->flags); | ||
71 | else | ||
72 | ret = -EINVAL; | ||
73 | wake_up(&ls->wait_control); | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | static ssize_t id_show(struct gdlm_ls *ls, char *buf) | ||
78 | { | ||
79 | return sprintf(buf, "%u\n", ls->id); | ||
80 | } | ||
81 | |||
82 | static ssize_t jid_show(struct gdlm_ls *ls, char *buf) | ||
83 | { | ||
84 | return sprintf(buf, "%d\n", ls->jid); | ||
85 | } | ||
86 | |||
87 | static ssize_t first_show(struct gdlm_ls *ls, char *buf) | ||
88 | { | ||
89 | return sprintf(buf, "%d\n", ls->first); | ||
90 | } | ||
91 | |||
92 | static ssize_t first_done_show(struct gdlm_ls *ls, char *buf) | ||
93 | { | ||
94 | return sprintf(buf, "%d\n", ls->first_done); | ||
95 | } | ||
96 | |||
97 | static ssize_t recover_show(struct gdlm_ls *ls, char *buf) | ||
98 | { | ||
99 | return sprintf(buf, "%d\n", ls->recover_jid); | ||
100 | } | ||
101 | |||
102 | static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len) | ||
103 | { | ||
104 | ls->recover_jid = simple_strtol(buf, NULL, 0); | ||
105 | ls->fscb(ls->sdp, LM_CB_NEED_RECOVERY, &ls->recover_jid); | ||
106 | return len; | ||
107 | } | ||
108 | |||
109 | static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf) | ||
110 | { | ||
111 | return sprintf(buf, "%d\n", ls->recover_jid_done); | ||
112 | } | ||
113 | |||
114 | static ssize_t recover_status_show(struct gdlm_ls *ls, char *buf) | ||
115 | { | ||
116 | return sprintf(buf, "%d\n", ls->recover_jid_status); | ||
117 | } | ||
118 | |||
119 | struct gdlm_attr { | ||
120 | struct attribute attr; | ||
121 | ssize_t (*show)(struct gdlm_ls *, char *); | ||
122 | ssize_t (*store)(struct gdlm_ls *, const char *, size_t); | ||
123 | }; | ||
124 | |||
125 | #define GDLM_ATTR(_name,_mode,_show,_store) \ | ||
126 | static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) | ||
127 | |||
128 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); | ||
129 | GDLM_ATTR(block, 0644, block_show, block_store); | ||
130 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); | ||
131 | GDLM_ATTR(id, 0444, id_show, NULL); | ||
132 | GDLM_ATTR(jid, 0444, jid_show, NULL); | ||
133 | GDLM_ATTR(first, 0444, first_show, NULL); | ||
134 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); | ||
135 | GDLM_ATTR(recover, 0644, recover_show, recover_store); | ||
136 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); | ||
137 | GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); | ||
138 | |||
139 | static struct attribute *gdlm_attrs[] = { | ||
140 | &gdlm_attr_proto_name.attr, | ||
141 | &gdlm_attr_block.attr, | ||
142 | &gdlm_attr_withdraw.attr, | ||
143 | &gdlm_attr_id.attr, | ||
144 | &gdlm_attr_jid.attr, | ||
145 | &gdlm_attr_first.attr, | ||
146 | &gdlm_attr_first_done.attr, | ||
147 | &gdlm_attr_recover.attr, | ||
148 | &gdlm_attr_recover_done.attr, | ||
149 | &gdlm_attr_recover_status.attr, | ||
150 | NULL, | ||
151 | }; | ||
152 | |||
153 | static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr, | ||
154 | char *buf) | ||
155 | { | ||
156 | struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); | ||
157 | struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr); | ||
158 | return a->show ? a->show(ls, buf) : 0; | ||
159 | } | ||
160 | |||
161 | static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr, | ||
162 | const char *buf, size_t len) | ||
163 | { | ||
164 | struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); | ||
165 | struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr); | ||
166 | return a->store ? a->store(ls, buf, len) : len; | ||
167 | } | ||
168 | |||
169 | static struct sysfs_ops gdlm_attr_ops = { | ||
170 | .show = gdlm_attr_show, | ||
171 | .store = gdlm_attr_store, | ||
172 | }; | ||
173 | |||
174 | static struct kobj_type gdlm_ktype = { | ||
175 | .default_attrs = gdlm_attrs, | ||
176 | .sysfs_ops = &gdlm_attr_ops, | ||
177 | }; | ||
178 | |||
179 | static struct kset gdlm_kset = { | ||
180 | .subsys = &kernel_subsys, | ||
181 | .kobj = {.name = "lock_dlm",}, | ||
182 | .ktype = &gdlm_ktype, | ||
183 | }; | ||
184 | |||
185 | int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj) | ||
186 | { | ||
187 | int error; | ||
188 | |||
189 | error = kobject_set_name(&ls->kobj, "%s", "lock_module"); | ||
190 | if (error) { | ||
191 | log_error("can't set kobj name %d", error); | ||
192 | return error; | ||
193 | } | ||
194 | |||
195 | ls->kobj.kset = &gdlm_kset; | ||
196 | ls->kobj.ktype = &gdlm_ktype; | ||
197 | ls->kobj.parent = fskobj; | ||
198 | |||
199 | error = kobject_register(&ls->kobj); | ||
200 | if (error) | ||
201 | log_error("can't register kobj %d", error); | ||
202 | |||
203 | return error; | ||
204 | } | ||
205 | |||
206 | void gdlm_kobject_release(struct gdlm_ls *ls) | ||
207 | { | ||
208 | kobject_unregister(&ls->kobj); | ||
209 | } | ||
210 | |||
211 | int gdlm_sysfs_init(void) | ||
212 | { | ||
213 | int error; | ||
214 | |||
215 | error = kset_register(&gdlm_kset); | ||
216 | if (error) | ||
217 | printk("lock_dlm: cannot register kset %d\n", error); | ||
218 | |||
219 | return error; | ||
220 | } | ||
221 | |||
222 | void gdlm_sysfs_exit(void) | ||
223 | { | ||
224 | kset_unregister(&gdlm_kset); | ||
225 | } | ||
226 | |||