Commit 9c6c877c04ce17d76a35d2173d3a3840d6b796a2

Authored by Joel Becker
Committed by Mark Fasheh
1 parent b61817e116

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>

Showing 3 changed files with 104 additions and 13 deletions Side-by-side Diff

... ... @@ -2627,7 +2627,8 @@
2627 2627 }
2628 2628  
2629 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 2632 strlen(osb->uuid_str),
2632 2633 ocfs2_do_node_down, osb,
2633 2634 &conn);
fs/ocfs2/stackglue.c
... ... @@ -27,11 +27,17 @@
27 27 #include <linux/kobject.h>
28 28 #include <linux/sysfs.h>
29 29  
  30 +#include "ocfs2_fs.h"
  31 +
30 32 #include "stackglue.h"
31 33  
  34 +#define OCFS2_STACK_PLUGIN_O2CB "o2cb"
  35 +#define OCFS2_STACK_PLUGIN_USER "user"
  36 +
32 37 static struct ocfs2_locking_protocol *lproto;
33 38 static DEFINE_SPINLOCK(ocfs2_stack_lock);
34 39 static LIST_HEAD(ocfs2_stack_list);
  40 +static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1];
35 41  
36 42 /*
37 43 * The stack currently in use. If not null, active_stack->sp_count > 0,
38 44  
39 45  
40 46  
... ... @@ -53,26 +59,36 @@
53 59 return NULL;
54 60 }
55 61  
56   -static int ocfs2_stack_driver_request(const char *name)
  62 +static int ocfs2_stack_driver_request(const char *stack_name,
  63 + const char *plugin_name)
57 64 {
58 65 int rc;
59 66 struct ocfs2_stack_plugin *p;
60 67  
61 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 79 if (active_stack) {
64 80 /*
65 81 * If the active stack isn't the one we want, it cannot
66 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 85 rc = 0;
70 86 else
71 87 rc = -EBUSY;
72 88 goto out;
73 89 }
74 90  
75   - p = ocfs2_stack_lookup(name);
  91 + p = ocfs2_stack_lookup(plugin_name);
76 92 if (!p || !try_module_get(p->sp_owner)) {
77 93 rc = -ENOENT;
78 94 goto out;
79 95  
80 96  
81 97  
82 98  
83 99  
... ... @@ -94,23 +110,42 @@
94 110 * there is no stack, it tries to load it. It will fail if the stack still
95 111 * cannot be found. It will also fail if a different stack is in use.
96 112 */
97   -static int ocfs2_stack_driver_get(const char *name)
  113 +static int ocfs2_stack_driver_get(const char *stack_name)
98 114 {
99 115 int rc;
  116 + char *plugin_name = OCFS2_STACK_PLUGIN_O2CB;
100 117  
101   - rc = ocfs2_stack_driver_request(name);
  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 + }
  131 +
  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 137 if (rc == -ENOENT) {
103   - request_module("ocfs2_stack_%s", name);
104   - rc = ocfs2_stack_driver_request(name);
  138 + request_module("ocfs2_stack_%s", plugin_name);
  139 + rc = ocfs2_stack_driver_request(stack_name, plugin_name);
105 140 }
106 141  
107 142 if (rc == -ENOENT) {
108 143 printk(KERN_ERR
109 144 "ocfs2: Cluster stack driver \"%s\" cannot be found\n",
110   - name);
  145 + plugin_name);
111 146 } else if (rc == -EBUSY) {
112 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 151 return rc;
... ... @@ -242,7 +277,8 @@
242 277 }
243 278 EXPORT_SYMBOL_GPL(ocfs2_dlm_dump_lksb);
244 279  
245   -int ocfs2_cluster_connect(const char *group,
  280 +int ocfs2_cluster_connect(const char *stack_name,
  281 + const char *group,
246 282 int grouplen,
247 283 void (*recovery_handler)(int node_num,
248 284 void *recovery_data),
... ... @@ -277,7 +313,7 @@
277 313 new_conn->cc_version = lproto->lp_max_version;
278 314  
279 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 317 if (rc)
282 318 goto out_free;
283 319  
284 320  
... ... @@ -416,10 +452,61 @@
416 452 __ATTR(active_cluster_plugin, S_IFREG | S_IRUGO,
417 453 ocfs2_active_cluster_plugin_show, NULL);
418 454  
  455 +static 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 +
  467 +static 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 +
  500 +static 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 +
419 505 static struct attribute *ocfs2_attrs[] = {
420 506 &ocfs2_attr_max_locking_protocol.attr,
421 507 &ocfs2_attr_loaded_cluster_plugins.attr,
422 508 &ocfs2_attr_active_cluster_plugin.attr,
  509 + &ocfs2_attr_cluster_stack.attr,
423 510 NULL,
424 511 };
425 512  
... ... @@ -455,6 +542,8 @@
455 542  
456 543 static int __init ocfs2_stack_glue_init(void)
457 544 {
  545 + strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
  546 +
458 547 return ocfs2_sysfs_init();
459 548 }
460 549  
fs/ocfs2/stackglue.h
... ... @@ -209,7 +209,8 @@
209 209  
210 210  
211 211 /* Used by the filesystem */
212   -int ocfs2_cluster_connect(const char *group,
  212 +int ocfs2_cluster_connect(const char *stack_name,
  213 + const char *group,
213 214 int grouplen,
214 215 void (*recovery_handler)(int node_num,
215 216 void *recovery_data),