Introduce md_cluster_operations to handle cluster functions
authorGoldwyn Rodrigues <rgoldwyn@suse.com>
Sat, 29 Mar 2014 15:01:53 +0000 (10:01 -0500)
committerGoldwyn Rodrigues <rgoldwyn@suse.com>
Mon, 23 Feb 2015 13:28:42 +0000 (07:28 -0600)
This allows dynamic registering of cluster hooks.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
drivers/md/md-cluster.c
drivers/md/md-cluster.h [new file with mode: 0644]
drivers/md/md.c
drivers/md/md.h

index bc8ea9d768754bf1f029c62ee58f8257e16150af..e2235600a72bd5ba92ce664d0a84cdd0bb12efb5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/dlm.h>
 #include <linux/sched.h>
 #include "md.h"
+#include "md-cluster.h"
 
 #define LVB_SIZE       64
 
@@ -113,15 +114,32 @@ static void lockres_free(struct dlm_lock_resource *res)
        kfree(res);
 }
 
+static int join(struct mddev *mddev, int nodes)
+{
+       return 0;
+}
+
+static int leave(struct mddev *mddev)
+{
+       return 0;
+}
+
+static struct md_cluster_operations cluster_ops = {
+       .join   = join,
+       .leave  = leave,
+};
+
 static int __init cluster_init(void)
 {
        pr_warn("md-cluster: EXPERIMENTAL. Use with caution\n");
        pr_info("Registering Cluster MD functions\n");
+       register_md_cluster_operations(&cluster_ops, THIS_MODULE);
        return 0;
 }
 
 static void cluster_exit(void)
 {
+       unregister_md_cluster_operations();
 }
 
 module_init(cluster_init);
diff --git a/drivers/md/md-cluster.h b/drivers/md/md-cluster.h
new file mode 100644 (file)
index 0000000..aa9f07b
--- /dev/null
@@ -0,0 +1,15 @@
+
+
+#ifndef _MD_CLUSTER_H
+#define _MD_CLUSTER_H
+
+#include "md.h"
+
+struct mddev;
+
+struct md_cluster_operations {
+       int (*join)(struct mddev *mddev);
+       int (*leave)(struct mddev *mddev);
+};
+
+#endif /* _MD_CLUSTER_H */
index c8d2bac4e28be4a65edb63d613b0336b7ff35783..57ecb51ec5fdf406e07b6d02ca67309bcde824b9 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/slab.h>
 #include "md.h"
 #include "bitmap.h"
+#include "md-cluster.h"
 
 #ifndef MODULE
 static void autostart_arrays(int part);
@@ -66,6 +67,10 @@ static void autostart_arrays(int part);
 static LIST_HEAD(pers_list);
 static DEFINE_SPINLOCK(pers_lock);
 
+struct md_cluster_operations *md_cluster_ops;
+struct module *md_cluster_mod;
+EXPORT_SYMBOL(md_cluster_mod);
+
 static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
 static struct workqueue_struct *md_wq;
 static struct workqueue_struct *md_misc_wq;
@@ -7231,6 +7236,53 @@ int unregister_md_personality(struct md_personality *p)
 }
 EXPORT_SYMBOL(unregister_md_personality);
 
+int register_md_cluster_operations(struct md_cluster_operations *ops, struct module *module)
+{
+       if (md_cluster_ops != NULL)
+               return -EALREADY;
+       spin_lock(&pers_lock);
+       md_cluster_ops = ops;
+       md_cluster_mod = module;
+       spin_unlock(&pers_lock);
+       return 0;
+}
+EXPORT_SYMBOL(register_md_cluster_operations);
+
+int unregister_md_cluster_operations(void)
+{
+       spin_lock(&pers_lock);
+       md_cluster_ops = NULL;
+       spin_unlock(&pers_lock);
+       return 0;
+}
+EXPORT_SYMBOL(unregister_md_cluster_operations);
+
+int md_setup_cluster(struct mddev *mddev, int nodes)
+{
+       int err;
+
+       err = request_module("md-cluster");
+       if (err) {
+               pr_err("md-cluster module not found.\n");
+               return err;
+       }
+
+       spin_lock(&pers_lock);
+       if (!md_cluster_ops || !try_module_get(md_cluster_mod)) {
+               spin_unlock(&pers_lock);
+               return -ENOENT;
+       }
+       spin_unlock(&pers_lock);
+
+       return md_cluster_ops->join(mddev);
+}
+
+void md_cluster_stop(struct mddev *mddev)
+{
+       md_cluster_ops->leave(mddev);
+       module_put(md_cluster_mod);
+}
+
 static int is_mddev_idle(struct mddev *mddev, int init)
 {
        struct md_rdev *rdev;
index 318ca8fd430f1f9cd422d84cde77ac6a1fff435a..018593197c4d9a1053d4fa5f45bf4145e03b2d95 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/timer.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
+#include "md-cluster.h"
 
 #define MaxSector (~(sector_t)0)
 
@@ -608,6 +609,11 @@ static inline void safe_put_page(struct page *p)
 
 extern int register_md_personality(struct md_personality *p);
 extern int unregister_md_personality(struct md_personality *p);
+extern int register_md_cluster_operations(struct md_cluster_operations *ops,
+               struct module *module);
+extern int unregister_md_cluster_operations(void);
+extern int md_setup_cluster(struct mddev *mddev, int nodes);
+extern void md_cluster_stop(struct mddev *mddev);
 extern struct md_thread *md_register_thread(
        void (*run)(struct md_thread *thread),
        struct mddev *mddev,
@@ -669,4 +675,5 @@ static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev)
        }
 }
 
+extern struct md_cluster_operations *md_cluster_ops;
 #endif /* _MD_MD_H */