diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2009-01-12 05:43:39 -0500 |
---|---|---|
committer | Steven Whitehouse <steve@dolmen.chygwyn.com> | 2009-03-24 07:21:14 -0400 |
commit | f057f6cdf64175db1151b1f5d110e29904f119a1 (patch) | |
tree | 582dbf358e351f64977620c29ebf772d693b1948 /fs/gfs2/sys.c | |
parent | 22077f57dec8fcbeb1112b35313961c0902ff038 (diff) |
GFS2: Merge lock_dlm module into GFS2
This is the big patch that I've been working on for some time
now. There are many reasons for wanting to make this change
such as:
o Reducing overhead by eliminating duplicated fields between structures
o Simplifcation of the code (reduces the code size by a fair bit)
o The locking interface is now the DLM interface itself as proposed
some time ago.
o Fewer lookups of glocks when processing replies from the DLM
o Fewer memory allocations/deallocations for each glock
o Scope to do further optimisations in the future (but this patch is
more than big enough for now!)
Please note that (a) this patch relates to the lock_dlm module and
not the DLM itself, that is still a separate module; and (b) that
we retain the ability to build GFS2 as a standalone single node
filesystem with out requiring the DLM.
This patch needs a lot of testing, hence my keeping it I restarted
my -git tree after the last merge window. That way, this has the maximum
exposure before its merged. This is (modulo a few minor bug fixes) the
same patch that I've been posting on and off the the last three months
and its passed a number of different tests so far.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/sys.c')
-rw-r--r-- | fs/gfs2/sys.c | 154 |
1 files changed, 148 insertions, 6 deletions
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index a58a120dac92..a78997ea5037 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -14,9 +14,8 @@ | |||
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/kobject.h> | 16 | #include <linux/kobject.h> |
17 | #include <linux/gfs2_ondisk.h> | ||
18 | #include <linux/lm_interface.h> | ||
19 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | #include <linux/gfs2_ondisk.h> | ||
20 | 19 | ||
21 | #include "gfs2.h" | 20 | #include "gfs2.h" |
22 | #include "incore.h" | 21 | #include "incore.h" |
@@ -224,14 +223,145 @@ static struct lockstruct_attr lockstruct_attr_##name = __ATTR_RO(name) | |||
224 | 223 | ||
225 | LOCKSTRUCT_ATTR(jid, "%u\n"); | 224 | LOCKSTRUCT_ATTR(jid, "%u\n"); |
226 | LOCKSTRUCT_ATTR(first, "%u\n"); | 225 | LOCKSTRUCT_ATTR(first, "%u\n"); |
227 | LOCKSTRUCT_ATTR(lvb_size, "%u\n"); | ||
228 | LOCKSTRUCT_ATTR(flags, "%d\n"); | ||
229 | 226 | ||
230 | static struct attribute *lockstruct_attrs[] = { | 227 | static struct attribute *lockstruct_attrs[] = { |
231 | &lockstruct_attr_jid.attr, | 228 | &lockstruct_attr_jid.attr, |
232 | &lockstruct_attr_first.attr, | 229 | &lockstruct_attr_first.attr, |
233 | &lockstruct_attr_lvb_size.attr, | 230 | NULL, |
234 | &lockstruct_attr_flags.attr, | 231 | }; |
232 | |||
233 | /* | ||
234 | * lock_module. Originally from lock_dlm | ||
235 | */ | ||
236 | |||
237 | static ssize_t proto_name_show(struct gfs2_sbd *sdp, char *buf) | ||
238 | { | ||
239 | const struct lm_lockops *ops = sdp->sd_lockstruct.ls_ops; | ||
240 | return sprintf(buf, "%s\n", ops->lm_proto_name); | ||
241 | } | ||
242 | |||
243 | static ssize_t block_show(struct gfs2_sbd *sdp, char *buf) | ||
244 | { | ||
245 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
246 | ssize_t ret; | ||
247 | int val = 0; | ||
248 | |||
249 | if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags)) | ||
250 | val = 1; | ||
251 | ret = sprintf(buf, "%d\n", val); | ||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | ||
256 | { | ||
257 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
258 | ssize_t ret = len; | ||
259 | int val; | ||
260 | |||
261 | val = simple_strtol(buf, NULL, 0); | ||
262 | |||
263 | if (val == 1) | ||
264 | set_bit(DFL_BLOCK_LOCKS, &ls->ls_flags); | ||
265 | else if (val == 0) { | ||
266 | clear_bit(DFL_BLOCK_LOCKS, &ls->ls_flags); | ||
267 | smp_mb__after_clear_bit(); | ||
268 | gfs2_glock_thaw(sdp); | ||
269 | } else { | ||
270 | ret = -EINVAL; | ||
271 | } | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | static ssize_t lkid_show(struct gfs2_sbd *sdp, char *buf) | ||
276 | { | ||
277 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
278 | return sprintf(buf, "%u\n", ls->ls_id); | ||
279 | } | ||
280 | |||
281 | static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf) | ||
282 | { | ||
283 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
284 | return sprintf(buf, "%d\n", ls->ls_first); | ||
285 | } | ||
286 | |||
287 | static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) | ||
288 | { | ||
289 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
290 | return sprintf(buf, "%d\n", ls->ls_first_done); | ||
291 | } | ||
292 | |||
293 | static ssize_t recover_show(struct gfs2_sbd *sdp, char *buf) | ||
294 | { | ||
295 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
296 | return sprintf(buf, "%d\n", ls->ls_recover_jid); | ||
297 | } | ||
298 | |||
299 | static void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | ||
300 | { | ||
301 | struct gfs2_jdesc *jd; | ||
302 | |||
303 | spin_lock(&sdp->sd_jindex_spin); | ||
304 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
305 | if (jd->jd_jid != jid) | ||
306 | continue; | ||
307 | jd->jd_dirty = 1; | ||
308 | break; | ||
309 | } | ||
310 | spin_unlock(&sdp->sd_jindex_spin); | ||
311 | } | ||
312 | |||
313 | static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | ||
314 | { | ||
315 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
316 | ls->ls_recover_jid = simple_strtol(buf, NULL, 0); | ||
317 | gfs2_jdesc_make_dirty(sdp, ls->ls_recover_jid); | ||
318 | if (sdp->sd_recoverd_process) | ||
319 | wake_up_process(sdp->sd_recoverd_process); | ||
320 | return len; | ||
321 | } | ||
322 | |||
323 | static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf) | ||
324 | { | ||
325 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
326 | return sprintf(buf, "%d\n", ls->ls_recover_jid_done); | ||
327 | } | ||
328 | |||
329 | static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf) | ||
330 | { | ||
331 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
332 | return sprintf(buf, "%d\n", ls->ls_recover_jid_status); | ||
333 | } | ||
334 | |||
335 | struct gdlm_attr { | ||
336 | struct attribute attr; | ||
337 | ssize_t (*show)(struct gfs2_sbd *sdp, char *); | ||
338 | ssize_t (*store)(struct gfs2_sbd *sdp, const char *, size_t); | ||
339 | }; | ||
340 | |||
341 | #define GDLM_ATTR(_name,_mode,_show,_store) \ | ||
342 | static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) | ||
343 | |||
344 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); | ||
345 | GDLM_ATTR(block, 0644, block_show, block_store); | ||
346 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); | ||
347 | GDLM_ATTR(id, 0444, lkid_show, NULL); | ||
348 | GDLM_ATTR(first, 0444, lkfirst_show, NULL); | ||
349 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); | ||
350 | GDLM_ATTR(recover, 0644, recover_show, recover_store); | ||
351 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); | ||
352 | GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); | ||
353 | |||
354 | static struct attribute *lock_module_attrs[] = { | ||
355 | &gdlm_attr_proto_name.attr, | ||
356 | &gdlm_attr_block.attr, | ||
357 | &gdlm_attr_withdraw.attr, | ||
358 | &gdlm_attr_id.attr, | ||
359 | &lockstruct_attr_jid.attr, | ||
360 | &gdlm_attr_first.attr, | ||
361 | &gdlm_attr_first_done.attr, | ||
362 | &gdlm_attr_recover.attr, | ||
363 | &gdlm_attr_recover_done.attr, | ||
364 | &gdlm_attr_recover_status.attr, | ||
235 | NULL, | 365 | NULL, |
236 | }; | 366 | }; |
237 | 367 | ||
@@ -412,6 +542,11 @@ static struct attribute_group tune_group = { | |||
412 | .attrs = tune_attrs, | 542 | .attrs = tune_attrs, |
413 | }; | 543 | }; |
414 | 544 | ||
545 | static struct attribute_group lock_module_group = { | ||
546 | .name = "lock_module", | ||
547 | .attrs = lock_module_attrs, | ||
548 | }; | ||
549 | |||
415 | int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | 550 | int gfs2_sys_fs_add(struct gfs2_sbd *sdp) |
416 | { | 551 | { |
417 | int error; | 552 | int error; |
@@ -434,9 +569,15 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
434 | if (error) | 569 | if (error) |
435 | goto fail_args; | 570 | goto fail_args; |
436 | 571 | ||
572 | error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group); | ||
573 | if (error) | ||
574 | goto fail_tune; | ||
575 | |||
437 | kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); | 576 | kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); |
438 | return 0; | 577 | return 0; |
439 | 578 | ||
579 | fail_tune: | ||
580 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | ||
440 | fail_args: | 581 | fail_args: |
441 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 582 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
442 | fail_lockstruct: | 583 | fail_lockstruct: |
@@ -453,6 +594,7 @@ void gfs2_sys_fs_del(struct gfs2_sbd *sdp) | |||
453 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 594 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
454 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 595 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
455 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 596 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
597 | sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); | ||
456 | kobject_put(&sdp->sd_kobj); | 598 | kobject_put(&sdp->sd_kobj); |
457 | } | 599 | } |
458 | 600 | ||