]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/dlm/user.c
494d00ac014e55ae07b1d6ebee9d54fa68fd0637
[linux-2.6-omap-h63xx.git] / fs / dlm / user.c
1 /*
2  * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
3  *
4  * This copyrighted material is made available to anyone wishing to use,
5  * modify, copy, or redistribute it subject to the terms and conditions
6  * of the GNU General Public License v.2.
7  */
8
9 #include <linux/miscdevice.h>
10 #include <linux/init.h>
11 #include <linux/wait.h>
12 #include <linux/module.h>
13 #include <linux/file.h>
14 #include <linux/fs.h>
15 #include <linux/poll.h>
16 #include <linux/signal.h>
17 #include <linux/spinlock.h>
18 #include <linux/dlm.h>
19 #include <linux/dlm_device.h>
20
21 #include "dlm_internal.h"
22 #include "lockspace.h"
23 #include "lock.h"
24 #include "lvb_table.h"
25
26 static const char *name_prefix="dlm";
27 static struct miscdevice ctl_device;
28 static struct file_operations device_fops;
29
30 #ifdef CONFIG_COMPAT
31
32 struct dlm_lock_params32 {
33         __u8 mode;
34         __u8 namelen;
35         __u16 flags;
36         __u32 lkid;
37         __u32 parent;
38
39         __u32 castparam;
40         __u32 castaddr;
41         __u32 bastparam;
42         __u32 bastaddr;
43         __u32 lksb;
44
45         char lvb[DLM_USER_LVB_LEN];
46         char name[0];
47 };
48
49 struct dlm_write_request32 {
50         __u32 version[3];
51         __u8 cmd;
52         __u8 is64bit;
53         __u8 unused[2];
54
55         union  {
56                 struct dlm_lock_params32 lock;
57                 struct dlm_lspace_params lspace;
58         } i;
59 };
60
61 struct dlm_lksb32 {
62         __u32 sb_status;
63         __u32 sb_lkid;
64         __u8 sb_flags;
65         __u32 sb_lvbptr;
66 };
67
68 struct dlm_lock_result32 {
69         __u32 length;
70         __u32 user_astaddr;
71         __u32 user_astparam;
72         __u32 user_lksb;
73         struct dlm_lksb32 lksb;
74         __u8 bast_mode;
75         __u8 unused[3];
76         /* Offsets may be zero if no data is present */
77         __u32 lvb_offset;
78 };
79
80 static void compat_input(struct dlm_write_request *kb,
81                          struct dlm_write_request32 *kb32)
82 {
83         kb->version[0] = kb32->version[0];
84         kb->version[1] = kb32->version[1];
85         kb->version[2] = kb32->version[2];
86
87         kb->cmd = kb32->cmd;
88         kb->is64bit = kb32->is64bit;
89         if (kb->cmd == DLM_USER_CREATE_LOCKSPACE ||
90             kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
91                 kb->i.lspace.flags = kb32->i.lspace.flags;
92                 kb->i.lspace.minor = kb32->i.lspace.minor;
93                 strcpy(kb->i.lspace.name, kb32->i.lspace.name);
94         } else {
95                 kb->i.lock.mode = kb32->i.lock.mode;
96                 kb->i.lock.namelen = kb32->i.lock.namelen;
97                 kb->i.lock.flags = kb32->i.lock.flags;
98                 kb->i.lock.lkid = kb32->i.lock.lkid;
99                 kb->i.lock.parent = kb32->i.lock.parent;
100                 kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam;
101                 kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr;
102                 kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam;
103                 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
104                 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
105                 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
106                 memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen);
107         }
108 }
109
110 static void compat_output(struct dlm_lock_result *res,
111                           struct dlm_lock_result32 *res32)
112 {
113         res32->length = res->length - (sizeof(struct dlm_lock_result) -
114                                        sizeof(struct dlm_lock_result32));
115         res32->user_astaddr = (__u32)(long)res->user_astaddr;
116         res32->user_astparam = (__u32)(long)res->user_astparam;
117         res32->user_lksb = (__u32)(long)res->user_lksb;
118         res32->bast_mode = res->bast_mode;
119
120         res32->lvb_offset = res->lvb_offset;
121         res32->length = res->length;
122
123         res32->lksb.sb_status = res->lksb.sb_status;
124         res32->lksb.sb_flags = res->lksb.sb_flags;
125         res32->lksb.sb_lkid = res->lksb.sb_lkid;
126         res32->lksb.sb_lvbptr = (__u32)(long)res->lksb.sb_lvbptr;
127 }
128 #endif
129
130
131 void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
132 {
133         struct dlm_ls *ls;
134         struct dlm_user_args *ua;
135         struct dlm_user_proc *proc;
136         int remove_ownqueue = 0;
137
138         /* dlm_clear_proc_locks() sets ORPHAN/DEAD flag on each
139            lkb before dealing with it.  We need to check this
140            flag before taking ls_clear_proc_locks mutex because if
141            it's set, dlm_clear_proc_locks() holds the mutex. */
142
143         if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
144                 /* log_print("user_add_ast skip1 %x", lkb->lkb_flags); */
145                 return;
146         }
147
148         ls = lkb->lkb_resource->res_ls;
149         mutex_lock(&ls->ls_clear_proc_locks);
150
151         /* If ORPHAN/DEAD flag is set, it means the process is dead so an ast
152            can't be delivered.  For ORPHAN's, dlm_clear_proc_locks() freed
153            lkb->ua so we can't try to use it. */
154
155         if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
156                 /* log_print("user_add_ast skip2 %x", lkb->lkb_flags); */
157                 goto out;
158         }
159
160         DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb););
161         ua = (struct dlm_user_args *)lkb->lkb_astparam;
162         proc = ua->proc;
163
164         if (type == AST_BAST && ua->bastaddr == NULL)
165                 goto out;
166
167         spin_lock(&proc->asts_spin);
168         if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
169                 kref_get(&lkb->lkb_ref);
170                 list_add_tail(&lkb->lkb_astqueue, &proc->asts);
171                 lkb->lkb_ast_type |= type;
172                 wake_up_interruptible(&proc->wait);
173         }
174
175         /* noqueue requests that fail may need to be removed from the
176            proc's locks list, there should be a better way of detecting
177            this situation than checking all these things... */
178
179         if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV &&
180             ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue))
181                 remove_ownqueue = 1;
182
183         /* We want to copy the lvb to userspace when the completion
184            ast is read if the status is 0, the lock has an lvb and
185            lvb_ops says we should.  We could probably have set_lvb_lock()
186            set update_user_lvb instead and not need old_mode */
187
188         if ((lkb->lkb_ast_type & AST_COMP) &&
189             (lkb->lkb_lksb->sb_status == 0) &&
190             lkb->lkb_lksb->sb_lvbptr &&
191             dlm_lvb_operations[ua->old_mode + 1][lkb->lkb_grmode + 1])
192                 ua->update_user_lvb = 1;
193         else
194                 ua->update_user_lvb = 0;
195
196         spin_unlock(&proc->asts_spin);
197
198         if (remove_ownqueue) {
199                 spin_lock(&ua->proc->locks_spin);
200                 list_del_init(&lkb->lkb_ownqueue);
201                 spin_unlock(&ua->proc->locks_spin);
202                 dlm_put_lkb(lkb);
203         }
204  out:
205         mutex_unlock(&ls->ls_clear_proc_locks);
206 }
207
208 static int device_user_lock(struct dlm_user_proc *proc,
209                             struct dlm_lock_params *params)
210 {
211         struct dlm_ls *ls;
212         struct dlm_user_args *ua;
213         int error = -ENOMEM;
214
215         ls = dlm_find_lockspace_local(proc->lockspace);
216         if (!ls)
217                 return -ENOENT;
218
219         if (!params->castaddr || !params->lksb) {
220                 error = -EINVAL;
221                 goto out;
222         }
223
224         ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
225         if (!ua)
226                 goto out;
227         ua->proc = proc;
228         ua->user_lksb = params->lksb;
229         ua->castparam = params->castparam;
230         ua->castaddr = params->castaddr;
231         ua->bastparam = params->bastparam;
232         ua->bastaddr = params->bastaddr;
233
234         if (params->flags & DLM_LKF_CONVERT)
235                 error = dlm_user_convert(ls, ua,
236                                          params->mode, params->flags,
237                                          params->lkid, params->lvb);
238         else {
239                 error = dlm_user_request(ls, ua,
240                                          params->mode, params->flags,
241                                          params->name, params->namelen,
242                                          params->parent);
243                 if (!error)
244                         error = ua->lksb.sb_lkid;
245         }
246  out:
247         dlm_put_lockspace(ls);
248         return error;
249 }
250
251 static int device_user_unlock(struct dlm_user_proc *proc,
252                               struct dlm_lock_params *params)
253 {
254         struct dlm_ls *ls;
255         struct dlm_user_args *ua;
256         int error = -ENOMEM;
257
258         ls = dlm_find_lockspace_local(proc->lockspace);
259         if (!ls)
260                 return -ENOENT;
261
262         ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
263         if (!ua)
264                 goto out;
265         ua->proc = proc;
266         ua->user_lksb = params->lksb;
267         ua->castparam = params->castparam;
268         ua->castaddr = params->castaddr;
269
270         if (params->flags & DLM_LKF_CANCEL)
271                 error = dlm_user_cancel(ls, ua, params->flags, params->lkid);
272         else
273                 error = dlm_user_unlock(ls, ua, params->flags, params->lkid,
274                                         params->lvb);
275  out:
276         dlm_put_lockspace(ls);
277         return error;
278 }
279
280 static int device_create_lockspace(struct dlm_lspace_params *params)
281 {
282         dlm_lockspace_t *lockspace;
283         struct dlm_ls *ls;
284         int error, len;
285
286         if (!capable(CAP_SYS_ADMIN))
287                 return -EPERM;
288
289         error = dlm_new_lockspace(params->name, strlen(params->name),
290                                   &lockspace, 0, DLM_USER_LVB_LEN);
291         if (error)
292                 return error;
293
294         ls = dlm_find_lockspace_local(lockspace);
295         if (!ls)
296                 return -ENOENT;
297
298         error = -ENOMEM;
299         len = strlen(params->name) + strlen(name_prefix) + 2;
300         ls->ls_device.name = kzalloc(len, GFP_KERNEL);
301         if (!ls->ls_device.name)
302                 goto fail;
303         snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
304                  params->name);
305         ls->ls_device.fops = &device_fops;
306         ls->ls_device.minor = MISC_DYNAMIC_MINOR;
307
308         error = misc_register(&ls->ls_device);
309         if (error) {
310                 kfree(ls->ls_device.name);
311                 goto fail;
312         }
313
314         error = ls->ls_device.minor;
315         dlm_put_lockspace(ls);
316         return error;
317
318  fail:
319         dlm_put_lockspace(ls);
320         dlm_release_lockspace(lockspace, 0);
321         return error;
322 }
323
324 static int device_remove_lockspace(struct dlm_lspace_params *params)
325 {
326         dlm_lockspace_t *lockspace;
327         struct dlm_ls *ls;
328         int error;
329
330         if (!capable(CAP_SYS_ADMIN))
331                 return -EPERM;
332
333         ls = dlm_find_lockspace_device(params->minor);
334         if (!ls)
335                 return -ENOENT;
336
337         error = misc_deregister(&ls->ls_device);
338         if (error) {
339                 dlm_put_lockspace(ls);
340                 goto out;
341         }
342         kfree(ls->ls_device.name);
343
344         lockspace = ls->ls_local_handle;
345
346         /* dlm_release_lockspace waits for references to go to zero,
347            so all processes will need to close their device for the ls
348            before the release will procede */
349
350         dlm_put_lockspace(ls);
351         error = dlm_release_lockspace(lockspace, 0);
352 out:
353         return error;
354 }
355
356 /* Check the user's version matches ours */
357 static int check_version(struct dlm_write_request *req)
358 {
359         if (req->version[0] != DLM_DEVICE_VERSION_MAJOR ||
360             (req->version[0] == DLM_DEVICE_VERSION_MAJOR &&
361              req->version[1] > DLM_DEVICE_VERSION_MINOR)) {
362
363                 printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
364                        "user (%d.%d.%d) kernel (%d.%d.%d)\n",
365                        current->comm,
366                        current->pid,
367                        req->version[0],
368                        req->version[1],
369                        req->version[2],
370                        DLM_DEVICE_VERSION_MAJOR,
371                        DLM_DEVICE_VERSION_MINOR,
372                        DLM_DEVICE_VERSION_PATCH);
373                 return -EINVAL;
374         }
375         return 0;
376 }
377
378 /*
379  * device_write
380  *
381  *   device_user_lock
382  *     dlm_user_request -> request_lock
383  *     dlm_user_convert -> convert_lock
384  *
385  *   device_user_unlock
386  *     dlm_user_unlock -> unlock_lock
387  *     dlm_user_cancel -> cancel_lock
388  *
389  *   device_create_lockspace
390  *     dlm_new_lockspace
391  *
392  *   device_remove_lockspace
393  *     dlm_release_lockspace
394  */
395
396 /* a write to a lockspace device is a lock or unlock request, a write
397    to the control device is to create/remove a lockspace */
398
399 static ssize_t device_write(struct file *file, const char __user *buf,
400                             size_t count, loff_t *ppos)
401 {
402         struct dlm_user_proc *proc = file->private_data;
403         struct dlm_write_request *kbuf;
404         sigset_t tmpsig, allsigs;
405         int error;
406
407 #ifdef CONFIG_COMPAT
408         if (count < sizeof(struct dlm_write_request32))
409 #else
410         if (count < sizeof(struct dlm_write_request))
411 #endif
412                 return -EINVAL;
413
414         kbuf = kmalloc(count, GFP_KERNEL);
415         if (!kbuf)
416                 return -ENOMEM;
417
418         if (copy_from_user(kbuf, buf, count)) {
419                 error = -EFAULT;
420                 goto out_free;
421         }
422
423         if (check_version(kbuf)) {
424                 error = -EBADE;
425                 goto out_free;
426         }
427
428 #ifdef CONFIG_COMPAT
429         if (!kbuf->is64bit) {
430                 struct dlm_write_request32 *k32buf;
431                 k32buf = (struct dlm_write_request32 *)kbuf;
432                 kbuf = kmalloc(count + (sizeof(struct dlm_write_request) -
433                                sizeof(struct dlm_write_request32)), GFP_KERNEL);
434                 if (!kbuf)
435                         return -ENOMEM;
436
437                 if (proc)
438                         set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
439                 compat_input(kbuf, k32buf);
440                 kfree(k32buf);
441         }
442 #endif
443
444         /* do we really need this? can a write happen after a close? */
445         if ((kbuf->cmd == DLM_USER_LOCK || kbuf->cmd == DLM_USER_UNLOCK) &&
446             test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
447                 return -EINVAL;
448
449         sigfillset(&allsigs);
450         sigprocmask(SIG_BLOCK, &allsigs, &tmpsig);
451
452         error = -EINVAL;
453
454         switch (kbuf->cmd)
455         {
456         case DLM_USER_LOCK:
457                 if (!proc) {
458                         log_print("no locking on control device");
459                         goto out_sig;
460                 }
461                 error = device_user_lock(proc, &kbuf->i.lock);
462                 break;
463
464         case DLM_USER_UNLOCK:
465                 if (!proc) {
466                         log_print("no locking on control device");
467                         goto out_sig;
468                 }
469                 error = device_user_unlock(proc, &kbuf->i.lock);
470                 break;
471
472         case DLM_USER_CREATE_LOCKSPACE:
473                 if (proc) {
474                         log_print("create/remove only on control device");
475                         goto out_sig;
476                 }
477                 error = device_create_lockspace(&kbuf->i.lspace);
478                 break;
479
480         case DLM_USER_REMOVE_LOCKSPACE:
481                 if (proc) {
482                         log_print("create/remove only on control device");
483                         goto out_sig;
484                 }
485                 error = device_remove_lockspace(&kbuf->i.lspace);
486                 break;
487
488         default:
489                 log_print("Unknown command passed to DLM device : %d\n",
490                           kbuf->cmd);
491         }
492
493  out_sig:
494         sigprocmask(SIG_SETMASK, &tmpsig, NULL);
495         recalc_sigpending();
496  out_free:
497         kfree(kbuf);
498         return error;
499 }
500
501 /* Every process that opens the lockspace device has its own "proc" structure
502    hanging off the open file that's used to keep track of locks owned by the
503    process and asts that need to be delivered to the process. */
504
505 static int device_open(struct inode *inode, struct file *file)
506 {
507         struct dlm_user_proc *proc;
508         struct dlm_ls *ls;
509
510         ls = dlm_find_lockspace_device(iminor(inode));
511         if (!ls)
512                 return -ENOENT;
513
514         proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
515         if (!proc) {
516                 dlm_put_lockspace(ls);
517                 return -ENOMEM;
518         }
519
520         proc->lockspace = ls->ls_local_handle;
521         INIT_LIST_HEAD(&proc->asts);
522         INIT_LIST_HEAD(&proc->locks);
523         spin_lock_init(&proc->asts_spin);
524         spin_lock_init(&proc->locks_spin);
525         init_waitqueue_head(&proc->wait);
526         file->private_data = proc;
527
528         return 0;
529 }
530
531 static int device_close(struct inode *inode, struct file *file)
532 {
533         struct dlm_user_proc *proc = file->private_data;
534         struct dlm_ls *ls;
535         sigset_t tmpsig, allsigs;
536
537         ls = dlm_find_lockspace_local(proc->lockspace);
538         if (!ls)
539                 return -ENOENT;
540
541         sigfillset(&allsigs);
542         sigprocmask(SIG_BLOCK, &allsigs, &tmpsig);
543
544         set_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags);
545
546         dlm_clear_proc_locks(ls, proc);
547
548         /* at this point no more lkb's should exist for this lockspace,
549            so there's no chance of dlm_user_add_ast() being called and
550            looking for lkb->ua->proc */
551
552         kfree(proc);
553         file->private_data = NULL;
554
555         dlm_put_lockspace(ls);
556         dlm_put_lockspace(ls);  /* for the find in device_open() */
557
558         /* FIXME: AUTOFREE: if this ls is no longer used do
559            device_remove_lockspace() */
560
561         sigprocmask(SIG_SETMASK, &tmpsig, NULL);
562         recalc_sigpending();
563
564         return 0;
565 }
566
567 static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
568                                int bmode, char __user *buf, size_t count)
569 {
570 #ifdef CONFIG_COMPAT
571         struct dlm_lock_result32 result32;
572 #endif
573         struct dlm_lock_result result;
574         void *resultptr;
575         int error=0;
576         int len;
577         int struct_len;
578
579         memset(&result, 0, sizeof(struct dlm_lock_result));
580         memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb));
581         result.user_lksb = ua->user_lksb;
582
583         /* FIXME: dlm1 provides for the user's bastparam/addr to not be updated
584            in a conversion unless the conversion is successful.  See code
585            in dlm_user_convert() for updating ua from ua_tmp.  OpenVMS, though,
586            notes that a new blocking AST address and parameter are set even if
587            the conversion fails, so maybe we should just do that. */
588
589         if (type == AST_BAST) {
590                 result.user_astaddr = ua->bastaddr;
591                 result.user_astparam = ua->bastparam;
592                 result.bast_mode = bmode;
593         } else {
594                 result.user_astaddr = ua->castaddr;
595                 result.user_astparam = ua->castparam;
596         }
597
598 #ifdef CONFIG_COMPAT
599         if (compat)
600                 len = sizeof(struct dlm_lock_result32);
601         else
602 #endif
603                 len = sizeof(struct dlm_lock_result);
604         struct_len = len;
605
606         /* copy lvb to userspace if there is one, it's been updated, and
607            the user buffer has space for it */
608
609         if (ua->update_user_lvb && ua->lksb.sb_lvbptr &&
610             count >= len + DLM_USER_LVB_LEN) {
611                 if (copy_to_user(buf+len, ua->lksb.sb_lvbptr,
612                                  DLM_USER_LVB_LEN)) {
613                         error = -EFAULT;
614                         goto out;
615                 }
616
617                 result.lvb_offset = len;
618                 len += DLM_USER_LVB_LEN;
619         }
620
621         result.length = len;
622         resultptr = &result;
623 #ifdef CONFIG_COMPAT
624         if (compat) {
625                 compat_output(&result, &result32);
626                 resultptr = &result32;
627         }
628 #endif
629
630         if (copy_to_user(buf, resultptr, struct_len))
631                 error = -EFAULT;
632         else
633                 error = len;
634  out:
635         return error;
636 }
637
638 /* a read returns a single ast described in a struct dlm_lock_result */
639
640 static ssize_t device_read(struct file *file, char __user *buf, size_t count,
641                            loff_t *ppos)
642 {
643         struct dlm_user_proc *proc = file->private_data;
644         struct dlm_lkb *lkb;
645         struct dlm_user_args *ua;
646         DECLARE_WAITQUEUE(wait, current);
647         int error, type=0, bmode=0, removed = 0;
648
649 #ifdef CONFIG_COMPAT
650         if (count < sizeof(struct dlm_lock_result32))
651 #else
652         if (count < sizeof(struct dlm_lock_result))
653 #endif
654                 return -EINVAL;
655
656         /* do we really need this? can a read happen after a close? */
657         if (test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
658                 return -EINVAL;
659
660         spin_lock(&proc->asts_spin);
661         if (list_empty(&proc->asts)) {
662                 if (file->f_flags & O_NONBLOCK) {
663                         spin_unlock(&proc->asts_spin);
664                         return -EAGAIN;
665                 }
666
667                 add_wait_queue(&proc->wait, &wait);
668
669         repeat:
670                 set_current_state(TASK_INTERRUPTIBLE);
671                 if (list_empty(&proc->asts) && !signal_pending(current)) {
672                         spin_unlock(&proc->asts_spin);
673                         schedule();
674                         spin_lock(&proc->asts_spin);
675                         goto repeat;
676                 }
677                 set_current_state(TASK_RUNNING);
678                 remove_wait_queue(&proc->wait, &wait);
679
680                 if (signal_pending(current)) {
681                         spin_unlock(&proc->asts_spin);
682                         return -ERESTARTSYS;
683                 }
684         }
685
686         if (list_empty(&proc->asts)) {
687                 spin_unlock(&proc->asts_spin);
688                 return -EAGAIN;
689         }
690
691         /* there may be both completion and blocking asts to return for
692            the lkb, don't remove lkb from asts list unless no asts remain */
693
694         lkb = list_entry(proc->asts.next, struct dlm_lkb, lkb_astqueue);
695
696         if (lkb->lkb_ast_type & AST_COMP) {
697                 lkb->lkb_ast_type &= ~AST_COMP;
698                 type = AST_COMP;
699         } else if (lkb->lkb_ast_type & AST_BAST) {
700                 lkb->lkb_ast_type &= ~AST_BAST;
701                 type = AST_BAST;
702                 bmode = lkb->lkb_bastmode;
703         }
704
705         if (!lkb->lkb_ast_type) {
706                 list_del(&lkb->lkb_astqueue);
707                 removed = 1;
708         }
709         spin_unlock(&proc->asts_spin);
710
711         ua = (struct dlm_user_args *)lkb->lkb_astparam;
712         error = copy_result_to_user(ua,
713                                 test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
714                                 type, bmode, buf, count);
715
716         /* removes reference for the proc->asts lists added by
717            dlm_user_add_ast() and may result in the lkb being freed */
718         if (removed)
719                 dlm_put_lkb(lkb);
720
721         return error;
722 }
723
724 static unsigned int device_poll(struct file *file, poll_table *wait)
725 {
726         struct dlm_user_proc *proc = file->private_data;
727
728         poll_wait(file, &proc->wait, wait);
729
730         spin_lock(&proc->asts_spin);
731         if (!list_empty(&proc->asts)) {
732                 spin_unlock(&proc->asts_spin);
733                 return POLLIN | POLLRDNORM;
734         }
735         spin_unlock(&proc->asts_spin);
736         return 0;
737 }
738
739 static int ctl_device_open(struct inode *inode, struct file *file)
740 {
741         file->private_data = NULL;
742         return 0;
743 }
744
745 static int ctl_device_close(struct inode *inode, struct file *file)
746 {
747         return 0;
748 }
749
750 static struct file_operations device_fops = {
751         .open    = device_open,
752         .release = device_close,
753         .read    = device_read,
754         .write   = device_write,
755         .poll    = device_poll,
756         .owner   = THIS_MODULE,
757 };
758
759 static struct file_operations ctl_device_fops = {
760         .open    = ctl_device_open,
761         .release = ctl_device_close,
762         .write   = device_write,
763         .owner   = THIS_MODULE,
764 };
765
766 int dlm_user_init(void)
767 {
768         int error;
769
770         ctl_device.name = "dlm-control";
771         ctl_device.fops = &ctl_device_fops;
772         ctl_device.minor = MISC_DYNAMIC_MINOR;
773
774         error = misc_register(&ctl_device);
775         if (error)
776                 log_print("misc_register failed for control device");
777
778         return error;
779 }
780
781 void dlm_user_exit(void)
782 {
783         misc_deregister(&ctl_device);
784 }
785