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