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