root/fs/ocfs2/stackglue.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ocfs2_stack_lookup
  2. ocfs2_stack_driver_request
  3. ocfs2_stack_driver_get
  4. ocfs2_stack_driver_put
  5. ocfs2_stack_glue_register
  6. ocfs2_stack_glue_unregister
  7. ocfs2_stack_glue_set_max_proto_version
  8. ocfs2_dlm_lock
  9. ocfs2_dlm_unlock
  10. ocfs2_dlm_lock_status
  11. ocfs2_dlm_lvb_valid
  12. ocfs2_dlm_lvb
  13. ocfs2_dlm_dump_lksb
  14. ocfs2_stack_supports_plocks
  15. ocfs2_plock
  16. ocfs2_cluster_connect
  17. ocfs2_cluster_connect_agnostic
  18. ocfs2_cluster_disconnect
  19. ocfs2_leave_group
  20. ocfs2_cluster_hangup
  21. ocfs2_cluster_this_node
  22. ocfs2_max_locking_protocol_show
  23. ocfs2_loaded_cluster_plugins_show
  24. ocfs2_active_cluster_plugin_show
  25. ocfs2_cluster_stack_show
  26. ocfs2_cluster_stack_store
  27. ocfs2_dlm_recover_show
  28. ocfs2_sysfs_exit
  29. ocfs2_sysfs_init
  30. ocfs2_stack_glue_init
  31. ocfs2_stack_glue_exit

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

/* [<][>][^][v][top][bottom][index][help] */