Linux 3.2.87
[pandora-kernel.git] / 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 *group,
319                           int grouplen,
320                           struct ocfs2_locking_protocol *lproto,
321                           void (*recovery_handler)(int node_num,
322                                                    void *recovery_data),
323                           void *recovery_data,
324                           struct ocfs2_cluster_connection **conn)
325 {
326         int rc = 0;
327         struct ocfs2_cluster_connection *new_conn;
328
329         BUG_ON(group == NULL);
330         BUG_ON(conn == NULL);
331         BUG_ON(recovery_handler == NULL);
332
333         if (grouplen > GROUP_NAME_MAX) {
334                 rc = -EINVAL;
335                 goto out;
336         }
337
338         if (memcmp(&lproto->lp_max_version, &locking_max_version,
339                    sizeof(struct ocfs2_protocol_version))) {
340                 rc = -EINVAL;
341                 goto out;
342         }
343
344         new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection),
345                            GFP_KERNEL);
346         if (!new_conn) {
347                 rc = -ENOMEM;
348                 goto out;
349         }
350
351         memcpy(new_conn->cc_name, group, grouplen);
352         new_conn->cc_namelen = grouplen;
353         new_conn->cc_recovery_handler = recovery_handler;
354         new_conn->cc_recovery_data = recovery_data;
355
356         new_conn->cc_proto = lproto;
357         /* Start the new connection at our maximum compatibility level */
358         new_conn->cc_version = lproto->lp_max_version;
359
360         /* This will pin the stack driver if successful */
361         rc = ocfs2_stack_driver_get(stack_name);
362         if (rc)
363                 goto out_free;
364
365         rc = active_stack->sp_ops->connect(new_conn);
366         if (rc) {
367                 ocfs2_stack_driver_put();
368                 goto out_free;
369         }
370
371         *conn = new_conn;
372
373 out_free:
374         if (rc)
375                 kfree(new_conn);
376
377 out:
378         return rc;
379 }
380 EXPORT_SYMBOL_GPL(ocfs2_cluster_connect);
381
382 /* The caller will ensure all nodes have the same cluster stack */
383 int ocfs2_cluster_connect_agnostic(const char *group,
384                                    int grouplen,
385                                    struct ocfs2_locking_protocol *lproto,
386                                    void (*recovery_handler)(int node_num,
387                                                             void *recovery_data),
388                                    void *recovery_data,
389                                    struct ocfs2_cluster_connection **conn)
390 {
391         char *stack_name = NULL;
392
393         if (cluster_stack_name[0])
394                 stack_name = cluster_stack_name;
395         return ocfs2_cluster_connect(stack_name, group, grouplen, lproto,
396                                      recovery_handler, recovery_data, conn);
397 }
398 EXPORT_SYMBOL_GPL(ocfs2_cluster_connect_agnostic);
399
400 /* If hangup_pending is 0, the stack driver will be dropped */
401 int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
402                              int hangup_pending)
403 {
404         int ret;
405
406         BUG_ON(conn == NULL);
407
408         ret = active_stack->sp_ops->disconnect(conn);
409
410         /* XXX Should we free it anyway? */
411         if (!ret) {
412                 kfree(conn);
413                 if (!hangup_pending)
414                         ocfs2_stack_driver_put();
415         }
416
417         return ret;
418 }
419 EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect);
420
421 /*
422  * Leave the group for this filesystem.  This is executed by a userspace
423  * program (stored in ocfs2_hb_ctl_path).
424  */
425 static void ocfs2_leave_group(const char *group)
426 {
427         int ret;
428         char *argv[5], *envp[3];
429
430         argv[0] = ocfs2_hb_ctl_path;
431         argv[1] = "-K";
432         argv[2] = "-u";
433         argv[3] = (char *)group;
434         argv[4] = NULL;
435
436         /* minimal command environment taken from cpu_run_sbin_hotplug */
437         envp[0] = "HOME=/";
438         envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
439         envp[2] = NULL;
440
441         ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
442         if (ret < 0) {
443                 printk(KERN_ERR
444                        "ocfs2: Error %d running user helper "
445                        "\"%s %s %s %s\"\n",
446                        ret, argv[0], argv[1], argv[2], argv[3]);
447         }
448 }
449
450 /*
451  * Hangup is a required post-umount.  ocfs2-tools software expects the
452  * filesystem to call "ocfs2_hb_ctl" during unmount.  This happens
453  * regardless of whether the DLM got started, so we can't do it
454  * in ocfs2_cluster_disconnect().  The ocfs2_leave_group() function does
455  * the actual work.
456  */
457 void ocfs2_cluster_hangup(const char *group, int grouplen)
458 {
459         BUG_ON(group == NULL);
460         BUG_ON(group[grouplen] != '\0');
461
462         ocfs2_leave_group(group);
463
464         /* cluster_disconnect() was called with hangup_pending==1 */
465         ocfs2_stack_driver_put();
466 }
467 EXPORT_SYMBOL_GPL(ocfs2_cluster_hangup);
468
469 int ocfs2_cluster_this_node(unsigned int *node)
470 {
471         return active_stack->sp_ops->this_node(node);
472 }
473 EXPORT_SYMBOL_GPL(ocfs2_cluster_this_node);
474
475
476 /*
477  * Sysfs bits
478  */
479
480 static ssize_t ocfs2_max_locking_protocol_show(struct kobject *kobj,
481                                                struct kobj_attribute *attr,
482                                                char *buf)
483 {
484         ssize_t ret = 0;
485
486         spin_lock(&ocfs2_stack_lock);
487         if (locking_max_version.pv_major)
488                 ret = snprintf(buf, PAGE_SIZE, "%u.%u\n",
489                                locking_max_version.pv_major,
490                                locking_max_version.pv_minor);
491         spin_unlock(&ocfs2_stack_lock);
492
493         return ret;
494 }
495
496 static struct kobj_attribute ocfs2_attr_max_locking_protocol =
497         __ATTR(max_locking_protocol, S_IFREG | S_IRUGO,
498                ocfs2_max_locking_protocol_show, NULL);
499
500 static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj,
501                                                  struct kobj_attribute *attr,
502                                                  char *buf)
503 {
504         ssize_t ret = 0, total = 0, remain = PAGE_SIZE;
505         struct ocfs2_stack_plugin *p;
506
507         spin_lock(&ocfs2_stack_lock);
508         list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
509                 ret = snprintf(buf, remain, "%s\n",
510                                p->sp_name);
511                 if (ret < 0) {
512                         total = ret;
513                         break;
514                 }
515                 if (ret == remain) {
516                         /* snprintf() didn't fit */
517                         total = -E2BIG;
518                         break;
519                 }
520                 total += ret;
521                 remain -= ret;
522         }
523         spin_unlock(&ocfs2_stack_lock);
524
525         return total;
526 }
527
528 static struct kobj_attribute ocfs2_attr_loaded_cluster_plugins =
529         __ATTR(loaded_cluster_plugins, S_IFREG | S_IRUGO,
530                ocfs2_loaded_cluster_plugins_show, NULL);
531
532 static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj,
533                                                 struct kobj_attribute *attr,
534                                                 char *buf)
535 {
536         ssize_t ret = 0;
537
538         spin_lock(&ocfs2_stack_lock);
539         if (active_stack) {
540                 ret = snprintf(buf, PAGE_SIZE, "%s\n",
541                                active_stack->sp_name);
542                 if (ret == PAGE_SIZE)
543                         ret = -E2BIG;
544         }
545         spin_unlock(&ocfs2_stack_lock);
546
547         return ret;
548 }
549
550 static struct kobj_attribute ocfs2_attr_active_cluster_plugin =
551         __ATTR(active_cluster_plugin, S_IFREG | S_IRUGO,
552                ocfs2_active_cluster_plugin_show, NULL);
553
554 static ssize_t ocfs2_cluster_stack_show(struct kobject *kobj,
555                                         struct kobj_attribute *attr,
556                                         char *buf)
557 {
558         ssize_t ret;
559         spin_lock(&ocfs2_stack_lock);
560         ret = snprintf(buf, PAGE_SIZE, "%s\n", cluster_stack_name);
561         spin_unlock(&ocfs2_stack_lock);
562
563         return ret;
564 }
565
566 static ssize_t ocfs2_cluster_stack_store(struct kobject *kobj,
567                                          struct kobj_attribute *attr,
568                                          const char *buf, size_t count)
569 {
570         size_t len = count;
571         ssize_t ret;
572
573         if (len == 0)
574                 return len;
575
576         if (buf[len - 1] == '\n')
577                 len--;
578
579         if ((len != OCFS2_STACK_LABEL_LEN) ||
580             (strnlen(buf, len) != len))
581                 return -EINVAL;
582
583         spin_lock(&ocfs2_stack_lock);
584         if (active_stack) {
585                 if (!strncmp(buf, cluster_stack_name, len))
586                         ret = count;
587                 else
588                         ret = -EBUSY;
589         } else {
590                 memcpy(cluster_stack_name, buf, len);
591                 ret = count;
592         }
593         spin_unlock(&ocfs2_stack_lock);
594
595         return ret;
596 }
597
598
599 static struct kobj_attribute ocfs2_attr_cluster_stack =
600         __ATTR(cluster_stack, S_IFREG | S_IRUGO | S_IWUSR,
601                ocfs2_cluster_stack_show,
602                ocfs2_cluster_stack_store);
603
604 static struct attribute *ocfs2_attrs[] = {
605         &ocfs2_attr_max_locking_protocol.attr,
606         &ocfs2_attr_loaded_cluster_plugins.attr,
607         &ocfs2_attr_active_cluster_plugin.attr,
608         &ocfs2_attr_cluster_stack.attr,
609         NULL,
610 };
611
612 static struct attribute_group ocfs2_attr_group = {
613         .attrs = ocfs2_attrs,
614 };
615
616 static struct kset *ocfs2_kset;
617
618 static void ocfs2_sysfs_exit(void)
619 {
620         kset_unregister(ocfs2_kset);
621 }
622
623 static int ocfs2_sysfs_init(void)
624 {
625         int ret;
626
627         ocfs2_kset = kset_create_and_add("ocfs2", NULL, fs_kobj);
628         if (!ocfs2_kset)
629                 return -ENOMEM;
630
631         ret = sysfs_create_group(&ocfs2_kset->kobj, &ocfs2_attr_group);
632         if (ret)
633                 goto error;
634
635         return 0;
636
637 error:
638         kset_unregister(ocfs2_kset);
639         return ret;
640 }
641
642 /*
643  * Sysctl bits
644  *
645  * The sysctl lives at /proc/sys/fs/ocfs2/nm/hb_ctl_path.  The 'nm' doesn't
646  * make as much sense in a multiple cluster stack world, but it's safer
647  * and easier to preserve the name.
648  */
649
650 #define FS_OCFS2_NM             1
651
652 static ctl_table ocfs2_nm_table[] = {
653         {
654                 .procname       = "hb_ctl_path",
655                 .data           = ocfs2_hb_ctl_path,
656                 .maxlen         = OCFS2_MAX_HB_CTL_PATH,
657                 .mode           = 0644,
658                 .proc_handler   = proc_dostring,
659         },
660         { }
661 };
662
663 static ctl_table ocfs2_mod_table[] = {
664         {
665                 .procname       = "nm",
666                 .data           = NULL,
667                 .maxlen         = 0,
668                 .mode           = 0555,
669                 .child          = ocfs2_nm_table
670         },
671         { }
672 };
673
674 static ctl_table ocfs2_kern_table[] = {
675         {
676                 .procname       = "ocfs2",
677                 .data           = NULL,
678                 .maxlen         = 0,
679                 .mode           = 0555,
680                 .child          = ocfs2_mod_table
681         },
682         { }
683 };
684
685 static ctl_table ocfs2_root_table[] = {
686         {
687                 .procname       = "fs",
688                 .data           = NULL,
689                 .maxlen         = 0,
690                 .mode           = 0555,
691                 .child          = ocfs2_kern_table
692         },
693         { }
694 };
695
696 static struct ctl_table_header *ocfs2_table_header = NULL;
697
698
699 /*
700  * Initialization
701  */
702
703 static int __init ocfs2_stack_glue_init(void)
704 {
705         strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
706
707         ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
708         if (!ocfs2_table_header) {
709                 printk(KERN_ERR
710                        "ocfs2 stack glue: unable to register sysctl\n");
711                 return -ENOMEM; /* or something. */
712         }
713
714         return ocfs2_sysfs_init();
715 }
716
717 static void __exit ocfs2_stack_glue_exit(void)
718 {
719         memset(&locking_max_version, 0,
720                sizeof(struct ocfs2_protocol_version));
721         locking_max_version.pv_major = 0;
722         locking_max_version.pv_minor = 0;
723         ocfs2_sysfs_exit();
724         if (ocfs2_table_header)
725                 unregister_sysctl_table(ocfs2_table_header);
726 }
727
728 MODULE_AUTHOR("Oracle");
729 MODULE_DESCRIPTION("ocfs2 cluter stack glue layer");
730 MODULE_LICENSE("GPL");
731 module_init(ocfs2_stack_glue_init);
732 module_exit(ocfs2_stack_glue_exit);