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