blob: e2235600a72bd5ba92ce664d0a84cdd0bb12efb5 [file] [log] [blame]
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001/*
2 * Copyright (C) 2015, SUSE
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 */
10
11
12#include <linux/module.h>
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -060013#include <linux/dlm.h>
14#include <linux/sched.h>
15#include "md.h"
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -050016#include "md-cluster.h"
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -060017
18#define LVB_SIZE 64
19
20struct dlm_lock_resource {
21 dlm_lockspace_t *ls;
22 struct dlm_lksb lksb;
23 char *name; /* lock name. */
24 uint32_t flags; /* flags to pass to dlm_lock() */
25 void (*bast)(void *arg, int mode); /* blocking AST function pointer*/
26 struct completion completion; /* completion for synchronized locking */
27};
28
29static void sync_ast(void *arg)
30{
31 struct dlm_lock_resource *res;
32
33 res = (struct dlm_lock_resource *) arg;
34 complete(&res->completion);
35}
36
37static int dlm_lock_sync(struct dlm_lock_resource *res, int mode)
38{
39 int ret = 0;
40
41 init_completion(&res->completion);
42 ret = dlm_lock(res->ls, mode, &res->lksb,
43 res->flags, res->name, strlen(res->name),
44 0, sync_ast, res, res->bast);
45 if (ret)
46 return ret;
47 wait_for_completion(&res->completion);
48 return res->lksb.sb_status;
49}
50
51static int dlm_unlock_sync(struct dlm_lock_resource *res)
52{
53 return dlm_lock_sync(res, DLM_LOCK_NL);
54}
55
56static struct dlm_lock_resource *lockres_init(dlm_lockspace_t *lockspace,
57 char *name, void (*bastfn)(void *arg, int mode), int with_lvb)
58{
59 struct dlm_lock_resource *res = NULL;
60 int ret, namelen;
61
62 res = kzalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL);
63 if (!res)
64 return NULL;
65 res->ls = lockspace;
66 namelen = strlen(name);
67 res->name = kzalloc(namelen + 1, GFP_KERNEL);
68 if (!res->name) {
69 pr_err("md-cluster: Unable to allocate resource name for resource %s\n", name);
70 goto out_err;
71 }
72 strlcpy(res->name, name, namelen + 1);
73 if (with_lvb) {
74 res->lksb.sb_lvbptr = kzalloc(LVB_SIZE, GFP_KERNEL);
75 if (!res->lksb.sb_lvbptr) {
76 pr_err("md-cluster: Unable to allocate LVB for resource %s\n", name);
77 goto out_err;
78 }
79 res->flags = DLM_LKF_VALBLK;
80 }
81
82 if (bastfn)
83 res->bast = bastfn;
84
85 res->flags |= DLM_LKF_EXPEDITE;
86
87 ret = dlm_lock_sync(res, DLM_LOCK_NL);
88 if (ret) {
89 pr_err("md-cluster: Unable to lock NL on new lock resource %s\n", name);
90 goto out_err;
91 }
92 res->flags &= ~DLM_LKF_EXPEDITE;
93 res->flags |= DLM_LKF_CONVERT;
94
95 return res;
96out_err:
97 kfree(res->lksb.sb_lvbptr);
98 kfree(res->name);
99 kfree(res);
100 return NULL;
101}
102
103static void lockres_free(struct dlm_lock_resource *res)
104{
105 if (!res)
106 return;
107
108 init_completion(&res->completion);
109 dlm_unlock(res->ls, res->lksb.sb_lkid, 0, &res->lksb, res);
110 wait_for_completion(&res->completion);
111
112 kfree(res->name);
113 kfree(res->lksb.sb_lvbptr);
114 kfree(res);
115}
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -0600116
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -0500117static int join(struct mddev *mddev, int nodes)
118{
119 return 0;
120}
121
122static int leave(struct mddev *mddev)
123{
124 return 0;
125}
126
127static struct md_cluster_operations cluster_ops = {
128 .join = join,
129 .leave = leave,
130};
131
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -0600132static int __init cluster_init(void)
133{
134 pr_warn("md-cluster: EXPERIMENTAL. Use with caution\n");
135 pr_info("Registering Cluster MD functions\n");
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -0500136 register_md_cluster_operations(&cluster_ops, THIS_MODULE);
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -0600137 return 0;
138}
139
140static void cluster_exit(void)
141{
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -0500142 unregister_md_cluster_operations();
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -0600143}
144
145module_init(cluster_init);
146module_exit(cluster_exit);
147MODULE_LICENSE("GPL");
148MODULE_DESCRIPTION("Clustering support for MD");