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