aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-02-01 18:17:30 -0500
committerMark Fasheh <mfasheh@suse.com>2008-04-18 11:56:05 -0400
commit9c6c877c04ce17d76a35d2173d3a3840d6b796a2 (patch)
treedb8bd7a104f17ddc28b0e642f39cbd059aca0fb7
parentb61817e1166c5e19c08baf05196477cc345e1b1a (diff)
ocfs2: Add the 'cluster_stack' sysfs file.
Userspace can now query and specify the cluster stack in use via the /sys/fs/ocfs2/cluster_stack file. By default, it is 'o2cb', which is the classic stack. Thus, old tools that do not know how to modify this file will work just fine. The stack cannot be modified if there is a live filesystem. ocfs2_cluster_connect() now takes the expected cluster stack as an argument. This way, the filesystem and the stack glue ensure they are speaking to the same backend. If the stack is 'o2cb', the o2cb stack plugin is used. For any other value, the fsdlm stack plugin is selected. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/dlmglue.c3
-rw-r--r--fs/ocfs2/stackglue.c111
-rw-r--r--fs/ocfs2/stackglue.h3
3 files changed, 104 insertions, 13 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index f62a9e4fc315..394d25a131a5 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2627,7 +2627,8 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
2627 } 2627 }
2628 2628
2629 /* for now, uuid == domain */ 2629 /* for now, uuid == domain */
2630 status = ocfs2_cluster_connect(osb->uuid_str, 2630 status = ocfs2_cluster_connect(osb->osb_cluster_stack,
2631 osb->uuid_str,
2631 strlen(osb->uuid_str), 2632 strlen(osb->uuid_str),
2632 ocfs2_do_node_down, osb, 2633 ocfs2_do_node_down, osb,
2633 &conn); 2634 &conn);
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
diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h
index c96c8bb76863..d88bc655644b 100644
--- a/fs/ocfs2/stackglue.h
+++ b/fs/ocfs2/stackglue.h
@@ -209,7 +209,8 @@ struct ocfs2_stack_plugin {
209 209
210 210
211/* Used by the filesystem */ 211/* Used by the filesystem */
212int ocfs2_cluster_connect(const char *group, 212int ocfs2_cluster_connect(const char *stack_name,
213 const char *group,
213 int grouplen, 214 int grouplen,
214 void (*recovery_handler)(int node_num, 215 void (*recovery_handler)(int node_num,
215 void *recovery_data), 216 void *recovery_data),