diff options
author | Hans Insulander <hin@cvs.openbsd.org> | 2002-06-07 04:10:33 +0000 |
---|---|---|
committer | Hans Insulander <hin@cvs.openbsd.org> | 2002-06-07 04:10:33 +0000 |
commit | c7406af60dafab45e920d9c3f52cd74cd4b9e81b (patch) | |
tree | d99f95636a30c46ffc4acee6363ac4bf9db13c89 /sys/xfs/xfs_dev-common.c | |
parent | 45d3283fa9b158e3ff3af143713064236a2eeb80 (diff) |
merge
Diffstat (limited to 'sys/xfs/xfs_dev-common.c')
-rw-r--r-- | sys/xfs/xfs_dev-common.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/sys/xfs/xfs_dev-common.c b/sys/xfs/xfs_dev-common.c index ecbc3f1902e..929e8a41628 100644 --- a/sys/xfs/xfs_dev-common.c +++ b/sys/xfs/xfs_dev-common.c @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -44,7 +39,7 @@ #include <xfs/xfs_dev.h> #include <xfs/xfs_deb.h> -RCSID("$Id: xfs_dev-common.c,v 1.3 2000/09/11 14:26:51 art Exp $"); +RCSID("$Id: xfs_dev-common.c,v 1.4 2002/06/07 04:10:32 hin Exp $"); struct xfs_channel xfs_channel[NXFS]; @@ -92,7 +87,7 @@ xfs_outq(struct xfs_link *p) * Only allow one open. */ int -xfs_devopen_common(dev_t dev) +xfs_devopen_common(dev_t dev, struct proc *p) { struct xfs_channel *chan; @@ -105,8 +100,9 @@ xfs_devopen_common(dev_t dev) if (chan->status & CHANNEL_OPENED) { XFSDEB(XDEBDEV, ("xfs_devopen: already open\n")); return EBUSY; - } else + } else { chan->status |= CHANNEL_OPENED; + } chan->message_buffer = xfs_alloc(MAX_XMSG_SIZE); @@ -233,6 +229,8 @@ xfs_devread(dev_t dev, struct uio * uiop, int ioflag) (unsigned long)chan->messageq.prev, (unsigned long)chan->messageq.next)); + chan->proc = xfs_uio_to_proc(uiop); + again: if (!xfs_emptyq (&chan->messageq)) { @@ -298,6 +296,7 @@ xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag) XFSDEB(XDEBDEV, ("xfs_devwrite dev = %s\n", xfs_devtoname_r (dev, devname, sizeof(devname)))); + chan->proc = xfs_uio_to_proc(uiop); cnt = uiop->uio_resid; error = uiomove((caddr_t) chan->message_buffer, MAX_XMSG_SIZE, uiop); if (error != 0) @@ -367,29 +366,61 @@ xfs_message_send(int fd, struct xfs_message_header * message, u_int size) #error what is your exit named ? #endif +#if defined(HAVE_STRUCT_PROC_P_SIGMASK) || defined(HAVE_STRUCT_PROC_P_SIGCTX) +static void +xfs_block_sigset (sigset_t *sigset) +{ +#if defined(__sigaddset) + __sigaddset(sigset, SIGIO); + __sigaddset(sigset, SIGALRM); + __sigaddset(sigset, SIGVTALRM); +#elif defined(SIGADDSET) + SIGADDSET(*sigset, SIGIO); + SIGADDSET(*sigset, SIGALRM); + SIGADDSET(*sigset, SIGVTALRM); +#else + *sigset |= sigmask(SIGIO); + *sigset |= sigmask(SIGALRM); + *sigset |= sigmask(SIGVTALRM); +#endif /* __sigaddset */ +} +#endif + /* * Send a message to user space and wait for reply. */ int -xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size) +xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size, + struct proc *proc) { int ret; struct xfs_channel *chan = &xfs_channel[fd]; struct xfs_link *this_message; struct xfs_link *this_process; struct xfs_message_header *msg; -#if defined(HAVE_STRUCT_PROC_P_SIGMASK) +#if defined(HAVE_STRUCT_PROC_P_SIGMASK) || defined(HAVE_STRUCT_PROC_P_SIGCTX) || defined(__osf__) sigset_t oldsigmask; -#endif /* HAVE_STRUCT_PROC_P_SIGMASK */ +#endif int catch; - struct proc *proc = xfs_curproc (); XFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode)); + if (proc == NULL) + proc = xfs_curproc(); + if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */ return ENODEV; + if (chan->proc != NULL && proc->p_pid == chan->proc->p_pid) { + printf("xfs_message_rpc: deadlock avoided " + "pid = %u == %u\n", proc->p_pid, chan->proc->p_pid); +#if 0 + psignal (proc, SIGABRT); +#endif + return EDEADLK; + } + if (size < sizeof(struct xfs_message_wakeup)) { printf("XFS PANIC Error: Message to small to receive wakeup, opcode = %d\n", message->opcode); return ENOMEM; @@ -420,25 +451,24 @@ xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size) */ #ifdef HAVE_STRUCT_PROC_P_SIGMASK + /* NetBSD 1.5, Darwin 1.3, FreeBSD 4.3, 5.0, OpenBSD 2.8 */ oldsigmask = proc->p_sigmask; -#if defined(__sigaddset) - __sigaddset(&proc->p_sigmask, SIGIO); - __sigaddset(&proc->p_sigmask, SIGALRM); - __sigaddset(&proc->p_sigmask, SIGVTALRM); -#elif defined(SIGADDSET) - SIGADDSET(proc->p_sigmask, SIGIO); - SIGADDSET(proc->p_sigmask, SIGALRM); - SIGADDSET(proc->p_sigmask, SIGVTALRM); -#else - proc->p_sigmask |= sigmask(SIGIO); - proc->p_sigmask |= sigmask(SIGALRM); - proc->p_sigmask |= sigmask(SIGVTALRM); -#endif /* __sigaddset */ + xfs_block_sigset (&proc->p_sigmask); +#elif defined(HAVE_STRUCT_PROC_P_SIGCTX) + /* NetBSD 1.6 */ + oldsigmask = proc->p_sigctx.ps_sigmask; + xfs_block_sigset (&proc->p_sigctx.ps_sigmask); #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) + /* OSF 4.0 */ oldsigmask = proc->p_sigwaitmask; sigaddset(&proc->p_sigwaitmask, SIGIO); sigaddset(&proc->p_sigwaitmask, SIGALRM); sigaddset(&proc->p_sigwaitmask, SIGVTALRM); +#elif defined(__osf__) + oldsigmask = u.u_sigmask; + sigaddset(&u.u_sigmask, SIGIO); + sigaddset(&u.u_sigmask, SIGALRM); + sigaddset(&u.u_sigmask, SIGVTALRM); #endif /* @@ -469,8 +499,12 @@ xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size) #ifdef HAVE_STRUCT_PROC_P_SIGMASK proc->p_sigmask = oldsigmask; +#elif defined(HAVE_STRUCT_PROC_P_SIGCTX) + proc->p_sigctx.ps_sigmask = oldsigmask; #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) proc->p_sigwaitmask = oldsigmask; +#elif defined(__osf__) + u.u_sigmask = oldsigmask; #endif /* |