aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.com>2014-03-07 14:49:26 -0500
committerGoldwyn Rodrigues <rgoldwyn@suse.com>2015-02-23 08:28:42 -0500
commit47741b7ca7b389d1b45d7cf15edc279c9be32fa8 (patch)
tree828b58d3b18618bfe2bf30fde3e44fb93f6efec2
parent8e854e9cfd1cc3837b4bd96643d5174a72d9f741 (diff)
DLM lock and unlock functions
A dlm_lock_resource is a structure which contains all information required for locking using DLM. The init function allocates the lock and acquires the lock in NL mode. The unlock function converts the lock resource to NL mode. This is done to preserve LVB and for faster processing of locks. The lock resource is DLM unlocked only in the lockres_free function, which is the end of life of the lock resource. Signed-off-by: Lidong Zhong <lzhong@suse.com> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-rw-r--r--drivers/md/md-cluster.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index f377e71949c5..bc8ea9d76875 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -10,6 +10,108 @@
10 10
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/dlm.h>
14#include <linux/sched.h>
15#include "md.h"
16
17#define LVB_SIZE 64
18
19struct dlm_lock_resource {
20 dlm_lockspace_t *ls;
21 struct dlm_lksb lksb;
22 char *name; /* lock name. */
23 uint32_t flags; /* flags to pass to dlm_lock() */
24 void (*bast)(void *arg, int mode); /* blocking AST function pointer*/
25 struct completion completion; /* completion for synchronized locking */
26};
27
28static void sync_ast(void *arg)
29{
30 struct dlm_lock_resource *res;
31
32 res = (struct dlm_lock_resource *) arg;
33 complete(&res->completion);
34}
35
36static int dlm_lock_sync(struct dlm_lock_resource *res, int mode)
37{
38 int ret = 0;
39
40 init_completion(&res->completion);
41 ret = dlm_lock(res->ls, mode, &res->lksb,
42 res->flags, res->name, strlen(res->name),
43 0, sync_ast, res, res->bast);
44 if (ret)
45 return ret;
46 wait_for_completion(&res->completion);
47 return res->lksb.sb_status;
48}
49
50static int dlm_unlock_sync(struct dlm_lock_resource *res)
51{
52 return dlm_lock_sync(res, DLM_LOCK_NL);
53}
54
55static struct dlm_lock_resource *lockres_init(dlm_lockspace_t *lockspace,
56 char *name, void (*bastfn)(void *arg, int mode), int with_lvb)
57{
58 struct dlm_lock_resource *res = NULL;
59 int ret, namelen;
60
61 res = kzalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL);
62 if (!res)
63 return NULL;
64 res->ls = lockspace;
65 namelen = strlen(name);
66 res->name = kzalloc(namelen + 1, GFP_KERNEL);
67 if (!res->name) {
68 pr_err("md-cluster: Unable to allocate resource name for resource %s\n", name);
69 goto out_err;
70 }
71 strlcpy(res->name, name, namelen + 1);
72 if (with_lvb) {
73 res->lksb.sb_lvbptr = kzalloc(LVB_SIZE, GFP_KERNEL);
74 if (!res->lksb.sb_lvbptr) {
75 pr_err("md-cluster: Unable to allocate LVB for resource %s\n", name);
76 goto out_err;
77 }
78 res->flags = DLM_LKF_VALBLK;
79 }
80
81 if (bastfn)
82 res->bast = bastfn;
83
84 res->flags |= DLM_LKF_EXPEDITE;
85
86 ret = dlm_lock_sync(res, DLM_LOCK_NL);
87 if (ret) {
88 pr_err("md-cluster: Unable to lock NL on new lock resource %s\n", name);
89 goto out_err;
90 }
91 res->flags &= ~DLM_LKF_EXPEDITE;
92 res->flags |= DLM_LKF_CONVERT;
93
94 return res;
95out_err:
96 kfree(res->lksb.sb_lvbptr);
97 kfree(res->name);
98 kfree(res);
99 return NULL;
100}
101
102static void lockres_free(struct dlm_lock_resource *res)
103{
104 if (!res)
105 return;
106
107 init_completion(&res->completion);
108 dlm_unlock(res->ls, res->lksb.sb_lkid, 0, &res->lksb, res);
109 wait_for_completion(&res->completion);
110
111 kfree(res->name);
112 kfree(res->lksb.sb_lvbptr);
113 kfree(res);
114}
13 115
14static int __init cluster_init(void) 116static int __init cluster_init(void)
15{ 117{