[GFS2] Fix up merge of Linus' kernel into GFS2
[pandora-kernel.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, force = 0;
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         if (params->flags & DLM_USER_LSFLG_FORCEFREE)
345                 force = 2;
346
347         lockspace = ls->ls_local_handle;
348
349         /* dlm_release_lockspace waits for references to go to zero,
350            so all processes will need to close their device for the ls
351            before the release will procede */
352
353         dlm_put_lockspace(ls);
354         error = dlm_release_lockspace(lockspace, force);
355  out:
356         return error;
357 }
358
359 /* Check the user's version matches ours */
360 static int check_version(struct dlm_write_request *req)
361 {
362         if (req->version[0] != DLM_DEVICE_VERSION_MAJOR ||
363             (req->version[0] == DLM_DEVICE_VERSION_MAJOR &&
364              req->version[1] > DLM_DEVICE_VERSION_MINOR)) {
365
366                 printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
367                        "user (%d.%d.%d) kernel (%d.%d.%d)\n",
368                        current->comm,
369                        current->pid,
370                        req->version[0],
371                        req->version[1],
372                        req->version[2],
373                        DLM_DEVICE_VERSION_MAJOR,
374                        DLM_DEVICE_VERSION_MINOR,
375                        DLM_DEVICE_VERSION_PATCH);
376                 return -EINVAL;
377         }
378         return 0;
379 }
380
381 /*
382  * device_write
383  *
384  *   device_user_lock
385  *     dlm_user_request -> request_lock
386  *     dlm_user_convert -> convert_lock
387  *
388  *   device_user_unlock
389  *     dlm_user_unlock -> unlock_lock
390  *     dlm_user_cancel -> cancel_lock
391  *
392  *   device_create_lockspace
393  *     dlm_new_lockspace
394  *
395  *   device_remove_lockspace
396  *     dlm_release_lockspace
397  */
398
399 /* a write to a lockspace device is a lock or unlock request, a write
400    to the control device is to create/remove a lockspace */
401
402 static ssize_t device_write(struct file *file, const char __user *buf,
403                             size_t count, loff_t *ppos)
404 {
405         struct dlm_user_proc *proc = file->private_data;
406         struct dlm_write_request *kbuf;
407         sigset_t tmpsig, allsigs;
408         int error;
409
410 #ifdef CONFIG_COMPAT
411         if (count < sizeof(struct dlm_write_request32))
412 #else
413         if (count < sizeof(struct dlm_write_request))
414 #endif
415                 return -EINVAL;
416
417         kbuf = kmalloc(count, GFP_KERNEL);
418         if (!kbuf)
419                 return -ENOMEM;
420
421         if (copy_from_user(kbuf, buf, count)) {
422                 error = -EFAULT;
423                 goto out_free;
424         }
425
426         if (check_version(kbuf)) {
427                 error = -EBADE;
428                 goto out_free;
429         }
430
431 #ifdef CONFIG_COMPAT
432         if (!kbuf->is64bit) {
433                 struct dlm_write_request32 *k32buf;
434                 k32buf = (struct dlm_write_request32 *)kbuf;
435                 kbuf = kmalloc(count + (sizeof(struct dlm_write_request) -
436                                sizeof(struct dlm_write_request32)), GFP_KERNEL);
437                 if (!kbuf)
438                         return -ENOMEM;
439
440                 if (proc)
441                         set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
442                 compat_input(kbuf, k32buf);
443                 kfree(k32buf);
444         }
445 #endif
446
447         /* do we really need this? can a write happen after a close? */
448         if ((kbuf->cmd == DLM_USER_LOCK || kbuf->cmd == DLM_USER_UNLOCK) &&
449             test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
450                 return -EINVAL;
451
452         sigfillset(&allsigs);
453         sigprocmask(SIG_BLOCK, &allsigs, &tmpsig);
454
455         error = -EINVAL;
456
457         switch (kbuf->cmd)
458         {
459         case DLM_USER_LOCK:
460                 if (!proc) {
461                         log_print("no locking on control device");
462                         goto out_sig;
463                 }
464                 error = device_user_lock(proc, &kbuf->i.lock);
465                 break;
466
467         case DLM_USER_UNLOCK:
468                 if (!proc) {
469                         log_print("no locking on control device");
470                         goto out_sig;
471                 }
472                 error = device_user_unlock(proc, &kbuf->i.lock);
473                 break;
474
475         case DLM_USER_CREATE_LOCKSPACE:
476                 if (proc) {
477                         log_print("create/remove only on control device");
478                         goto out_sig;
479                 }
480                 error = device_create_lockspace(&kbuf->i.lspace);
481                 break;
482
483         case DLM_USER_REMOVE_LOCKSPACE:
484                 if (proc) {
485                         log_print("create/remove only on control device");
486                         goto out_sig;
487                 }
488                 error = device_remove_lockspace(&kbuf->i.lspace);
489                 break;
490
491         default:
492                 log_print("Unknown command passed to DLM device : %d\n",
493                           kbuf->cmd);
494         }
495
496  out_sig:
497         sigprocmask(SIG_SETMASK, &tmpsig, NULL);
498         recalc_sigpending();
499  out_free:
500         kfree(kbuf);
501         return error;
502 }
503
504 /* Every process that opens the lockspace device has its own "proc" structure
505    hanging off the open file that's used to keep track of locks owned by the
506    process and asts that need to be delivered to the process. */
507
508 static int device_open(struct inode *inode, struct file *file)
509 {
510         struct dlm_user_proc *proc;
511         struct dlm_ls *ls;
512
513         ls = dlm_find_lockspace_device(iminor(inode));
514         if (!ls)
515                 return -ENOENT;
516
517         proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
518         if (!proc) {
519                 dlm_put_lockspace(ls);
520                 return -ENOMEM;
521         }
522
523         proc->lockspace = ls->ls_local_handle;
524         INIT_LIST_HEAD(&proc->asts);
525         INIT_LIST_HEAD(&proc->locks);
526         spin_lock_init(&proc->asts_spin);
527         spin_lock_init(&proc->locks_spin);
528         init_waitqueue_head(&proc->wait);
529         file->private_data = proc;
530
531         return 0;
532 }
533
534 static int device_close(struct inode *inode, struct file *file)
535 {
536         struct dlm_user_proc *proc = file->private_data;
537         struct dlm_ls *ls;
538         sigset_t tmpsig, allsigs;
539
540         ls = dlm_find_lockspace_local(proc->lockspace);
541         if (!ls)
542                 return -ENOENT;
543
544         sigfillset(&allsigs);
545         sigprocmask(SIG_BLOCK, &allsigs, &tmpsig);
546
547         set_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags);
548
549         dlm_clear_proc_locks(ls, proc);
550
551         /* at this point no more lkb's should exist for this lockspace,
552            so there's no chance of dlm_user_add_ast() being called and
553            looking for lkb->ua->proc */
554
555         kfree(proc);
556         file->private_data = NULL;
557
558         dlm_put_lockspace(ls);
559         dlm_put_lockspace(ls);  /* for the find in device_open() */
560
561         /* FIXME: AUTOFREE: if this ls is no longer used do
562            device_remove_lockspace() */
563
564         sigprocmask(SIG_SETMASK, &tmpsig, NULL);
565         recalc_sigpending();
566
567         return 0;
568 }
569
570 static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
571                                int bmode, char __user *buf, size_t count)
572 {
573 #ifdef CONFIG_COMPAT
574         struct dlm_lock_result32 result32;
575 #endif
576         struct dlm_lock_result result;
577         void *resultptr;
578         int error=0;
579         int len;
580         int struct_len;
581
582         memset(&result, 0, sizeof(struct dlm_lock_result));
583         memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb));
584         result.user_lksb = ua->user_lksb;
585
586         /* FIXME: dlm1 provides for the user's bastparam/addr to not be updated
587            in a conversion unless the conversion is successful.  See code
588            in dlm_user_convert() for updating ua from ua_tmp.  OpenVMS, though,
589            notes that a new blocking AST address and parameter are set even if
590            the conversion fails, so maybe we should just do that. */
591
592         if (type == AST_BAST) {
593                 result.user_astaddr = ua->bastaddr;
594                 result.user_astparam = ua->bastparam;
595                 result.bast_mode = bmode;
596         } else {
597                 result.user_astaddr = ua->castaddr;
598                 result.user_astparam = ua->castparam;
599         }
600
601 #ifdef CONFIG_COMPAT
602         if (compat)
603                 len = sizeof(struct dlm_lock_result32);
604         else
605 #endif
606                 len = sizeof(struct dlm_lock_result);
607         struct_len = len;
608
609         /* copy lvb to userspace if there is one, it's been updated, and
610            the user buffer has space for it */
611
612         if (ua->update_user_lvb && ua->lksb.sb_lvbptr &&
613             count >= len + DLM_USER_LVB_LEN) {
614                 if (copy_to_user(buf+len, ua->lksb.sb_lvbptr,
615                                  DLM_USER_LVB_LEN)) {
616                         error = -EFAULT;
617                         goto out;
618                 }
619
620                 result.lvb_offset = len;
621                 len += DLM_USER_LVB_LEN;
622         }
623
624         result.length = len;
625         resultptr = &result;
626 #ifdef CONFIG_COMPAT
627         if (compat) {
628                 compat_output(&result, &result32);
629                 resultptr = &result32;
630         }
631 #endif
632
633         if (copy_to_user(buf, resultptr, struct_len))
634                 error = -EFAULT;
635         else
636                 error = len;
637  out:
638         return error;
639 }
640
641 /* a read returns a single ast described in a struct dlm_lock_result */
642
643 static ssize_t device_read(struct file *file, char __user *buf, size_t count,
644                            loff_t *ppos)
645 {
646         struct dlm_user_proc *proc = file->private_data;
647         struct dlm_lkb *lkb;
648         struct dlm_user_args *ua;
649         DECLARE_WAITQUEUE(wait, current);
650         int error, type=0, bmode=0, removed = 0;
651
652 #ifdef CONFIG_COMPAT
653         if (count < sizeof(struct dlm_lock_result32))
654 #else
655         if (count < sizeof(struct dlm_lock_result))
656 #endif
657                 return -EINVAL;
658
659         /* do we really need this? can a read happen after a close? */
660         if (test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
661                 return -EINVAL;
662
663         spin_lock(&proc->asts_spin);
664         if (list_empty(&proc->asts)) {
665                 if (file->f_flags & O_NONBLOCK) {
666                         spin_unlock(&proc->asts_spin);
667                         return -EAGAIN;
668                 }
669
670                 add_wait_queue(&proc->wait, &wait);
671
672         repeat:
673                 set_current_state(TASK_INTERRUPTIBLE);
674                 if (list_empty(&proc->asts) && !signal_pending(current)) {
675                         spin_unlock(&proc->asts_spin);
676                         schedule();
677                         spin_lock(&proc->asts_spin);
678                         goto repeat;
679                 }
680                 set_current_state(TASK_RUNNING);
681                 remove_wait_queue(&proc->wait, &wait);
682
683                 if (signal_pending(current)) {
684                         spin_unlock(&proc->asts_spin);
685                         return -ERESTARTSYS;
686                 }
687         }
688
689         if (list_empty(&proc->asts)) {
690                 spin_unlock(&proc->asts_spin);
691                 return -EAGAIN;
692         }
693
694         /* there may be both completion and blocking asts to return for
695            the lkb, don't remove lkb from asts list unless no asts remain */
696
697         lkb = list_entry(proc->asts.next, struct dlm_lkb, lkb_astqueue);
698
699         if (lkb->lkb_ast_type & AST_COMP) {
700                 lkb->lkb_ast_type &= ~AST_COMP;
701                 type = AST_COMP;
702         } else if (lkb->lkb_ast_type & AST_BAST) {
703                 lkb->lkb_ast_type &= ~AST_BAST;
704                 type = AST_BAST;
705                 bmode = lkb->lkb_bastmode;
706         }
707
708         if (!lkb->lkb_ast_type) {
709                 list_del(&lkb->lkb_astqueue);
710                 removed = 1;
711         }
712         spin_unlock(&proc->asts_spin);
713
714         ua = (struct dlm_user_args *)lkb->lkb_astparam;
715         error = copy_result_to_user(ua,
716                                 test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
717                                 type, bmode, buf, count);
718
719         /* removes reference for the proc->asts lists added by
720            dlm_user_add_ast() and may result in the lkb being freed */
721         if (removed)
722                 dlm_put_lkb(lkb);
723
724         return error;
725 }
726
727 static unsigned int device_poll(struct file *file, poll_table *wait)
728 {
729         struct dlm_user_proc *proc = file->private_data;
730
731         poll_wait(file, &proc->wait, wait);
732
733         spin_lock(&proc->asts_spin);
734         if (!list_empty(&proc->asts)) {
735                 spin_unlock(&proc->asts_spin);
736                 return POLLIN | POLLRDNORM;
737         }
738         spin_unlock(&proc->asts_spin);
739         return 0;
740 }
741
742 static int ctl_device_open(struct inode *inode, struct file *file)
743 {
744         file->private_data = NULL;
745         return 0;
746 }
747
748 static int ctl_device_close(struct inode *inode, struct file *file)
749 {
750         return 0;
751 }
752
753 static struct file_operations device_fops = {
754         .open    = device_open,
755         .release = device_close,
756         .read    = device_read,
757         .write   = device_write,
758         .poll    = device_poll,
759         .owner   = THIS_MODULE,
760 };
761
762 static struct file_operations ctl_device_fops = {
763         .open    = ctl_device_open,
764         .release = ctl_device_close,
765         .write   = device_write,
766         .owner   = THIS_MODULE,
767 };
768
769 int dlm_user_init(void)
770 {
771         int error;
772
773         ctl_device.name = "dlm-control";
774         ctl_device.fops = &ctl_device_fops;
775         ctl_device.minor = MISC_DYNAMIC_MINOR;
776
777         error = misc_register(&ctl_device);
778         if (error)
779                 log_print("misc_register failed for control device");
780
781         return error;
782 }
783
784 void dlm_user_exit(void)
785 {
786         misc_deregister(&ctl_device);
787 }
788