ocfs2: Create ocfs2_stack_operations and split out the o2cb stack.
[linux-3.10.git] / fs / ocfs2 / stackglue.c
1 /* -*- mode: c; c-basic-offset: 8; -*-
2  * vim: noexpandtab sw=8 ts=8 sts=0:
3  *
4  * stackglue.c
5  *
6  * Code which implements an OCFS2 specific interface to underlying
7  * cluster stacks.
8  *
9  * Copyright (C) 2007 Oracle.  All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  */
20
21 #include <linux/slab.h>
22 #include <linux/kmod.h>
23
24 /* Needed for AOP_TRUNCATED_PAGE in mlog_errno() */
25 #include <linux/fs.h>
26
27 #include "cluster/masklog.h"
28
29 #include "stackglue.h"
30
31 struct ocfs2_locking_protocol *stack_glue_lproto;
32
33
34 int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
35                    int mode,
36                    union ocfs2_dlm_lksb *lksb,
37                    u32 flags,
38                    void *name,
39                    unsigned int namelen,
40                    void *astarg)
41 {
42         BUG_ON(stack_glue_lproto == NULL);
43
44         return o2cb_stack_ops.dlm_lock(conn, mode, lksb, flags,
45                                        name, namelen, astarg);
46 }
47
48 int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
49                      union ocfs2_dlm_lksb *lksb,
50                      u32 flags,
51                      void *astarg)
52 {
53         BUG_ON(stack_glue_lproto == NULL);
54
55         return o2cb_stack_ops.dlm_unlock(conn, lksb, flags, astarg);
56 }
57
58 int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb)
59 {
60         return o2cb_stack_ops.lock_status(lksb);
61 }
62
63 /*
64  * Why don't we cast to ocfs2_meta_lvb?  The "clean" answer is that we
65  * don't cast at the glue level.  The real answer is that the header
66  * ordering is nigh impossible.
67  */
68 void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb)
69 {
70         return o2cb_stack_ops.lock_lvb(lksb);
71 }
72
73 void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb)
74 {
75         o2cb_stack_ops.dump_lksb(lksb);
76 }
77
78 int ocfs2_cluster_connect(const char *group,
79                           int grouplen,
80                           void (*recovery_handler)(int node_num,
81                                                    void *recovery_data),
82                           void *recovery_data,
83                           struct ocfs2_cluster_connection **conn)
84 {
85         int rc = 0;
86         struct ocfs2_cluster_connection *new_conn;
87
88         BUG_ON(group == NULL);
89         BUG_ON(conn == NULL);
90         BUG_ON(recovery_handler == NULL);
91
92         if (grouplen > GROUP_NAME_MAX) {
93                 rc = -EINVAL;
94                 goto out;
95         }
96
97         new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection),
98                            GFP_KERNEL);
99         if (!new_conn) {
100                 rc = -ENOMEM;
101                 goto out;
102         }
103
104         memcpy(new_conn->cc_name, group, grouplen);
105         new_conn->cc_namelen = grouplen;
106         new_conn->cc_recovery_handler = recovery_handler;
107         new_conn->cc_recovery_data = recovery_data;
108
109         /* Start the new connection at our maximum compatibility level */
110         new_conn->cc_version = stack_glue_lproto->lp_max_version;
111
112         rc = o2cb_stack_ops.connect(new_conn);
113         if (rc) {
114                 mlog_errno(rc);
115                 goto out_free;
116         }
117
118         *conn = new_conn;
119
120 out_free:
121         if (rc)
122                 kfree(new_conn);
123
124 out:
125         return rc;
126 }
127
128 int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn)
129 {
130         int ret;
131
132         BUG_ON(conn == NULL);
133
134         ret = o2cb_stack_ops.disconnect(conn);
135
136         /* XXX Should we free it anyway? */
137         if (!ret)
138                 kfree(conn);
139
140         return ret;
141 }
142
143 void ocfs2_cluster_hangup(const char *group, int grouplen)
144 {
145         BUG_ON(group == NULL);
146         BUG_ON(group[grouplen] != '\0');
147
148         o2cb_stack_ops.hangup(group, grouplen);
149 }
150
151 int ocfs2_cluster_this_node(unsigned int *node)
152 {
153         return o2cb_stack_ops.this_node(node);
154 }
155
156 void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto)
157 {
158         BUG_ON(proto != NULL);
159
160         stack_glue_lproto = proto;
161 }
162