2 * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
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.
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>
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>
21 #include "dlm_internal.h"
22 #include "lockspace.h"
24 #include "lvb_table.h"
26 static const char *name_prefix="dlm";
27 static struct miscdevice ctl_device;
28 static const struct file_operations device_fops;
32 struct dlm_lock_params32 {
45 char lvb[DLM_USER_LVB_LEN];
49 struct dlm_write_request32 {
56 struct dlm_lock_params32 lock;
57 struct dlm_lspace_params lspace;
68 struct dlm_lock_result32 {
73 struct dlm_lksb32 lksb;
76 /* Offsets may be zero if no data is present */
80 static void compat_input(struct dlm_write_request *kb,
81 struct dlm_write_request32 *kb32)
83 kb->version[0] = kb32->version[0];
84 kb->version[1] = kb32->version[1];
85 kb->version[2] = kb32->version[2];
88 kb->is64bit = kb32->is64bit;
89 if (kb->cmd == DLM_USER_CREATE_LOCKSPACE ||
90 kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
91 kb->i.lspace.flags = kb32->i.lspace.flags;
92 kb->i.lspace.minor = kb32->i.lspace.minor;
93 strcpy(kb->i.lspace.name, kb32->i.lspace.name);
95 kb->i.lock.mode = kb32->i.lock.mode;
96 kb->i.lock.namelen = kb32->i.lock.namelen;
97 kb->i.lock.flags = kb32->i.lock.flags;
98 kb->i.lock.lkid = kb32->i.lock.lkid;
99 kb->i.lock.parent = kb32->i.lock.parent;
100 kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam;
101 kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr;
102 kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam;
103 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
104 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
105 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
106 memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen);
110 static void compat_output(struct dlm_lock_result *res,
111 struct dlm_lock_result32 *res32)
113 res32->length = res->length - (sizeof(struct dlm_lock_result) -
114 sizeof(struct dlm_lock_result32));
115 res32->user_astaddr = (__u32)(long)res->user_astaddr;
116 res32->user_astparam = (__u32)(long)res->user_astparam;
117 res32->user_lksb = (__u32)(long)res->user_lksb;
118 res32->bast_mode = res->bast_mode;
120 res32->lvb_offset = res->lvb_offset;
121 res32->length = res->length;
123 res32->lksb.sb_status = res->lksb.sb_status;
124 res32->lksb.sb_flags = res->lksb.sb_flags;
125 res32->lksb.sb_lkid = res->lksb.sb_lkid;
126 res32->lksb.sb_lvbptr = (__u32)(long)res->lksb.sb_lvbptr;
131 void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
134 struct dlm_user_args *ua;
135 struct dlm_user_proc *proc;
136 int remove_ownqueue = 0;
138 /* dlm_clear_proc_locks() sets ORPHAN/DEAD flag on each
139 lkb before dealing with it. We need to check this
140 flag before taking ls_clear_proc_locks mutex because if
141 it's set, dlm_clear_proc_locks() holds the mutex. */
143 if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
144 /* log_print("user_add_ast skip1 %x", lkb->lkb_flags); */
148 ls = lkb->lkb_resource->res_ls;
149 mutex_lock(&ls->ls_clear_proc_locks);
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. */
155 if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
156 /* log_print("user_add_ast skip2 %x", lkb->lkb_flags); */
160 DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb););
161 ua = (struct dlm_user_args *)lkb->lkb_astparam;
164 if (type == AST_BAST && ua->bastaddr == NULL)
167 spin_lock(&proc->asts_spin);
168 if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
169 kref_get(&lkb->lkb_ref);
170 list_add_tail(&lkb->lkb_astqueue, &proc->asts);
171 lkb->lkb_ast_type |= type;
172 wake_up_interruptible(&proc->wait);
175 /* noqueue requests that fail may need to be removed from the
176 proc's locks list, there should be a better way of detecting
177 this situation than checking all these things... */
179 if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV &&
180 ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue))
183 /* unlocks or cancels of waiting requests need to be removed from the
184 proc's unlocking list, again there must be a better way... */
186 if (ua->lksb.sb_status == -DLM_EUNLOCK ||
187 (ua->lksb.sb_status == -DLM_ECANCEL &&
188 lkb->lkb_grmode == DLM_LOCK_IV))
191 /* We want to copy the lvb to userspace when the completion
192 ast is read if the status is 0, the lock has an lvb and
193 lvb_ops says we should. We could probably have set_lvb_lock()
194 set update_user_lvb instead and not need old_mode */
196 if ((lkb->lkb_ast_type & AST_COMP) &&
197 (lkb->lkb_lksb->sb_status == 0) &&
198 lkb->lkb_lksb->sb_lvbptr &&
199 dlm_lvb_operations[ua->old_mode + 1][lkb->lkb_grmode + 1])
200 ua->update_user_lvb = 1;
202 ua->update_user_lvb = 0;
204 spin_unlock(&proc->asts_spin);
206 if (remove_ownqueue) {
207 spin_lock(&ua->proc->locks_spin);
208 list_del_init(&lkb->lkb_ownqueue);
209 spin_unlock(&ua->proc->locks_spin);
213 mutex_unlock(&ls->ls_clear_proc_locks);
216 static int device_user_lock(struct dlm_user_proc *proc,
217 struct dlm_lock_params *params)
220 struct dlm_user_args *ua;
223 ls = dlm_find_lockspace_local(proc->lockspace);
227 if (!params->castaddr || !params->lksb) {
232 ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
236 ua->user_lksb = params->lksb;
237 ua->castparam = params->castparam;
238 ua->castaddr = params->castaddr;
239 ua->bastparam = params->bastparam;
240 ua->bastaddr = params->bastaddr;
242 if (params->flags & DLM_LKF_CONVERT)
243 error = dlm_user_convert(ls, ua,
244 params->mode, params->flags,
245 params->lkid, params->lvb);
247 error = dlm_user_request(ls, ua,
248 params->mode, params->flags,
249 params->name, params->namelen,
252 error = ua->lksb.sb_lkid;
255 dlm_put_lockspace(ls);
259 static int device_user_unlock(struct dlm_user_proc *proc,
260 struct dlm_lock_params *params)
263 struct dlm_user_args *ua;
266 ls = dlm_find_lockspace_local(proc->lockspace);
270 ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
274 ua->user_lksb = params->lksb;
275 ua->castparam = params->castparam;
276 ua->castaddr = params->castaddr;
278 if (params->flags & DLM_LKF_CANCEL)
279 error = dlm_user_cancel(ls, ua, params->flags, params->lkid);
281 error = dlm_user_unlock(ls, ua, params->flags, params->lkid,
284 dlm_put_lockspace(ls);
288 static int device_create_lockspace(struct dlm_lspace_params *params)
290 dlm_lockspace_t *lockspace;
294 if (!capable(CAP_SYS_ADMIN))
297 error = dlm_new_lockspace(params->name, strlen(params->name),
298 &lockspace, 0, DLM_USER_LVB_LEN);
302 ls = dlm_find_lockspace_local(lockspace);
307 len = strlen(params->name) + strlen(name_prefix) + 2;
308 ls->ls_device.name = kzalloc(len, GFP_KERNEL);
309 if (!ls->ls_device.name)
311 snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
313 ls->ls_device.fops = &device_fops;
314 ls->ls_device.minor = MISC_DYNAMIC_MINOR;
316 error = misc_register(&ls->ls_device);
318 kfree(ls->ls_device.name);
322 error = ls->ls_device.minor;
323 dlm_put_lockspace(ls);
327 dlm_put_lockspace(ls);
328 dlm_release_lockspace(lockspace, 0);
332 static int device_remove_lockspace(struct dlm_lspace_params *params)
334 dlm_lockspace_t *lockspace;
336 int error, force = 0;
338 if (!capable(CAP_SYS_ADMIN))
341 ls = dlm_find_lockspace_device(params->minor);
345 error = misc_deregister(&ls->ls_device);
347 dlm_put_lockspace(ls);
350 kfree(ls->ls_device.name);
352 if (params->flags & DLM_USER_LSFLG_FORCEFREE)
355 lockspace = ls->ls_local_handle;
357 /* dlm_release_lockspace waits for references to go to zero,
358 so all processes will need to close their device for the ls
359 before the release will procede */
361 dlm_put_lockspace(ls);
362 error = dlm_release_lockspace(lockspace, force);
367 /* Check the user's version matches ours */
368 static int check_version(struct dlm_write_request *req)
370 if (req->version[0] != DLM_DEVICE_VERSION_MAJOR ||
371 (req->version[0] == DLM_DEVICE_VERSION_MAJOR &&
372 req->version[1] > DLM_DEVICE_VERSION_MINOR)) {
374 printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
375 "user (%d.%d.%d) kernel (%d.%d.%d)\n",
381 DLM_DEVICE_VERSION_MAJOR,
382 DLM_DEVICE_VERSION_MINOR,
383 DLM_DEVICE_VERSION_PATCH);
393 * dlm_user_request -> request_lock
394 * dlm_user_convert -> convert_lock
397 * dlm_user_unlock -> unlock_lock
398 * dlm_user_cancel -> cancel_lock
400 * device_create_lockspace
403 * device_remove_lockspace
404 * dlm_release_lockspace
407 /* a write to a lockspace device is a lock or unlock request, a write
408 to the control device is to create/remove a lockspace */
410 static ssize_t device_write(struct file *file, const char __user *buf,
411 size_t count, loff_t *ppos)
413 struct dlm_user_proc *proc = file->private_data;
414 struct dlm_write_request *kbuf;
415 sigset_t tmpsig, allsigs;
419 if (count < sizeof(struct dlm_write_request32))
421 if (count < sizeof(struct dlm_write_request))
425 kbuf = kmalloc(count, GFP_KERNEL);
429 if (copy_from_user(kbuf, buf, count)) {
434 if (check_version(kbuf)) {
440 if (!kbuf->is64bit) {
441 struct dlm_write_request32 *k32buf;
442 k32buf = (struct dlm_write_request32 *)kbuf;
443 kbuf = kmalloc(count + (sizeof(struct dlm_write_request) -
444 sizeof(struct dlm_write_request32)), GFP_KERNEL);
449 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
450 compat_input(kbuf, k32buf);
455 /* do we really need this? can a write happen after a close? */
456 if ((kbuf->cmd == DLM_USER_LOCK || kbuf->cmd == DLM_USER_UNLOCK) &&
457 test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
460 sigfillset(&allsigs);
461 sigprocmask(SIG_BLOCK, &allsigs, &tmpsig);
469 log_print("no locking on control device");
472 error = device_user_lock(proc, &kbuf->i.lock);
475 case DLM_USER_UNLOCK:
477 log_print("no locking on control device");
480 error = device_user_unlock(proc, &kbuf->i.lock);
483 case DLM_USER_CREATE_LOCKSPACE:
485 log_print("create/remove only on control device");
488 error = device_create_lockspace(&kbuf->i.lspace);
491 case DLM_USER_REMOVE_LOCKSPACE:
493 log_print("create/remove only on control device");
496 error = device_remove_lockspace(&kbuf->i.lspace);
500 log_print("Unknown command passed to DLM device : %d\n",
505 sigprocmask(SIG_SETMASK, &tmpsig, NULL);
512 /* Every process that opens the lockspace device has its own "proc" structure
513 hanging off the open file that's used to keep track of locks owned by the
514 process and asts that need to be delivered to the process. */
516 static int device_open(struct inode *inode, struct file *file)
518 struct dlm_user_proc *proc;
521 ls = dlm_find_lockspace_device(iminor(inode));
525 proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
527 dlm_put_lockspace(ls);
531 proc->lockspace = ls->ls_local_handle;
532 INIT_LIST_HEAD(&proc->asts);
533 INIT_LIST_HEAD(&proc->locks);
534 INIT_LIST_HEAD(&proc->unlocking);
535 spin_lock_init(&proc->asts_spin);
536 spin_lock_init(&proc->locks_spin);
537 init_waitqueue_head(&proc->wait);
538 file->private_data = proc;
543 static int device_close(struct inode *inode, struct file *file)
545 struct dlm_user_proc *proc = file->private_data;
547 sigset_t tmpsig, allsigs;
549 ls = dlm_find_lockspace_local(proc->lockspace);
553 sigfillset(&allsigs);
554 sigprocmask(SIG_BLOCK, &allsigs, &tmpsig);
556 set_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags);
558 dlm_clear_proc_locks(ls, proc);
560 /* at this point no more lkb's should exist for this lockspace,
561 so there's no chance of dlm_user_add_ast() being called and
562 looking for lkb->ua->proc */
565 file->private_data = NULL;
567 dlm_put_lockspace(ls);
568 dlm_put_lockspace(ls); /* for the find in device_open() */
570 /* FIXME: AUTOFREE: if this ls is no longer used do
571 device_remove_lockspace() */
573 sigprocmask(SIG_SETMASK, &tmpsig, NULL);
579 static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
580 int bmode, char __user *buf, size_t count)
583 struct dlm_lock_result32 result32;
585 struct dlm_lock_result result;
591 memset(&result, 0, sizeof(struct dlm_lock_result));
592 memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb));
593 result.user_lksb = ua->user_lksb;
595 /* FIXME: dlm1 provides for the user's bastparam/addr to not be updated
596 in a conversion unless the conversion is successful. See code
597 in dlm_user_convert() for updating ua from ua_tmp. OpenVMS, though,
598 notes that a new blocking AST address and parameter are set even if
599 the conversion fails, so maybe we should just do that. */
601 if (type == AST_BAST) {
602 result.user_astaddr = ua->bastaddr;
603 result.user_astparam = ua->bastparam;
604 result.bast_mode = bmode;
606 result.user_astaddr = ua->castaddr;
607 result.user_astparam = ua->castparam;
612 len = sizeof(struct dlm_lock_result32);
615 len = sizeof(struct dlm_lock_result);
618 /* copy lvb to userspace if there is one, it's been updated, and
619 the user buffer has space for it */
621 if (ua->update_user_lvb && ua->lksb.sb_lvbptr &&
622 count >= len + DLM_USER_LVB_LEN) {
623 if (copy_to_user(buf+len, ua->lksb.sb_lvbptr,
629 result.lvb_offset = len;
630 len += DLM_USER_LVB_LEN;
637 compat_output(&result, &result32);
638 resultptr = &result32;
642 if (copy_to_user(buf, resultptr, struct_len))
650 /* a read returns a single ast described in a struct dlm_lock_result */
652 static ssize_t device_read(struct file *file, char __user *buf, size_t count,
655 struct dlm_user_proc *proc = file->private_data;
657 struct dlm_user_args *ua;
658 DECLARE_WAITQUEUE(wait, current);
659 int error, type=0, bmode=0, removed = 0;
662 if (count < sizeof(struct dlm_lock_result32))
664 if (count < sizeof(struct dlm_lock_result))
668 /* do we really need this? can a read happen after a close? */
669 if (test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
672 spin_lock(&proc->asts_spin);
673 if (list_empty(&proc->asts)) {
674 if (file->f_flags & O_NONBLOCK) {
675 spin_unlock(&proc->asts_spin);
679 add_wait_queue(&proc->wait, &wait);
682 set_current_state(TASK_INTERRUPTIBLE);
683 if (list_empty(&proc->asts) && !signal_pending(current)) {
684 spin_unlock(&proc->asts_spin);
686 spin_lock(&proc->asts_spin);
689 set_current_state(TASK_RUNNING);
690 remove_wait_queue(&proc->wait, &wait);
692 if (signal_pending(current)) {
693 spin_unlock(&proc->asts_spin);
698 if (list_empty(&proc->asts)) {
699 spin_unlock(&proc->asts_spin);
703 /* there may be both completion and blocking asts to return for
704 the lkb, don't remove lkb from asts list unless no asts remain */
706 lkb = list_entry(proc->asts.next, struct dlm_lkb, lkb_astqueue);
708 if (lkb->lkb_ast_type & AST_COMP) {
709 lkb->lkb_ast_type &= ~AST_COMP;
711 } else if (lkb->lkb_ast_type & AST_BAST) {
712 lkb->lkb_ast_type &= ~AST_BAST;
714 bmode = lkb->lkb_bastmode;
717 if (!lkb->lkb_ast_type) {
718 list_del(&lkb->lkb_astqueue);
721 spin_unlock(&proc->asts_spin);
723 ua = (struct dlm_user_args *)lkb->lkb_astparam;
724 error = copy_result_to_user(ua,
725 test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
726 type, bmode, buf, count);
728 /* removes reference for the proc->asts lists added by
729 dlm_user_add_ast() and may result in the lkb being freed */
736 static unsigned int device_poll(struct file *file, poll_table *wait)
738 struct dlm_user_proc *proc = file->private_data;
740 poll_wait(file, &proc->wait, wait);
742 spin_lock(&proc->asts_spin);
743 if (!list_empty(&proc->asts)) {
744 spin_unlock(&proc->asts_spin);
745 return POLLIN | POLLRDNORM;
747 spin_unlock(&proc->asts_spin);
751 static int ctl_device_open(struct inode *inode, struct file *file)
753 file->private_data = NULL;
757 static int ctl_device_close(struct inode *inode, struct file *file)
762 static const struct file_operations device_fops = {
764 .release = device_close,
766 .write = device_write,
768 .owner = THIS_MODULE,
771 static const struct file_operations ctl_device_fops = {
772 .open = ctl_device_open,
773 .release = ctl_device_close,
774 .write = device_write,
775 .owner = THIS_MODULE,
778 int dlm_user_init(void)
782 ctl_device.name = "dlm-control";
783 ctl_device.fops = &ctl_device_fops;
784 ctl_device.minor = MISC_DYNAMIC_MINOR;
786 error = misc_register(&ctl_device);
788 log_print("misc_register failed for control device");
793 void dlm_user_exit(void)
795 misc_deregister(&ctl_device);