Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / fs / ocfs2 / stackglue.c
1 /* -*- mode: c; c-basic-offset: 8; -*-
2  * vim: noexpandtab sw=8 ts=8 sts=0:
3  *
4  * stackglue.c
5  *
6  * Code which implements an OCFS2 specific interface to underlying
7  * cluster stacks.
8  *
9  * Copyright (C) 2007, 2009 Oracle.  All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  */
20
21 #include <linux/list.h>
22 #include <linux/spinlock.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/kmod.h>
26 #include <linux/fs.h>
27 #include <linux/kobject.h>
28 #include <linux/sysfs.h>
29 #include <linux/sysctl.h>
30
31 #include "ocfs2_fs.h"
32
33 #include "stackglue.h"
34
35 #define OCFS2_STACK_PLUGIN_O2CB         "o2cb"
36 #define OCFS2_STACK_PLUGIN_USER         "user"
37 #define OCFS2_MAX_HB_CTL_PATH           256
38
39 static struct ocfs2_protocol_version locking_max_version;
40 static DEFINE_SPINLOCK(ocfs2_stack_lock);
41 static LIST_HEAD(ocfs2_stack_list);
42 static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1];
43 static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
44
45 /*
46  * The stack currently in use.  If not null, active_stack->sp_count > 0,
47  * the module is pinned, and the locking protocol cannot be changed.
48  */
49 static struct ocfs2_stack_plugin *active_stack;
50
51 inline int ocfs2_is_o2cb_active(void)
52 {
53         return !strcmp(active_stack->sp_name, OCFS2_STACK_PLUGIN_O2CB);
54 }
55 EXPORT_SYMBOL_GPL(ocfs2_is_o2cb_active);
56
57 static struct ocfs2_stack_plugin *ocfs2_stack_lookup(const char *name)
58 {
59         struct ocfs2_stack_plugin *p;
60
61         assert_spin_locked(&ocfs2_stack_lock);
62
63         list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
64                 if (!strcmp(p->sp_name, name))
65                         return p;
66         }
67
68         return NULL;
69 }
70
71 static int ocfs2_stack_driver_request(const char *stack_name,
72                                       const char *plugin_name)
73 {
74         int rc;
75         struct ocfs2_stack_plugin *p;
76
77         spin_lock(&ocfs2_stack_lock);
78
79         /*
80          * If the stack passed by the filesystem isn't the selected one,
81          * we can't continue.
82          */
83         if (strcmp(stack_name, cluster_stack_name)) {
84                 rc = -EBUSY;
85                 goto out;
86         }
87
88         if (active_stack) {
89                 /*
90                  * If the active stack isn't the one we want, it cannot
91                  * be selected right now.
92                  */
93                 if (!strcmp(active_stack->sp_name, plugin_name))
94                         rc = 0;
95                 else
96                         rc = -EBUSY;
97                 goto out;
98         }
99
100         p = ocfs2_stack_lookup(plugin_name);
101         if (!p || !try_module_get(p->sp_owner)) {
102                 rc = -ENOENT;
103                 goto out;
104         }
105
106         active_stack = p;
107         rc = 0;
108
109 out:
110         /* If we found it, pin it */
111         if (!rc)
112                 active_stack->sp_count++;
113
114         spin_unlock(&ocfs2_stack_lock);
115         return rc;
116 }
117
118 /*
119  * This function looks up the appropriate stack and makes it active.  If
120  * there is no stack, it tries to load it.  It will fail if the stack still
121  * cannot be found.  It will also fail if a different stack is in use.
122  */
123 static int ocfs2_stack_driver_get(const char *stack_name)
124 {
125         int rc;
126         char *plugin_name = OCFS2_STACK_PLUGIN_O2CB;
127
128         /*
129          * Classic stack does not pass in a stack name.  This is
130          * compatible with older tools as well.
131          */
132         if (!stack_name || !*stack_name)
133                 stack_name = OCFS2_STACK_PLUGIN_O2CB;
134
135         if (strlen(stack_name) != OCFS2_STACK_LABEL_LEN) {
136                 printk(KERN_ERR
137                        "ocfs2 passed an invalid cluster stack label: \"%s\"\n",
138                        stack_name);
139                 return -EINVAL;
140         }
141
142         /* Anything that isn't the classic stack is a user stack */
143         if (strcmp(stack_name, OCFS2_STACK_PLUGIN_O2CB))
144                 plugin_name = OCFS2_STACK_PLUGIN_USER;
145
146         rc = ocfs2_stack_driver_request(stack_name, plugin_name);
147         if (rc == -ENOENT) {
148                 request_module("ocfs2_stack_%s", plugin_name);
149                 rc = ocfs2_stack_driver_request(stack_name, plugin_name);
150         }
151
152         if (rc == -ENOENT) {
153                 printk(KERN_ERR
154                        "ocfs2: Cluster stack driver \"%s\" cannot be found\n",
155                        plugin_name);
156         } else if (rc == -EBUSY) {
157                 printk(KERN_ERR
158                        "ocfs2: A different cluster stack is in use\n");
159         }
160
161         return rc;
162 }
163
164 static void ocfs2_stack_driver_put(void)
165 {
166         spin_lock(&ocfs2_stack_lock);
167         BUG_ON(active_stack == NULL);
168         BUG_ON(active_stack->sp_count == 0);
169
170         active_stack->sp_count--;
171         if (!active_stack->sp_count) {
172                 module_put(active_stack->sp_owner);
173                 active_stack = NULL;
174         }
175         spin_unlock(&ocfs2_stack_lock);
176 }
177
178 int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin)
179 {
180         int rc;
181
182         spin_lock(&ocfs2_stack_lock);
183         if (!ocfs2_stack_lookup(plugin->sp_name)) {
184                 plugin->sp_count = 0;
185                 plugin->sp_max_proto = locking_max_version;
186                 list_add(&plugin->sp_list, &ocfs2_stack_list);
187                 printk(KERN_INFO "ocfs2: Registered cluster interface %s\n",
188                        plugin->sp_name);
189                 rc = 0;
190         } else {
191                 printk(KERN_ERR "ocfs2: Stack \"%s\" already registered\n",
192                        plugin->sp_name);
193                 rc = -EEXIST;
194         }
195         spin_unlock(&ocfs2_stack_lock);
196
197         return rc;
198 }
199 EXPORT_SYMBOL_GPL(ocfs2_stack_glue_register);
200
201 void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin)
202 {
203         struct ocfs2_stack_plugin *p;
204
205         spin_lock(&ocfs2_stack_lock);
206         p = ocfs2_stack_lookup(plugin->sp_name);
207         if (p) {
208                 BUG_ON(p != plugin);
209                 BUG_ON(plugin == active_stack);
210                 BUG_ON(plugin->sp_count != 0);
211                 list_del_init(&plugin->sp_list);
212                 printk(KERN_INFO "ocfs2: Unregistered cluster interface %s\n",
213                        plugin->sp_name);
214         } else {
215                 printk(KERN_ERR "Stack \"%s\" is not registered\n",
216                        plugin->sp_name);
217         }
218         spin_unlock(&ocfs2_stack_lock);
219 }
220 EXPORT_SYMBOL_GPL(ocfs2_stack_glue_unregister);
221
222 void ocfs2_stack_glue_set_max_proto_version(struct ocfs2_protocol_version *max_proto)
223 {
224         struct ocfs2_stack_plugin *p;
225
226         spin_lock(&ocfs2_stack_lock);
227         if (memcmp(max_proto, &locking_max_version,
228                    sizeof(struct ocfs2_protocol_version))) {
229                 BUG_ON(locking_max_version.pv_major != 0);
230
231                 locking_max_version = *max_proto;
232                 list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
233                         p->sp_max_proto = locking_max_version;
234                 }
235         }
236         spin_unlock(&ocfs2_stack_lock);
237 }
238 EXPORT_SYMBOL_GPL(ocfs2_stack_glue_set_max_proto_version);
239
240
241 /*
242  * The ocfs2_dlm_lock() and ocfs2_dlm_unlock() functions take no argument
243  * for the ast and bast functions.  They will pass the lksb to the ast
244  * and bast.  The caller can wrap the lksb with their own structure to
245  * get more information.
246  */
247 int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
248                    int mode,
249                    struct ocfs2_dlm_lksb *lksb,
250                    u32 flags,
251                    void *name,
252                    unsigned int namelen)
253 {
254         if (!lksb->lksb_conn)
255                 lksb->lksb_conn = conn;
256         else
257                 BUG_ON(lksb->lksb_conn != conn);
258         return active_stack->sp_ops->dlm_lock(conn, mode, lksb, flags,
259                                               name, namelen);
260 }
261 EXPORT_SYMBOL_GPL(ocfs2_dlm_lock);
262
263 int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
264                      struct ocfs2_dlm_lksb *lksb,
265                      u32 flags)
266 {
267         BUG_ON(lksb->lksb_conn == NULL);
268
269         return active_stack->sp_ops->dlm_unlock(conn, lksb, flags);
270 }
271 EXPORT_SYMBOL_GPL(ocfs2_dlm_unlock);
272
273 int ocfs2_dlm_lock_status(struct ocfs2_dlm_lksb *lksb)
274 {
275         return active_stack->sp_ops->lock_status(lksb);
276 }
277 EXPORT_SYMBOL_GPL(ocfs2_dlm_lock_status);
278
279 int ocfs2_dlm_lvb_valid(struct ocfs2_dlm_lksb *lksb)
280 {
281         return active_stack->sp_ops->lvb_valid(lksb);
282 }
283 EXPORT_SYMBOL_GPL(ocfs2_dlm_lvb_valid);
284
285 void *ocfs2_dlm_lvb(struct ocfs2_dlm_lksb *lksb)
286 {
287         return active_stack->sp_ops->lock_lvb(lksb);
288 }
289 EXPORT_SYMBOL_GPL(ocfs2_dlm_lvb);
290
291 void ocfs2_dlm_dump_lksb(struct ocfs2_dlm_lksb *lksb)
292 {
293         active_stack->sp_ops->dump_lksb(lksb);
294 }
295 EXPORT_SYMBOL_GPL(ocfs2_dlm_dump_lksb);
296
297 int ocfs2_stack_supports_plocks(void)
298 {
299         return active_stack && active_stack->sp_ops->plock;
300 }
301 EXPORT_SYMBOL_GPL(ocfs2_stack_supports_plocks);
302
303 /*
304  * ocfs2_plock() can only be safely called if
305  * ocfs2_stack_supports_plocks() returned true
306  */
307 int ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino,
308                 struct file *file, int cmd, struct file_lock *fl)
309 {
310         WARN_ON_ONCE(active_stack->sp_ops->plock == NULL);
311         if (active_stack->sp_ops->plock)
312                 return active_stack->sp_ops->plock(conn, ino, file, cmd, fl);
313         return -EOPNOTSUPP;
314 }
315 EXPORT_SYMBOL_GPL(ocfs2_plock);
316
317 int ocfs2_cluster_connect(const char *stack_name,
318                           const char *cluster_name,
319                           int cluster_name_len,
320                           const char *group,
321                           int grouplen,
322                           struct ocfs2_locking_protocol *lproto,
323                           void (*recovery_handler)(int node_num,
324                                                    void *recovery_data),
325                           void *recovery_data,
326                           struct ocfs2_cluster_connection **conn)
327 {
328         int rc = 0;
329         struct ocfs2_cluster_connection *new_conn;
330
331         BUG_ON(group == NULL);
332         BUG_ON(conn == NULL);
333         BUG_ON(recovery_handler == NULL);
334
335         if (grouplen > GROUP_NAME_MAX) {
336                 rc = -EINVAL;
337                 goto out;
338         }
339
340         if (memcmp(&lproto->lp_max_version, &locking_max_version,
341                    sizeof(struct ocfs2_protocol_version))) {
342                 rc = -EINVAL;
343                 goto out;
344         }
345
346         new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection),
347                            GFP_KERNEL);
348         if (!new_conn) {
349                 rc = -ENOMEM;
350                 goto out;
351         }
352
353         strlcpy(new_conn->cc_name, group, GROUP_NAME_MAX + 1);
354         new_conn->cc_namelen = grouplen;
355         if (cluster_name_len)
356                 strlcpy(new_conn->cc_cluster_name, cluster_name,
357                         CLUSTER_NAME_MAX + 1);
358         new_conn->cc_cluster_name_len = cluster_name_len;
359         new_conn->cc_recovery_handler = recovery_handler;
360         new_conn->cc_recovery_data = recovery_data;
361
362         new_conn->cc_proto = lproto;
363         /* Start the new connection at our maximum compatibility level */
364         new_conn->cc_version = lproto->lp_max_version;
365
366         /* This will pin the stack driver if successful */
367         rc = ocfs2_stack_driver_get(stack_name);
368         if (rc)
369                 goto out_free;
370
371         rc = active_stack->sp_ops->connect(new_conn);
372         if (rc) {
373                 ocfs2_stack_driver_put();
374                 goto out_free;
375         }
376
377         *conn = new_conn;
378
379 out_free:
380         if (rc)
381                 kfree(new_conn);
382
383 out:
384         return rc;
385 }
386 EXPORT_SYMBOL_GPL(ocfs2_cluster_connect);
387
388 /* The caller will ensure all nodes have the same cluster stack */
389 int ocfs2_cluster_connect_agnostic(const char *group,
390                                    int grouplen,
391                                    struct ocfs2_locking_protocol *lproto,
392                                    void (*recovery_handler)(int node_num,
393                                                             void *recovery_data),
394                                    void *recovery_data,
395                                    struct ocfs2_cluster_connection **conn)
396 {
397         char *stack_name = NULL;
398
399         if (cluster_stack_name[0])
400                 stack_name = cluster_stack_name;
401         return ocfs2_cluster_connect(stack_name, NULL, 0, group, grouplen,
402                                      lproto, recovery_handler, recovery_data,
403                                      conn);
404 }
405 EXPORT_SYMBOL_GPL(ocfs2_cluster_connect_agnostic);
406
407 /* If hangup_pending is 0, the stack driver will be dropped */
408 int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
409                              int hangup_pending)
410 {
411         int ret;
412
413         BUG_ON(conn == NULL);
414
415         ret = active_stack->sp_ops->disconnect(conn);
416
417         /* XXX Should we free it anyway? */
418         if (!ret) {
419                 kfree(conn);
420                 if (!hangup_pending)
421                         ocfs2_stack_driver_put();
422         }
423
424         return ret;
425 }
426 EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect);
427
428 /*
429  * Leave the group for this filesystem.  This is executed by a userspace
430  * program (stored in ocfs2_hb_ctl_path).
431  */
432 static void ocfs2_leave_group(const char *group)
433 {
434         int ret;
435         char *argv[5], *envp[3];
436
437         argv[0] = ocfs2_hb_ctl_path;
438         argv[1] = "-K";
439         argv[2] = "-u";
440         argv[3] = (char *)group;
441         argv[4] = NULL;
442
443         /* minimal command environment taken from cpu_run_sbin_hotplug */
444         envp[0] = "HOME=/";
445         envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
446         envp[2] = NULL;
447
448         ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
449         if (ret < 0) {
450                 printk(KERN_ERR
451                        "ocfs2: Error %d running user helper "
452                        "\"%s %s %s %s\"\n",
453                        ret, argv[0], argv[1], argv[2], argv[3]);
454         }
455 }
456
457 /*
458  * Hangup is a required post-umount.  ocfs2-tools software expects the
459  * filesystem to call "ocfs2_hb_ctl" during unmount.  This happens
460  * regardless of whether the DLM got started, so we can't do it
461  * in ocfs2_cluster_disconnect().  The ocfs2_leave_group() function does
462  * the actual work.
463  */
464 void ocfs2_cluster_hangup(const char *group, int grouplen)
465 {
466         BUG_ON(group == NULL);
467         BUG_ON(group[grouplen] != '\0');
468
469         ocfs2_leave_group(group);
470
471         /* cluster_disconnect() was called with hangup_pending==1 */
472         ocfs2_stack_driver_put();
473 }
474 EXPORT_SYMBOL_GPL(ocfs2_cluster_hangup);
475
476 int ocfs2_cluster_this_node(struct ocfs2_cluster_connection *conn,
477                             unsigned int *node)
478 {
479         return active_stack->sp_ops->this_node(conn, node);
480 }
481 EXPORT_SYMBOL_GPL(ocfs2_cluster_this_node);
482
483
484 /*
485  * Sysfs bits
486  */
487
488 static ssize_t ocfs2_max_locking_protocol_show(struct kobject *kobj,
489                                                struct kobj_attribute *attr,
490                                                char *buf)
491 {
492         ssize_t ret = 0;
493
494         spin_lock(&ocfs2_stack_lock);
495         if (locking_max_version.pv_major)
496                 ret = snprintf(buf, PAGE_SIZE, "%u.%u\n",
497                                locking_max_version.pv_major,
498                                locking_max_version.pv_minor);
499         spin_unlock(&ocfs2_stack_lock);
500
501         return ret;
502 }
503
504 static struct kobj_attribute ocfs2_attr_max_locking_protocol =
505         __ATTR(max_locking_protocol, S_IRUGO,
506                ocfs2_max_locking_protocol_show, NULL);
507
508 static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj,
509                                                  struct kobj_attribute *attr,
510                                                  char *buf)
511 {
512         ssize_t ret = 0, total = 0, remain = PAGE_SIZE;
513         struct ocfs2_stack_plugin *p;
514
515         spin_lock(&ocfs2_stack_lock);
516         list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
517                 ret = snprintf(buf, remain, "%s\n",
518                                p->sp_name);
519                 if (ret < 0) {
520                         total = ret;
521                         break;
522                 }
523                 if (ret == remain) {
524                         /* snprintf() didn't fit */
525                         total = -E2BIG;
526                         break;
527                 }
528                 total += ret;
529                 remain -= ret;
530         }
531         spin_unlock(&ocfs2_stack_lock);
532
533         return total;
534 }
535
536 static struct kobj_attribute ocfs2_attr_loaded_cluster_plugins =
537         __ATTR(loaded_cluster_plugins, S_IRUGO,
538                ocfs2_loaded_cluster_plugins_show, NULL);
539
540 static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj,
541                                                 struct kobj_attribute *attr,
542                                                 char *buf)
543 {
544         ssize_t ret = 0;
545
546         spin_lock(&ocfs2_stack_lock);
547         if (active_stack) {
548                 ret = snprintf(buf, PAGE_SIZE, "%s\n",
549                                active_stack->sp_name);
550                 if (ret == PAGE_SIZE)
551                         ret = -E2BIG;
552         }
553         spin_unlock(&ocfs2_stack_lock);
554
555         return ret;
556 }
557
558 static struct kobj_attribute ocfs2_attr_active_cluster_plugin =
559         __ATTR(active_cluster_plugin, S_IRUGO,
560                ocfs2_active_cluster_plugin_show, NULL);
561
562 static ssize_t ocfs2_cluster_stack_show(struct kobject *kobj,
563                                         struct kobj_attribute *attr,
564                                         char *buf)
565 {
566         ssize_t ret;
567         spin_lock(&ocfs2_stack_lock);
568         ret = snprintf(buf, PAGE_SIZE, "%s\n", cluster_stack_name);
569         spin_unlock(&ocfs2_stack_lock);
570
571         return ret;
572 }
573
574 static ssize_t ocfs2_cluster_stack_store(struct kobject *kobj,
575                                          struct kobj_attribute *attr,
576                                          const char *buf, size_t count)
577 {
578         size_t len = count;
579         ssize_t ret;
580
581         if (len == 0)
582                 return len;
583
584         if (buf[len - 1] == '\n')
585                 len--;
586
587         if ((len != OCFS2_STACK_LABEL_LEN) ||
588             (strnlen(buf, len) != len))
589                 return -EINVAL;
590
591         spin_lock(&ocfs2_stack_lock);
592         if (active_stack) {
593                 if (!strncmp(buf, cluster_stack_name, len))
594                         ret = count;
595                 else
596                         ret = -EBUSY;
597         } else {
598                 memcpy(cluster_stack_name, buf, len);
599                 ret = count;
600         }
601         spin_unlock(&ocfs2_stack_lock);
602
603         return ret;
604 }
605
606
607 static struct kobj_attribute ocfs2_attr_cluster_stack =
608         __ATTR(cluster_stack, S_IRUGO | S_IWUSR,
609                ocfs2_cluster_stack_show,
610                ocfs2_cluster_stack_store);
611
612
613
614 static ssize_t ocfs2_dlm_recover_show(struct kobject *kobj,
615                                         struct kobj_attribute *attr,
616                                         char *buf)
617 {
618         return snprintf(buf, PAGE_SIZE, "1\n");
619 }
620
621 static struct kobj_attribute ocfs2_attr_dlm_recover_support =
622         __ATTR(dlm_recover_callback_support, S_IRUGO,
623                ocfs2_dlm_recover_show, NULL);
624
625 static struct attribute *ocfs2_attrs[] = {
626         &ocfs2_attr_max_locking_protocol.attr,
627         &ocfs2_attr_loaded_cluster_plugins.attr,
628         &ocfs2_attr_active_cluster_plugin.attr,
629         &ocfs2_attr_cluster_stack.attr,
630         &ocfs2_attr_dlm_recover_support.attr,
631         NULL,
632 };
633
634 static struct attribute_group ocfs2_attr_group = {
635         .attrs = ocfs2_attrs,
636 };
637
638 static struct kset *ocfs2_kset;
639
640 static void ocfs2_sysfs_exit(void)
641 {
642         kset_unregister(ocfs2_kset);
643 }
644
645 static int ocfs2_sysfs_init(void)
646 {
647         int ret;
648
649         ocfs2_kset = kset_create_and_add("ocfs2", NULL, fs_kobj);
650         if (!ocfs2_kset)
651                 return -ENOMEM;
652
653         ret = sysfs_create_group(&ocfs2_kset->kobj, &ocfs2_attr_group);
654         if (ret)
655                 goto error;
656
657         return 0;
658
659 error:
660         kset_unregister(ocfs2_kset);
661         return ret;
662 }
663
664 /*
665  * Sysctl bits
666  *
667  * The sysctl lives at /proc/sys/fs/ocfs2/nm/hb_ctl_path.  The 'nm' doesn't
668  * make as much sense in a multiple cluster stack world, but it's safer
669  * and easier to preserve the name.
670  */
671
672 #define FS_OCFS2_NM             1
673
674 static struct ctl_table ocfs2_nm_table[] = {
675         {
676                 .procname       = "hb_ctl_path",
677                 .data           = ocfs2_hb_ctl_path,
678                 .maxlen         = OCFS2_MAX_HB_CTL_PATH,
679                 .mode           = 0644,
680                 .proc_handler   = proc_dostring,
681         },
682         { }
683 };
684
685 static struct ctl_table ocfs2_mod_table[] = {
686         {
687                 .procname       = "nm",
688                 .data           = NULL,
689                 .maxlen         = 0,
690                 .mode           = 0555,
691                 .child          = ocfs2_nm_table
692         },
693         { }
694 };
695
696 static struct ctl_table ocfs2_kern_table[] = {
697         {
698                 .procname       = "ocfs2",
699                 .data           = NULL,
700                 .maxlen         = 0,
701                 .mode           = 0555,
702                 .child          = ocfs2_mod_table
703         },
704         { }
705 };
706
707 static struct ctl_table ocfs2_root_table[] = {
708         {
709                 .procname       = "fs",
710                 .data           = NULL,
711                 .maxlen         = 0,
712                 .mode           = 0555,
713                 .child          = ocfs2_kern_table
714         },
715         { }
716 };
717
718 static struct ctl_table_header *ocfs2_table_header;
719
720
721 /*
722  * Initialization
723  */
724
725 static int __init ocfs2_stack_glue_init(void)
726 {
727         strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
728
729         ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
730         if (!ocfs2_table_header) {
731                 printk(KERN_ERR
732                        "ocfs2 stack glue: unable to register sysctl\n");
733                 return -ENOMEM; /* or something. */
734         }
735
736         return ocfs2_sysfs_init();
737 }
738
739 static void __exit ocfs2_stack_glue_exit(void)
740 {
741         memset(&locking_max_version, 0,
742                sizeof(struct ocfs2_protocol_version));
743         locking_max_version.pv_major = 0;
744         locking_max_version.pv_minor = 0;
745         ocfs2_sysfs_exit();
746         if (ocfs2_table_header)
747                 unregister_sysctl_table(ocfs2_table_header);
748 }
749
750 MODULE_AUTHOR("Oracle");
751 MODULE_DESCRIPTION("ocfs2 cluter stack glue layer");
752 MODULE_LICENSE("GPL");
753 module_init(ocfs2_stack_glue_init);
754 module_exit(ocfs2_stack_glue_exit);