]> Pileus Git - ~andy/linux/blob - fs/gfs2/locking/nolock/main.c
[GFS2] The lock modules for GFS2
[~andy/linux] / fs / gfs2 / locking / nolock / main.c
1 /******************************************************************************
2 *******************************************************************************
3 **
4 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
5 **  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
6 **
7 **  This copyrighted material is made available to anyone wishing to use,
8 **  modify, copy, or redistribute it subject to the terms and conditions
9 **  of the GNU General Public License v.2.
10 **
11 *******************************************************************************
12 ******************************************************************************/
13
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/types.h>
19 #include <linux/fs.h>
20 #include <linux/smp_lock.h>
21
22 #include "../../lm_interface.h"
23
24 struct nolock_lockspace {
25         unsigned int nl_lvb_size;
26 };
27
28 struct lm_lockops nolock_ops;
29
30 /**
31  * nolock_mount - mount a nolock lockspace
32  * @table_name: the name of the space to mount
33  * @host_data: host specific data
34  * @cb: the callback
35  * @fsdata:
36  * @min_lvb_size:
37  * @flags:
38  * @lockstruct: the structure of crap to fill in
39  *
40  * Returns: 0 on success, -EXXX on failure
41  */
42
43 static int nolock_mount(char *table_name, char *host_data,
44                         lm_callback_t cb, lm_fsdata_t *fsdata,
45                         unsigned int min_lvb_size, int flags,
46                         struct lm_lockstruct *lockstruct)
47 {
48         char *c;
49         unsigned int jid;
50         struct nolock_lockspace *nl;
51
52         /* If there is a "jid=" in the hostdata, return that jid.
53            Otherwise, return zero. */
54
55         c = strstr(host_data, "jid=");
56         if (!c)
57                 jid = 0;
58         else {
59                 c += 4;
60                 sscanf(c, "%u", &jid);
61         }
62
63         nl = kmalloc(sizeof(struct nolock_lockspace), GFP_KERNEL);
64         if (!nl)
65                 return -ENOMEM;
66
67         memset(nl, 0, sizeof(struct nolock_lockspace));
68         nl->nl_lvb_size = min_lvb_size;
69
70         lockstruct->ls_jid = jid;
71         lockstruct->ls_first = 1;
72         lockstruct->ls_lvb_size = min_lvb_size;
73         lockstruct->ls_lockspace = (lm_lockspace_t *)nl;
74         lockstruct->ls_ops = &nolock_ops;
75         lockstruct->ls_flags = LM_LSFLAG_LOCAL;
76
77         return 0;
78 }
79
80 /**
81  * nolock_others_may_mount - unmount a lock space
82  * @lockspace: the lockspace to unmount
83  *
84  */
85
86 static void nolock_others_may_mount(lm_lockspace_t *lockspace)
87 {
88 }
89
90 /**
91  * nolock_unmount - unmount a lock space
92  * @lockspace: the lockspace to unmount
93  *
94  */
95
96 static void nolock_unmount(lm_lockspace_t *lockspace)
97 {
98         struct nolock_lockspace *nl = (struct nolock_lockspace *)lockspace;
99         kfree(nl);
100 }
101
102 /**
103  * nolock_withdraw - withdraw from a lock space
104  * @lockspace: the lockspace
105  *
106  */
107
108 static void nolock_withdraw(lm_lockspace_t *lockspace)
109 {
110 }
111
112 /**
113  * nolock_get_lock - get a lm_lock_t given a descripton of the lock
114  * @lockspace: the lockspace the lock lives in
115  * @name: the name of the lock
116  * @lockp: return the lm_lock_t here
117  *
118  * Returns: 0 on success, -EXXX on failure
119  */
120
121 static int nolock_get_lock(lm_lockspace_t *lockspace, struct lm_lockname *name,
122                            lm_lock_t **lockp)
123 {
124         *lockp = (lm_lock_t *)lockspace;
125         return 0;
126 }
127
128 /**
129  * nolock_put_lock - get rid of a lock structure
130  * @lock: the lock to throw away
131  *
132  */
133
134 static void nolock_put_lock(lm_lock_t *lock)
135 {
136 }
137
138 /**
139  * nolock_lock - acquire a lock
140  * @lock: the lock to manipulate
141  * @cur_state: the current state
142  * @req_state: the requested state
143  * @flags: modifier flags
144  *
145  * Returns: A bitmap of LM_OUT_*
146  */
147
148 static unsigned int nolock_lock(lm_lock_t *lock, unsigned int cur_state,
149                                 unsigned int req_state, unsigned int flags)
150 {
151         return req_state | LM_OUT_CACHEABLE;
152 }
153
154 /**
155  * nolock_unlock - unlock a lock
156  * @lock: the lock to manipulate
157  * @cur_state: the current state
158  *
159  * Returns: 0
160  */
161
162 static unsigned int nolock_unlock(lm_lock_t *lock, unsigned int cur_state)
163 {
164         return 0;
165 }
166
167 /**
168  * nolock_cancel - cancel a request on a lock
169  * @lock: the lock to cancel request for
170  *
171  */
172
173 static void nolock_cancel(lm_lock_t *lock)
174 {
175 }
176
177 /**
178  * nolock_hold_lvb - hold on to a lock value block
179  * @lock: the lock the LVB is associated with
180  * @lvbp: return the lm_lvb_t here
181  *
182  * Returns: 0 on success, -EXXX on failure
183  */
184
185 static int nolock_hold_lvb(lm_lock_t *lock, char **lvbp)
186 {
187         struct nolock_lockspace *nl = (struct nolock_lockspace *)lock;
188         int error = 0;
189
190         *lvbp = kmalloc(nl->nl_lvb_size, GFP_KERNEL);
191         if (*lvbp)
192                 memset(*lvbp, 0, nl->nl_lvb_size);
193         else
194                 error = -ENOMEM;
195
196         return error;
197 }
198
199 /**
200  * nolock_unhold_lvb - release a LVB
201  * @lock: the lock the LVB is associated with
202  * @lvb: the lock value block
203  *
204  */
205
206 static void nolock_unhold_lvb(lm_lock_t *lock, char *lvb)
207 {
208         kfree(lvb);
209 }
210
211 /**
212  * nolock_sync_lvb - sync out the value of a lvb
213  * @lock: the lock the LVB is associated with
214  * @lvb: the lock value block
215  *
216  */
217
218 static void nolock_sync_lvb(lm_lock_t *lock, char *lvb)
219 {
220 }
221
222 /**
223  * nolock_plock_get -
224  * @lockspace: the lockspace
225  * @name:
226  * @file:
227  * @fl:
228  *
229  * Returns: errno
230  */
231
232 static int nolock_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name,
233                             struct file *file, struct file_lock *fl)
234 {
235         struct file_lock *tmp;
236
237         lock_kernel();
238         tmp = posix_test_lock(file, fl);
239         fl->fl_type = F_UNLCK;
240         if (tmp)
241                 memcpy(fl, tmp, sizeof(struct file_lock));
242         unlock_kernel();
243
244         return 0;
245 }
246
247 /**
248  * nolock_plock -
249  * @lockspace: the lockspace
250  * @name:
251  * @file:
252  * @cmd:
253  * @fl:
254  *
255  * Returns: errno
256  */
257
258 static int nolock_plock(lm_lockspace_t *lockspace, struct lm_lockname *name,
259                         struct file *file, int cmd, struct file_lock *fl)
260 {
261         int error;
262         lock_kernel();
263         error = posix_lock_file_wait(file, fl);
264         unlock_kernel();
265         return error;
266 }
267
268 /**
269  * nolock_punlock -
270  * @lockspace: the lockspace
271  * @name:
272  * @file:
273  * @fl:
274  *
275  * Returns: errno
276  */
277
278 static int nolock_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name,
279                           struct file *file, struct file_lock *fl)
280 {
281         int error;
282         lock_kernel();
283         error = posix_lock_file_wait(file, fl);
284         unlock_kernel();
285         return error;
286 }
287
288 /**
289  * nolock_recovery_done - reset the expired locks for a given jid
290  * @lockspace: the lockspace
291  * @jid: the jid
292  *
293  */
294
295 static void nolock_recovery_done(lm_lockspace_t *lockspace, unsigned int jid,
296                                  unsigned int message)
297 {
298 }
299
300 struct lm_lockops nolock_ops = {
301         .lm_proto_name = "lock_nolock",
302         .lm_mount = nolock_mount,
303         .lm_others_may_mount = nolock_others_may_mount,
304         .lm_unmount = nolock_unmount,
305         .lm_withdraw = nolock_withdraw,
306         .lm_get_lock = nolock_get_lock,
307         .lm_put_lock = nolock_put_lock,
308         .lm_lock = nolock_lock,
309         .lm_unlock = nolock_unlock,
310         .lm_cancel = nolock_cancel,
311         .lm_hold_lvb = nolock_hold_lvb,
312         .lm_unhold_lvb = nolock_unhold_lvb,
313         .lm_sync_lvb = nolock_sync_lvb,
314         .lm_plock_get = nolock_plock_get,
315         .lm_plock = nolock_plock,
316         .lm_punlock = nolock_punlock,
317         .lm_recovery_done = nolock_recovery_done,
318         .lm_owner = THIS_MODULE,
319 };
320
321 /**
322  * init_nolock - Initialize the nolock module
323  *
324  * Returns: 0 on success, -EXXX on failure
325  */
326
327 int __init init_nolock(void)
328 {
329         int error;
330
331         error = lm_register_proto(&nolock_ops);
332         if (error) {
333                 printk("lock_nolock: can't register protocol: %d\n", error);
334                 return error;
335         }
336
337         printk("Lock_Nolock (built %s %s) installed\n", __DATE__, __TIME__);
338         return 0;
339 }
340
341 /**
342  * exit_nolock - cleanup the nolock module
343  *
344  */
345
346 void __exit exit_nolock(void)
347 {
348         lm_unregister_proto(&nolock_ops);
349 }
350
351 module_init(init_nolock);
352 module_exit(exit_nolock);
353
354 MODULE_DESCRIPTION("GFS Nolock Locking Module");
355 MODULE_AUTHOR("Red Hat, Inc.");
356 MODULE_LICENSE("GPL");
357