diff options
Diffstat (limited to 'sys/fs/coda/coda_psdev.c')
-rw-r--r-- | sys/fs/coda/coda_psdev.c | 788 |
1 files changed, 0 insertions, 788 deletions
diff --git a/sys/fs/coda/coda_psdev.c b/sys/fs/coda/coda_psdev.c deleted file mode 100644 index 0d29f6e1d737..000000000000 --- a/sys/fs/coda/coda_psdev.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - * - * Coda: an Experimental Distributed File System - * Release 3.1 - * - * Copyright (c) 1987-1998 Carnegie Mellon University - * All Rights Reserved - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation, and - * that credit is given to Carnegie Mellon University in all documents - * and publicity pertaining to direct or indirect use of this code or its - * derivatives. - * - * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS, - * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS - * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON - * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER - * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF - * ANY DERIVATIVE WORK. - * - * Carnegie Mellon encourages users of this software to return any - * improvements or extensions that they make, and to grant Carnegie - * Mellon the rights to redistribute these changes without encumbrance. - * - * @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $ - * $Id: coda_psdev.c,v 1.9 1998/11/11 20:32:20 rvb Exp $ - * - */ - -/* - * Mach Operating System - * Copyright (c) 1989 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * This code was written for the Coda file system at Carnegie Mellon - * University. Contributers include David Steere, James Kistler, and - * M. Satyanarayanan. */ - -/* - * These routines define the psuedo device for communication between - * Coda's Venus and Minicache in Mach 2.6. They used to be in cfs_subr.c, - * but I moved them to make it easier to port the Minicache without - * porting coda. -- DCS 10/12/94 - */ - -/* - * HISTORY - * $Log: coda_psdev.c,v $ - * Revision 1.9 1998/11/11 20:32:20 rvb - * coda_lookup now passes up an extra flag. But old veni will - * be ok; new veni will check /dev/cfs0 to make sure that a new - * kernel is running. - * Also, a bug in vc_nb_close iff CODA_SIGNAL's were seen has been - * fixed. - * - * Revision 1.8 1998/10/28 20:31:13 rvb - * Change the way unmounting happens to guarantee that the - * client programs are allowed to finish up (coda_call is - * forced to complete) and release their locks. Thus there - * is a reasonable chance that the vflush implicit in the - * unmount will not get hung on held locks. - * - * Revision 1.7 1998/09/29 20:19:45 rvb - * Fixes for lkm: - * 1. use VFS_LKM vs ACTUALLY_LKM_NOT_KERNEL - * 2. don't pass -DCODA to lkm build - * - * Revision 1.6 1998/09/28 20:52:58 rvb - * Cleanup and fix THE bug - * - * Revision 1.5 1998/09/25 17:38:31 rvb - * Put "stray" printouts under DIAGNOSTIC. Make everything build - * with DEBUG on. Add support for lkm. (The macro's don't work - * for me; for a good chuckle look at the end of coda_fbsd.c.) - * - * Revision 1.4 1998/09/13 13:57:59 rvb - * Finish conversion of cfs -> coda - * - * Revision 1.3 1998/09/11 18:50:17 rvb - * All the references to cfs, in symbols, structs, and strings - * have been changed to coda. (Same for CFS.) - * - * Revision 1.2 1998/09/02 19:09:53 rvb - * Pass2 complete - * - * Revision 1.1.1.1 1998/08/29 21:14:52 rvb - * Very Preliminary Coda - * - * Revision 1.9 1998/08/28 18:12:17 rvb - * Now it also works on FreeBSD -current. This code will be - * committed to the FreeBSD -current and NetBSD -current - * trees. It will then be tailored to the particular platform - * by flushing conditional code. - * - * Revision 1.8 1998/08/18 17:05:15 rvb - * Don't use __RCSID now - * - * Revision 1.7 1998/08/18 16:31:41 rvb - * Sync the code for NetBSD -current; test on 1.3 later - * - * Revision 1.8 1998/06/09 23:30:42 rvb - * Try to allow ^C -- take 1 - * - * Revision 1.5.2.8 98/01/23 11:21:04 rvb - * Sync with 2.2.5 - * - * Revision 1.5.2.7 98/01/22 22:22:21 rvb - * sync 1.2 and 1.3 - * - * Revision 1.5.2.6 98/01/22 13:11:24 rvb - * Move make_coda_node ctlfid later so vfsp is known; work on ^c and ^z - * - * Revision 1.5.2.5 97/12/16 22:01:27 rvb - * Oops add cfs_subr.h cfs_venus.h; sync with peter - * - * Revision 1.5.2.4 97/12/16 12:40:05 rvb - * Sync with 1.3 - * - * Revision 1.5.2.3 97/12/10 14:08:24 rvb - * Fix O_ flags; check result in coda_call - * - * Revision 1.5.2.2 97/12/10 11:40:24 rvb - * No more ody - * - * Revision 1.5.2.1 97/12/06 17:41:20 rvb - * Sync with peters coda.h - * - * Revision 1.5 97/12/05 10:39:16 rvb - * Read CHANGES - * - * Revision 1.4.18.9 97/12/05 08:58:07 rvb - * peter found this one - * - * Revision 1.4.18.8 97/11/26 15:28:57 rvb - * Cant make downcall pbuf == union cfs_downcalls yet - * - * Revision 1.4.18.7 97/11/25 09:40:49 rvb - * Final cfs_venus.c w/o macros, but one locking bug - * - * Revision 1.4.18.6 97/11/20 11:46:41 rvb - * Capture current cfs_venus - * - * Revision 1.4.18.5 97/11/18 10:27:15 rvb - * cfs_nbsd.c is DEAD!!!; integrated into cfs_vf/vnops.c - * cfs_nb_foo and cfs_foo are joined - * - * Revision 1.4.18.4 97/11/13 22:02:59 rvb - * pass2 cfs_NetBSD.h mt - * - * Revision 1.4.18.3 97/11/12 12:09:38 rvb - * reorg pass1 - * - * Revision 1.4.18.2 97/10/29 16:06:09 rvb - * Kill DYING - * - * Revision 1.4.18.1 1997/10/28 23:10:15 rvb - * >64Meg; venus can be killed! - * - * Revision 1.4 1996/12/12 22:10:58 bnoble - * Fixed the "downcall invokes venus operation" deadlock in all known cases. - * There may be more - * - * Revision 1.3 1996/11/13 04:14:20 bnoble - * Merging BNOBLE_WORK_6_20_96 into main line - * - * Revision 1.2.8.1 1996/08/22 14:25:04 bnoble - * Added a return code from vc_nb_close - * - * Revision 1.2 1996/01/02 16:56:58 bnoble - * Added support for Coda MiniCache and raw inode calls (final commit) - * - * Revision 1.1.2.1 1995/12/20 01:57:24 bnoble - * Added CODA-specific files - * - * Revision 1.1 1995/03/14 20:52:15 bnoble - * Initial revision - * - */ - -/* These routines are the device entry points for Venus. */ - -extern int coda_nc_initialized; /* Set if cache has been initialized */ - -#include <vcoda.h> - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/file.h> -#include <sys/ioccom.h> -#include <sys/poll.h> -#include <sys/conf.h> - -#include <coda/coda.h> -#include <coda/cnode.h> -#include <coda/coda_namecache.h> -#include <coda/coda_io.h> -#include <coda/coda_psdev.h> - -#define CTL_C - -int coda_psdev_print_entry = 0; -static -int outstanding_upcalls = 0; -int coda_call_sleep = PZERO - 1; -#ifdef CTL_C -int coda_pcatch = PCATCH; -#else -#endif - -#define ENTRY if(coda_psdev_print_entry) myprintf(("Entered %s\n",__FUNCTION__)) - -void vcodaattach(int n); - -struct vmsg { - struct queue vm_chain; - caddr_t vm_data; - u_short vm_flags; - u_short vm_inSize; /* Size is at most 5000 bytes */ - u_short vm_outSize; - u_short vm_opcode; /* copied from data to save ptr lookup */ - int vm_unique; - caddr_t vm_sleep; /* Not used by Mach. */ -}; - -#define VM_READ 1 -#define VM_WRITE 2 -#define VM_INTR 4 - -/* vcodaattach: do nothing */ -void -vcodaattach(n) - int n; -{ -} - -int -vc_nb_open(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; /* NetBSD only */ -{ - register struct vcomm *vcp; - - ENTRY; - - if (minor(dev) >= NVCODA || minor(dev) < 0) - return(ENXIO); - - if (!coda_nc_initialized) - coda_nc_init(); - - vcp = &coda_mnttbl[minor(dev)].mi_vcomm; - if (VC_OPEN(vcp)) - return(EBUSY); - - bzero(&(vcp->vc_selproc), sizeof (struct selinfo)); - INIT_QUEUE(vcp->vc_requests); - INIT_QUEUE(vcp->vc_replys); - MARK_VC_OPEN(vcp); - - coda_mnttbl[minor(dev)].mi_vfsp = NULL; - coda_mnttbl[minor(dev)].mi_rootvp = NULL; - - return(0); -} - -int -vc_nb_close (dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - register struct vcomm *vcp; - register struct vmsg *vmp, *nvmp = NULL; - struct coda_mntinfo *mi; - int err; - - ENTRY; - - if (minor(dev) >= NVCODA || minor(dev) < 0) - return(ENXIO); - - mi = &coda_mnttbl[minor(dev)]; - vcp = &(mi->mi_vcomm); - - if (!VC_OPEN(vcp)) - panic("vcclose: not open"); - - /* prevent future operations on this vfs from succeeding by auto- - * unmounting any vfs mounted via this device. This frees user or - * sysadm from having to remember where all mount points are located. - * Put this before WAKEUPs to avoid queuing new messages between - * the WAKEUP and the unmount (which can happen if we're unlucky) - */ - if (!mi->mi_rootvp) { - /* just a simple open/close w no mount */ - MARK_VC_CLOSED(vcp); - return 0; - } - - /* Let unmount know this is for real */ - VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING; - coda_unmounting(mi->mi_vfsp); - - outstanding_upcalls = 0; - /* Wakeup clients so they can return. */ - for (vmp = (struct vmsg *)GETNEXT(vcp->vc_requests); - !EOQ(vmp, vcp->vc_requests); - vmp = nvmp) - { - nvmp = (struct vmsg *)GETNEXT(vmp->vm_chain); - /* Free signal request messages and don't wakeup cause - no one is waiting. */ - if (vmp->vm_opcode == CODA_SIGNAL) { - CODA_FREE((caddr_t)vmp->vm_data, (u_int)VC_IN_NO_DATA); - CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg)); - continue; - } - outstanding_upcalls++; - wakeup(&vmp->vm_sleep); - } - - for (vmp = (struct vmsg *)GETNEXT(vcp->vc_replys); - !EOQ(vmp, vcp->vc_replys); - vmp = (struct vmsg *)GETNEXT(vmp->vm_chain)) - { - outstanding_upcalls++; - wakeup(&vmp->vm_sleep); - } - - MARK_VC_CLOSED(vcp); - - if (outstanding_upcalls) { -#ifdef CODA_VERBOSE - printf("presleep: outstanding_upcalls = %d\n", outstanding_upcalls); - (void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0); - printf("postsleep: outstanding_upcalls = %d\n", outstanding_upcalls); -#else - (void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0); -#endif - } - - err = dounmount(mi->mi_vfsp, flag, p); - if (err) - myprintf(("Error %d unmounting vfs in vcclose(%d)\n", - err, minor(dev))); - return 0; -} - -int -vc_nb_read(dev, uiop, flag) - dev_t dev; - struct uio *uiop; - int flag; -{ - register struct vcomm * vcp; - register struct vmsg *vmp; - int error = 0; - - ENTRY; - - if (minor(dev) >= NVCODA || minor(dev) < 0) - return(ENXIO); - - vcp = &coda_mnttbl[minor(dev)].mi_vcomm; - /* Get message at head of request queue. */ - if (EMPTY(vcp->vc_requests)) - return(0); /* Nothing to read */ - - vmp = (struct vmsg *)GETNEXT(vcp->vc_requests); - - /* Move the input args into userspace */ - uiop->uio_rw = UIO_READ; - error = uiomove(vmp->vm_data, vmp->vm_inSize, uiop); - if (error) { - myprintf(("vcread: error (%d) on uiomove\n", error)); - error = EINVAL; - } - -#ifdef OLD_DIAGNOSTIC - if (vmp->vm_chain.forw == 0 || vmp->vm_chain.back == 0) - panic("vc_nb_read: bad chain"); -#endif - - REMQUE(vmp->vm_chain); - - /* If request was a signal, free up the message and don't - enqueue it in the reply queue. */ - if (vmp->vm_opcode == CODA_SIGNAL) { - if (codadebug) - myprintf(("vcread: signal msg (%d, %d)\n", - vmp->vm_opcode, vmp->vm_unique)); - CODA_FREE((caddr_t)vmp->vm_data, (u_int)VC_IN_NO_DATA); - CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg)); - return(error); - } - - vmp->vm_flags |= VM_READ; - INSQUE(vmp->vm_chain, vcp->vc_replys); - - return(error); -} - -int -vc_nb_write(dev, uiop, flag) - dev_t dev; - struct uio *uiop; - int flag; -{ - register struct vcomm * vcp; - register struct vmsg *vmp; - struct coda_out_hdr *out; - u_long seq; - u_long opcode; - int buf[2]; - int error = 0; - - ENTRY; - - if (minor(dev) >= NVCODA || minor(dev) < 0) - return(ENXIO); - - vcp = &coda_mnttbl[minor(dev)].mi_vcomm; - - /* Peek at the opcode, unique without transfering the data. */ - uiop->uio_rw = UIO_WRITE; - error = uiomove((caddr_t)buf, sizeof(int) * 2, uiop); - if (error) { - myprintf(("vcwrite: error (%d) on uiomove\n", error)); - return(EINVAL); - } - - opcode = buf[0]; - seq = buf[1]; - - if (codadebug) - myprintf(("vcwrite got a call for %ld.%ld\n", opcode, seq)); - - if (DOWNCALL(opcode)) { - union outputArgs pbuf; - - /* get the rest of the data. */ - uiop->uio_rw = UIO_WRITE; - error = uiomove((caddr_t)&pbuf.coda_purgeuser.oh.result, sizeof(pbuf) - (sizeof(int)*2), uiop); - if (error) { - myprintf(("vcwrite: error (%d) on uiomove (Op %ld seq %ld)\n", - error, opcode, seq)); - return(EINVAL); - } - - return handleDownCall(opcode, &pbuf); - } - - /* Look for the message on the (waiting for) reply queue. */ - for (vmp = (struct vmsg *)GETNEXT(vcp->vc_replys); - !EOQ(vmp, vcp->vc_replys); - vmp = (struct vmsg *)GETNEXT(vmp->vm_chain)) - { - if (vmp->vm_unique == seq) break; - } - - if (EOQ(vmp, vcp->vc_replys)) { - if (codadebug) - myprintf(("vcwrite: msg (%ld, %ld) not found\n", opcode, seq)); - - return(ESRCH); - } - - /* Remove the message from the reply queue */ - REMQUE(vmp->vm_chain); - - /* move data into response buffer. */ - out = (struct coda_out_hdr *)vmp->vm_data; - /* Don't need to copy opcode and uniquifier. */ - - /* get the rest of the data. */ - if (vmp->vm_outSize < uiop->uio_resid) { - myprintf(("vcwrite: more data than asked for (%d < %d)\n", - vmp->vm_outSize, uiop->uio_resid)); - wakeup(&vmp->vm_sleep); /* Notify caller of the error. */ - return(EINVAL); - } - - buf[0] = uiop->uio_resid; /* Save this value. */ - uiop->uio_rw = UIO_WRITE; - error = uiomove((caddr_t) &out->result, vmp->vm_outSize - (sizeof(int) * 2), uiop); - if (error) { - myprintf(("vcwrite: error (%d) on uiomove (op %ld seq %ld)\n", - error, opcode, seq)); - return(EINVAL); - } - - /* I don't think these are used, but just in case. */ - /* XXX - aren't these two already correct? -bnoble */ - out->opcode = opcode; - out->unique = seq; - vmp->vm_outSize = buf[0]; /* Amount of data transferred? */ - vmp->vm_flags |= VM_WRITE; - wakeup(&vmp->vm_sleep); - - return(0); -} - -int -vc_nb_ioctl(dev, cmd, addr, flag, p) - dev_t dev; - u_long cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - ENTRY; - - switch(cmd) { - case CODARESIZE: { - struct coda_resize *data = (struct coda_resize *)addr; - return(coda_nc_resize(data->hashsize, data->heapsize, IS_DOWNCALL)); - break; - } - case CODASTATS: - if (coda_nc_use) { - coda_nc_gather_stats(); - return(0); - } else { - return(ENODEV); - } - break; - case CODAPRINT: - if (coda_nc_use) { - print_coda_nc(); - return(0); - } else { - return(ENODEV); - } - break; - case CIOC_KERNEL_VERSION: - switch (*(u_int *)addr) { - case 0: - *(u_int *)addr = coda_kernel_version; - return 0; - break; - case 1: - case 2: - if (coda_kernel_version != *(u_int *)addr) - return ENOENT; - else - return 0; - default: - return ENOENT; - } - break; - default : - return(EINVAL); - break; - } -} - -int -vc_nb_poll(dev, events, p) - dev_t dev; - int events; - struct proc *p; -{ - register struct vcomm *vcp; - int event_msk = 0; - - ENTRY; - - if (minor(dev) >= NVCODA || minor(dev) < 0) - return(ENXIO); - - vcp = &coda_mnttbl[minor(dev)].mi_vcomm; - - event_msk = events & (POLLIN|POLLRDNORM); - if (!event_msk) - return(0); - - if (!EMPTY(vcp->vc_requests)) - return(events & (POLLIN|POLLRDNORM)); - - selrecord(p, &(vcp->vc_selproc)); - - return(0); -} - -/* - * Statistics - */ -struct coda_clstat coda_clstat; - -/* - * Key question: whether to sleep interuptably or uninteruptably when - * waiting for Venus. The former seems better (cause you can ^C a - * job), but then GNU-EMACS completion breaks. Use tsleep with no - * timeout, and no longjmp happens. But, when sleeping - * "uninterruptibly", we don't get told if it returns abnormally - * (e.g. kill -9). - */ - -int -coda_call(mntinfo, inSize, outSize, buffer) - struct coda_mntinfo *mntinfo; int inSize; int *outSize; caddr_t buffer; -{ - struct vcomm *vcp; - struct vmsg *vmp; - int error; -#ifdef CTL_C - struct proc *p = curproc; - unsigned int psig_omask = p->p_sigmask; - int i; -#endif - if (mntinfo == NULL) { - /* Unlikely, but could be a race condition with a dying warden */ - return ENODEV; - } - - vcp = &(mntinfo->mi_vcomm); - - coda_clstat.ncalls++; - coda_clstat.reqs[((struct coda_in_hdr *)buffer)->opcode]++; - - if (!VC_OPEN(vcp)) - return(ENODEV); - - CODA_ALLOC(vmp,struct vmsg *,sizeof(struct vmsg)); - /* Format the request message. */ - vmp->vm_data = buffer; - vmp->vm_flags = 0; - vmp->vm_inSize = inSize; - vmp->vm_outSize - = *outSize ? *outSize : inSize; /* |buffer| >= inSize */ - vmp->vm_opcode = ((struct coda_in_hdr *)buffer)->opcode; - vmp->vm_unique = ++vcp->vc_seq; - if (codadebug) - myprintf(("Doing a call for %d.%d\n", - vmp->vm_opcode, vmp->vm_unique)); - - /* Fill in the common input args. */ - ((struct coda_in_hdr *)buffer)->unique = vmp->vm_unique; - - /* Append msg to request queue and poke Venus. */ - INSQUE(vmp->vm_chain, vcp->vc_requests); - selwakeup(&(vcp->vc_selproc)); - - /* We can be interrupted while we wait for Venus to process - * our request. If the interrupt occurs before Venus has read - * the request, we dequeue and return. If it occurs after the - * read but before the reply, we dequeue, send a signal - * message, and return. If it occurs after the reply we ignore - * it. In no case do we want to restart the syscall. If it - * was interrupted by a venus shutdown (vcclose), return - * ENODEV. */ - - /* Ignore return, We have to check anyway */ -#ifdef CTL_C - /* This is work in progress. Setting coda_pcatch lets tsleep reawaken - on a ^c or ^z. The problem is that emacs sets certain interrupts - as SA_RESTART. This means that we should exit sleep handle the - "signal" and then go to sleep again. Mostly this is done by letting - the syscall complete and be restarted. We are not idempotent and - can not do this. A better solution is necessary. - */ - i = 0; - do { - error = tsleep(&vmp->vm_sleep, (coda_call_sleep|coda_pcatch), "coda_call", hz*2); - if (error == 0) - break; - else if (error == EWOULDBLOCK) { -#ifdef CODA_VERBOSE - printf("coda_call: tsleep TIMEOUT %d sec\n", 2+2*i); -#endif - } else if (p->p_siglist == sigmask(SIGIO)) { - p->p_sigmask |= p->p_siglist; -#ifdef CODA_VERBOSE - printf("coda_call: tsleep returns %d SIGIO, cnt %d\n", error, i); -#endif - } else if (p->p_siglist == sigmask(SIGALRM)) { - p->p_sigmask |= p->p_siglist; -#ifdef CODA_VERBOSE - printf("coda_call: tsleep returns %d SIGALRM, cnt %d\n", error, i); -#endif - } else { - printf("coda_call: tsleep returns %d, cnt %d\n", error, i); - printf("coda_call: siglist = %x, sigmask = %x, mask %x\n", - p->p_siglist, p->p_sigmask, - p->p_siglist & ~p->p_sigmask); - break; -#ifdef notyet - p->p_sigmask |= p->p_siglist; - printf("coda_call: new mask, siglist = %x, sigmask = %x, mask %x\n", - p->p_siglist, p->p_sigmask, - p->p_siglist & ~p->p_sigmask); -#endif - } - } while (error && i++ < 128 && VC_OPEN(vcp)); - p->p_sigmask = psig_omask; -#else - (void) tsleep(&vmp->vm_sleep, coda_call_sleep, "coda_call", 0); -#endif - if (VC_OPEN(vcp)) { /* Venus is still alive */ - /* Op went through, interrupt or not... */ - if (vmp->vm_flags & VM_WRITE) { - error = 0; - *outSize = vmp->vm_outSize; - } - - else if (!(vmp->vm_flags & VM_READ)) { - /* Interrupted before venus read it. */ -#ifdef CODA_VERBOSE - if (1) -#else - if (codadebug) -#endif - myprintf(("interrupted before read: op = %d.%d, flags = %x\n", - vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags)); - REMQUE(vmp->vm_chain); - error = EINTR; - } - - else { - /* (!(vmp->vm_flags & VM_WRITE)) means interrupted after - upcall started */ - /* Interrupted after start of upcall, send venus a signal */ - struct coda_in_hdr *dog; - struct vmsg *svmp; - -#ifdef CODA_VERBOSE - if (1) -#else - if (codadebug) -#endif - myprintf(("Sending Venus a signal: op = %d.%d, flags = %x\n", - vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags)); - - REMQUE(vmp->vm_chain); - error = EINTR; - - CODA_ALLOC(svmp, struct vmsg *, sizeof (struct vmsg)); - - CODA_ALLOC((svmp->vm_data), char *, sizeof (struct coda_in_hdr)); - dog = (struct coda_in_hdr *)svmp->vm_data; - - svmp->vm_flags = 0; - dog->opcode = svmp->vm_opcode = CODA_SIGNAL; - dog->unique = svmp->vm_unique = vmp->vm_unique; - svmp->vm_inSize = sizeof (struct coda_in_hdr); -/*??? rvb */ svmp->vm_outSize = sizeof (struct coda_in_hdr); - - if (codadebug) - myprintf(("coda_call: enqueing signal msg (%d, %d)\n", - svmp->vm_opcode, svmp->vm_unique)); - - /* insert at head of queue! */ - INSQUE(svmp->vm_chain, vcp->vc_requests); - selwakeup(&(vcp->vc_selproc)); - } - } - - else { /* If venus died (!VC_OPEN(vcp)) */ - if (codadebug) - myprintf(("vcclose woke op %d.%d flags %d\n", - vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags)); - - error = ENODEV; - } - - CODA_FREE(vmp, sizeof(struct vmsg)); - - if (outstanding_upcalls > 0 && (--outstanding_upcalls == 0)) - wakeup(&outstanding_upcalls); - - if (!error) - error = ((struct coda_out_hdr *)buffer)->result; - return(error); -} |