diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-02-01 02:56:17 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-04-18 11:56:05 -0400 |
commit | 74ae4e104dfc57017783fc07d5f2f9129062207f (patch) | |
tree | 4b33a403e1c23acb5bcb756d9cab17f3609e79ed /fs/ocfs2/stackglue.c | |
parent | 286eaa95c5c5915a6b72cc3f0a2534161fd7928b (diff) |
ocfs2: Create stack glue sysfs files.
Introduce a set of sysfs files that describe the current stack glue
state. The files live under /sys/fs/ocfs2. The locking_protocol file
displays the version of ocfs2's locking code. The
loaded_cluster_plugins file displays all of the currently loaded stack
plugins. When filesystems are mounted, the active_cluster_plugin file
will display the plugin in use.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/stackglue.c')
-rw-r--r-- | fs/ocfs2/stackglue.c | 121 |
1 files changed, 120 insertions, 1 deletions
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 1978c9cff0e9..76ae4fcebcbd 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/kmod.h> | 25 | #include <linux/kmod.h> |
26 | #include <linux/fs.h> | ||
27 | #include <linux/kobject.h> | ||
28 | #include <linux/sysfs.h> | ||
26 | 29 | ||
27 | #include "stackglue.h" | 30 | #include "stackglue.h" |
28 | 31 | ||
@@ -335,14 +338,130 @@ int ocfs2_cluster_this_node(unsigned int *node) | |||
335 | EXPORT_SYMBOL_GPL(ocfs2_cluster_this_node); | 338 | EXPORT_SYMBOL_GPL(ocfs2_cluster_this_node); |
336 | 339 | ||
337 | 340 | ||
338 | static int __init ocfs2_stack_glue_init(void) | 341 | /* |
342 | * Sysfs bits | ||
343 | */ | ||
344 | |||
345 | static ssize_t ocfs2_max_locking_protocol_show(struct kobject *kobj, | ||
346 | struct kobj_attribute *attr, | ||
347 | char *buf) | ||
348 | { | ||
349 | ssize_t ret = 0; | ||
350 | |||
351 | spin_lock(&ocfs2_stack_lock); | ||
352 | if (lproto) | ||
353 | ret = snprintf(buf, PAGE_SIZE, "%u.%u\n", | ||
354 | lproto->lp_max_version.pv_major, | ||
355 | lproto->lp_max_version.pv_minor); | ||
356 | spin_unlock(&ocfs2_stack_lock); | ||
357 | |||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | static struct kobj_attribute ocfs2_attr_max_locking_protocol = | ||
362 | __ATTR(max_locking_protocol, S_IFREG | S_IRUGO, | ||
363 | ocfs2_max_locking_protocol_show, NULL); | ||
364 | |||
365 | static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj, | ||
366 | struct kobj_attribute *attr, | ||
367 | char *buf) | ||
339 | { | 368 | { |
369 | ssize_t ret = 0, total = 0, remain = PAGE_SIZE; | ||
370 | struct ocfs2_stack_plugin *p; | ||
371 | |||
372 | spin_lock(&ocfs2_stack_lock); | ||
373 | list_for_each_entry(p, &ocfs2_stack_list, sp_list) { | ||
374 | ret = snprintf(buf, remain, "%s\n", | ||
375 | p->sp_name); | ||
376 | if (ret < 0) { | ||
377 | total = ret; | ||
378 | break; | ||
379 | } | ||
380 | if (ret == remain) { | ||
381 | /* snprintf() didn't fit */ | ||
382 | total = -E2BIG; | ||
383 | break; | ||
384 | } | ||
385 | total += ret; | ||
386 | remain -= ret; | ||
387 | } | ||
388 | spin_unlock(&ocfs2_stack_lock); | ||
389 | |||
390 | return total; | ||
391 | } | ||
392 | |||
393 | static struct kobj_attribute ocfs2_attr_loaded_cluster_plugins = | ||
394 | __ATTR(loaded_cluster_plugins, S_IFREG | S_IRUGO, | ||
395 | ocfs2_loaded_cluster_plugins_show, NULL); | ||
396 | |||
397 | static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj, | ||
398 | struct kobj_attribute *attr, | ||
399 | char *buf) | ||
400 | { | ||
401 | ssize_t ret = 0; | ||
402 | |||
403 | spin_lock(&ocfs2_stack_lock); | ||
404 | if (active_stack) { | ||
405 | ret = snprintf(buf, PAGE_SIZE, "%s\n", | ||
406 | active_stack->sp_name); | ||
407 | if (ret == PAGE_SIZE) | ||
408 | ret = -E2BIG; | ||
409 | } | ||
410 | spin_unlock(&ocfs2_stack_lock); | ||
411 | |||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | static struct kobj_attribute ocfs2_attr_active_cluster_plugin = | ||
416 | __ATTR(active_cluster_plugin, S_IFREG | S_IRUGO, | ||
417 | ocfs2_active_cluster_plugin_show, NULL); | ||
418 | |||
419 | static struct attribute *ocfs2_attrs[] = { | ||
420 | &ocfs2_attr_max_locking_protocol.attr, | ||
421 | &ocfs2_attr_loaded_cluster_plugins.attr, | ||
422 | &ocfs2_attr_active_cluster_plugin.attr, | ||
423 | NULL, | ||
424 | }; | ||
425 | |||
426 | static struct attribute_group ocfs2_attr_group = { | ||
427 | .attrs = ocfs2_attrs, | ||
428 | }; | ||
429 | |||
430 | static struct kset *ocfs2_kset; | ||
431 | |||
432 | static void ocfs2_sysfs_exit(void) | ||
433 | { | ||
434 | kset_unregister(ocfs2_kset); | ||
435 | } | ||
436 | |||
437 | static int ocfs2_sysfs_init(void) | ||
438 | { | ||
439 | int ret; | ||
440 | |||
441 | ocfs2_kset = kset_create_and_add("ocfs2", NULL, fs_kobj); | ||
442 | if (!ocfs2_kset) | ||
443 | return -ENOMEM; | ||
444 | |||
445 | ret = sysfs_create_group(&ocfs2_kset->kobj, &ocfs2_attr_group); | ||
446 | if (ret) | ||
447 | goto error; | ||
448 | |||
340 | return 0; | 449 | return 0; |
450 | |||
451 | error: | ||
452 | kset_unregister(ocfs2_kset); | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static int __init ocfs2_stack_glue_init(void) | ||
457 | { | ||
458 | return ocfs2_sysfs_init(); | ||
341 | } | 459 | } |
342 | 460 | ||
343 | static void __exit ocfs2_stack_glue_exit(void) | 461 | static void __exit ocfs2_stack_glue_exit(void) |
344 | { | 462 | { |
345 | lproto = NULL; | 463 | lproto = NULL; |
464 | ocfs2_sysfs_exit(); | ||
346 | } | 465 | } |
347 | 466 | ||
348 | MODULE_AUTHOR("Oracle"); | 467 | MODULE_AUTHOR("Oracle"); |