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