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