aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/stackglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/stackglue.c')
-rw-r--r--fs/ocfs2/stackglue.c111
1 files changed, 100 insertions, 11 deletions
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
index 76ae4fcebcbd..bf45d9bff8a7 100644
--- a/fs/ocfs2/stackglue.c
+++ b/fs/ocfs2/stackglue.c
@@ -27,11 +27,17 @@
27#include <linux/kobject.h> 27#include <linux/kobject.h>
28#include <linux/sysfs.h> 28#include <linux/sysfs.h>
29 29
30#include "ocfs2_fs.h"
31
30#include "stackglue.h" 32#include "stackglue.h"
31 33
34#define OCFS2_STACK_PLUGIN_O2CB "o2cb"
35#define OCFS2_STACK_PLUGIN_USER "user"
36
32static struct ocfs2_locking_protocol *lproto; 37static struct ocfs2_locking_protocol *lproto;
33static DEFINE_SPINLOCK(ocfs2_stack_lock); 38static DEFINE_SPINLOCK(ocfs2_stack_lock);
34static LIST_HEAD(ocfs2_stack_list); 39static LIST_HEAD(ocfs2_stack_list);
40static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1];
35 41
36/* 42/*
37 * The stack currently in use. If not null, active_stack->sp_count > 0, 43 * The stack currently in use. If not null, active_stack->sp_count > 0,
@@ -53,26 +59,36 @@ static struct ocfs2_stack_plugin *ocfs2_stack_lookup(const char *name)
53 return NULL; 59 return NULL;
54} 60}
55 61
56static int ocfs2_stack_driver_request(const char *name) 62static int ocfs2_stack_driver_request(const char *stack_name,
63 const char *plugin_name)
57{ 64{
58 int rc; 65 int rc;
59 struct ocfs2_stack_plugin *p; 66 struct ocfs2_stack_plugin *p;
60 67
61 spin_lock(&ocfs2_stack_lock); 68 spin_lock(&ocfs2_stack_lock);
62 69
70 /*
71 * If the stack passed by the filesystem isn't the selected one,
72 * we can't continue.
73 */
74 if (strcmp(stack_name, cluster_stack_name)) {
75 rc = -EBUSY;
76 goto out;
77 }
78
63 if (active_stack) { 79 if (active_stack) {
64 /* 80 /*
65 * If the active stack isn't the one we want, it cannot 81 * If the active stack isn't the one we want, it cannot
66 * be selected right now. 82 * be selected right now.
67 */ 83 */
68 if (!strcmp(active_stack->sp_name, name)) 84 if (!strcmp(active_stack->sp_name, plugin_name))
69 rc = 0; 85 rc = 0;
70 else 86 else
71 rc = -EBUSY; 87 rc = -EBUSY;
72 goto out; 88 goto out;
73 } 89 }
74 90
75 p = ocfs2_stack_lookup(name); 91 p = ocfs2_stack_lookup(plugin_name);
76 if (!p || !try_module_get(p->sp_owner)) { 92 if (!p || !try_module_get(p->sp_owner)) {
77 rc = -ENOENT; 93 rc = -ENOENT;
78 goto out; 94 goto out;
@@ -94,23 +110,42 @@ out:
94 * there is no stack, it tries to load it. It will fail if the stack still 110 * there is no stack, it tries to load it. It will fail if the stack still
95 * cannot be found. It will also fail if a different stack is in use. 111 * cannot be found. It will also fail if a different stack is in use.
96 */ 112 */
97static int ocfs2_stack_driver_get(const char *name) 113static int ocfs2_stack_driver_get(const char *stack_name)
98{ 114{
99 int rc; 115 int rc;
116 char *plugin_name = OCFS2_STACK_PLUGIN_O2CB;
117
118 /*
119 * Classic stack does not pass in a stack name. This is
120 * compatible with older tools as well.
121 */
122 if (!stack_name || !*stack_name)
123 stack_name = OCFS2_STACK_PLUGIN_O2CB;
124
125 if (strlen(stack_name) != OCFS2_STACK_LABEL_LEN) {
126 printk(KERN_ERR
127 "ocfs2 passed an invalid cluster stack label: \"%s\"\n",
128 stack_name);
129 return -EINVAL;
130 }
100 131
101 rc = ocfs2_stack_driver_request(name); 132 /* Anything that isn't the classic stack is a user stack */
133 if (strcmp(stack_name, OCFS2_STACK_PLUGIN_O2CB))
134 plugin_name = OCFS2_STACK_PLUGIN_USER;
135
136 rc = ocfs2_stack_driver_request(stack_name, plugin_name);
102 if (rc == -ENOENT) { 137 if (rc == -ENOENT) {
103 request_module("ocfs2_stack_%s", name); 138 request_module("ocfs2_stack_%s", plugin_name);
104 rc = ocfs2_stack_driver_request(name); 139 rc = ocfs2_stack_driver_request(stack_name, plugin_name);
105 } 140 }
106 141
107 if (rc == -ENOENT) { 142 if (rc == -ENOENT) {
108 printk(KERN_ERR 143 printk(KERN_ERR
109 "ocfs2: Cluster stack driver \"%s\" cannot be found\n", 144 "ocfs2: Cluster stack driver \"%s\" cannot be found\n",
110 name); 145 plugin_name);
111 } else if (rc == -EBUSY) { 146 } else if (rc == -EBUSY) {
112 printk(KERN_ERR 147 printk(KERN_ERR
113 "ocfs2: A different cluster stack driver is in use\n"); 148 "ocfs2: A different cluster stack is in use\n");
114 } 149 }
115 150
116 return rc; 151 return rc;
@@ -242,7 +277,8 @@ void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb)
242} 277}
243EXPORT_SYMBOL_GPL(ocfs2_dlm_dump_lksb); 278EXPORT_SYMBOL_GPL(ocfs2_dlm_dump_lksb);
244 279
245int ocfs2_cluster_connect(const char *group, 280int ocfs2_cluster_connect(const char *stack_name,
281 const char *group,
246 int grouplen, 282 int grouplen,
247 void (*recovery_handler)(int node_num, 283 void (*recovery_handler)(int node_num,
248 void *recovery_data), 284 void *recovery_data),
@@ -277,7 +313,7 @@ int ocfs2_cluster_connect(const char *group,
277 new_conn->cc_version = lproto->lp_max_version; 313 new_conn->cc_version = lproto->lp_max_version;
278 314
279 /* This will pin the stack driver if successful */ 315 /* This will pin the stack driver if successful */
280 rc = ocfs2_stack_driver_get("o2cb"); 316 rc = ocfs2_stack_driver_get(stack_name);
281 if (rc) 317 if (rc)
282 goto out_free; 318 goto out_free;
283 319
@@ -416,10 +452,61 @@ static struct kobj_attribute ocfs2_attr_active_cluster_plugin =
416 __ATTR(active_cluster_plugin, S_IFREG | S_IRUGO, 452 __ATTR(active_cluster_plugin, S_IFREG | S_IRUGO,
417 ocfs2_active_cluster_plugin_show, NULL); 453 ocfs2_active_cluster_plugin_show, NULL);
418 454
455static ssize_t ocfs2_cluster_stack_show(struct kobject *kobj,
456 struct kobj_attribute *attr,
457 char *buf)
458{
459 ssize_t ret;
460 spin_lock(&ocfs2_stack_lock);
461 ret = snprintf(buf, PAGE_SIZE, "%s\n", cluster_stack_name);
462 spin_unlock(&ocfs2_stack_lock);
463
464 return ret;
465}
466
467static ssize_t ocfs2_cluster_stack_store(struct kobject *kobj,
468 struct kobj_attribute *attr,
469 const char *buf, size_t count)
470{
471 size_t len = count;
472 ssize_t ret;
473
474 if (len == 0)
475 return len;
476
477 if (buf[len - 1] == '\n')
478 len--;
479
480 if ((len != OCFS2_STACK_LABEL_LEN) ||
481 (strnlen(buf, len) != len))
482 return -EINVAL;
483
484 spin_lock(&ocfs2_stack_lock);
485 if (active_stack) {
486 if (!strncmp(buf, cluster_stack_name, len))
487 ret = count;
488 else
489 ret = -EBUSY;
490 } else {
491 memcpy(cluster_stack_name, buf, len);
492 ret = count;
493 }
494 spin_unlock(&ocfs2_stack_lock);
495
496 return ret;
497}
498
499
500static struct kobj_attribute ocfs2_attr_cluster_stack =
501 __ATTR(cluster_stack, S_IFREG | S_IRUGO | S_IWUSR,
502 ocfs2_cluster_stack_show,
503 ocfs2_cluster_stack_store);
504
419static struct attribute *ocfs2_attrs[] = { 505static struct attribute *ocfs2_attrs[] = {
420 &ocfs2_attr_max_locking_protocol.attr, 506 &ocfs2_attr_max_locking_protocol.attr,
421 &ocfs2_attr_loaded_cluster_plugins.attr, 507 &ocfs2_attr_loaded_cluster_plugins.attr,
422 &ocfs2_attr_active_cluster_plugin.attr, 508 &ocfs2_attr_active_cluster_plugin.attr,
509 &ocfs2_attr_cluster_stack.attr,
423 NULL, 510 NULL,
424}; 511};
425 512
@@ -455,6 +542,8 @@ error:
455 542
456static int __init ocfs2_stack_glue_init(void) 543static int __init ocfs2_stack_glue_init(void)
457{ 544{
545 strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
546
458 return ocfs2_sysfs_init(); 547 return ocfs2_sysfs_init();
459} 548}
460 549