diff options
Diffstat (limited to 'sys/xfs/xfs_dev-common.c')
-rw-r--r-- | sys/xfs/xfs_dev-common.c | 149 |
1 files changed, 115 insertions, 34 deletions
diff --git a/sys/xfs/xfs_dev-common.c b/sys/xfs/xfs_dev-common.c index d9e5af3fcd6..ecbc3f1902e 100644 --- a/sys/xfs/xfs_dev-common.c +++ b/sys/xfs/xfs_dev-common.c @@ -1,7 +1,5 @@ -/* $OpenBSD: xfs_dev-common.c,v 1.2 2000/03/03 00:54:58 todd Exp $ */ - /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -46,7 +44,7 @@ #include <xfs/xfs_dev.h> #include <xfs/xfs_deb.h> -RCSID("$OpenBSD: xfs_dev-common.c,v 1.2 2000/03/03 00:54:58 todd Exp $"); +RCSID("$Id: xfs_dev-common.c,v 1.3 2000/09/11 14:26:51 art Exp $"); struct xfs_channel xfs_channel[NXFS]; @@ -59,14 +57,14 @@ xfs_initq(struct xfs_link *q) /* Is this queue empty? */ int -xfs_emptyq(struct xfs_link *q) +xfs_emptyq(const struct xfs_link *q) { return q->next == q; } /* Is this link on any queue? Link *must* be inited! */ int -xfs_onq(struct xfs_link *link) +xfs_onq(const struct xfs_link *link) { return link->next != NULL || link->prev != NULL; } @@ -81,12 +79,13 @@ xfs_appendq(struct xfs_link *q, struct xfs_link *p) q->prev = p; } +/* remove `p' from its queue */ void xfs_outq(struct xfs_link *p) { p->next->prev = p->prev; p->prev->next = p->next; - p->next = p->prev = 0; + p->next = p->prev = NULL; } /* @@ -194,20 +193,45 @@ xfs_devclose_common(dev_t dev, struct proc *proc) return 0; } +#ifdef XFS_DEBUG +/* + * osf glue for CURSIG + */ + +static long +xfs_cursig (struct proc *p) +{ +#ifdef __osf__ + thread_t th = current_thread(); + struct np_uthread *npu = thread_to_np_uthread(th); + return CURSIG(p,npu); +#else + return CURSIG(p); +#endif +} +#endif + /* * Move messages from kernel to user space. */ + int xfs_devread(dev_t dev, struct uio * uiop, int ioflag) { struct xfs_channel *chan = &xfs_channel[minor(dev)]; struct xfs_link *first; int error = 0; +#ifdef XFS_DEBUG + char devname[64]; +#endif - XFSDEB(XDEBDEV, ("xfs_devread dev = %d\n", dev)); + XFSDEB(XDEBDEV, ("xfs_devread dev = %s\n", + xfs_devtoname_r(dev, devname, sizeof(devname)))); - XFSDEB(XDEBDEV, ("xfs_devread: m = %p, m->prev = %p, m->next = %p\n", - &chan->messageq, chan->messageq.prev, chan->messageq.next)); + XFSDEB(XDEBDEV, ("xfs_devread: m = %lx, m->prev = %lx, m->next = %lx\n", + (unsigned long)&chan->messageq, + (unsigned long)chan->messageq.prev, + (unsigned long)chan->messageq.next)); again: @@ -215,13 +239,18 @@ xfs_devread(dev_t dev, struct uio * uiop, int ioflag) while (!xfs_emptyq (&chan->messageq)) { /* Remove message */ first = chan->messageq.next; - XFSDEB(XDEBDEV, ("xfs_devread: first = %p, " - "first->prev = %p, first->next = %p\n", - first, first->prev, first->next)); + XFSDEB(XDEBDEV, ("xfs_devread: first = %lx, " + "first->prev = %lx, first->next = %lx\n", + (unsigned long)first, + (unsigned long)first->prev, + (unsigned long)first->next)); XFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n", first->message->size)); + if (first->message->size > uiop->uio_resid) + break; + error = uiomove((caddr_t) first->message, first->message->size, uiop); if (error) @@ -234,8 +263,10 @@ xfs_devread(dev_t dev, struct uio * uiop, int ioflag) } } else { chan->status |= CHANNEL_WAITING; - if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsr", 0)) { - XFSDEB(XDEBMSG, ("caught signal xfs_devread\n")); + if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsread", 0)) { + XFSDEB(XDEBMSG, + ("caught signal xfs_devread: %ld\n", + xfs_cursig(xfs_uio_to_proc(uiop)))); error = EINTR; } else if ((chan->status & CHANNEL_WAITING) == 0) { goto again; @@ -243,7 +274,6 @@ xfs_devread(dev_t dev, struct uio * uiop, int ioflag) error = EIO; } - XFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error)); return error; @@ -261,8 +291,12 @@ xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag) int error; u_int cnt; struct xfs_message_header *msg_buf; +#ifdef XFS_DEBUG + char devname[64]; +#endif - XFSDEB(XDEBDEV, ("xfs_devwrite dev = %d\n", dev)); + XFSDEB(XDEBDEV, ("xfs_devwrite dev = %s\n", + xfs_devtoname_r (dev, devname, sizeof(devname)))); cnt = uiop->uio_resid; error = uiomove((caddr_t) chan->message_buffer, MAX_XMSG_SIZE, uiop); @@ -325,9 +359,18 @@ xfs_message_send(int fd, struct xfs_message_header * message, u_int size) return 0; } +#if defined(SWEXIT) +#define XFS_P_EXIT SWEXIT +#elif defined(P_WEXIT) +#define XFS_P_EXIT P_WEXIT +#else +#error what is your exit named ? +#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) { @@ -339,6 +382,8 @@ xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size) #if defined(HAVE_STRUCT_PROC_P_SIGMASK) sigset_t oldsigmask; #endif /* HAVE_STRUCT_PROC_P_SIGMASK */ + int catch; + struct proc *proc = xfs_curproc (); XFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode)); @@ -375,31 +420,57 @@ xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size) */ #ifdef HAVE_STRUCT_PROC_P_SIGMASK - oldsigmask = xfs_curproc()->p_sigmask; -#ifdef __sigaddset - __sigaddset(&xfs_curproc()->p_sigmask, SIGIO); + 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 - xfs_curproc()->p_sigmask |= sigmask(SIGIO); + proc->p_sigmask |= sigmask(SIGIO); + proc->p_sigmask |= sigmask(SIGALRM); + proc->p_sigmask |= sigmask(SIGVTALRM); #endif /* __sigaddset */ #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) - oldsigmask = xfs_curproc()->p_sigwaitmask; - sigaddset(&xfs_curproc()->p_sigwaitmask, SIGIO); + oldsigmask = proc->p_sigwaitmask; + sigaddset(&proc->p_sigwaitmask, SIGIO); + sigaddset(&proc->p_sigwaitmask, SIGALRM); + sigaddset(&proc->p_sigwaitmask, SIGVTALRM); #endif + + /* + * if we are exiting we should not try to catch signals, since + * there might not be enough context left in the process to handle + * signal delivery, and besides, most BSD-variants ignore all + * signals while closing anyway. + */ + + catch = 0; + if (!(proc->p_flag & XFS_P_EXIT)) + catch |= PCATCH; + /* * We have to check if we have a receiver here too because the * daemon could have terminated before we sleep. This seems to - * happen sometimes when rebooting. - */ - if (!(chan->status & CHANNEL_OPENED) || - tsleep((caddr_t) this_process, (PZERO + 1) | PCATCH, "xfs", 0)) { - XFSDEB(XDEBMSG, ("caught signal\n")); + * happen sometimes when rebooting. */ + + if (!(chan->status & CHANNEL_OPENED)) { + XFSDEB(XDEBMSG, ("xfs_message_rpc: channel went away\n")); + this_process->error_or_size = EINTR; + } else if ((ret = tsleep((caddr_t) this_process, + (PZERO + 1) | catch, "xfs", 0)) != 0) { + XFSDEB(XDEBMSG, ("caught signal (%d): %ld\n", + ret, xfs_cursig(proc))); this_process->error_or_size = EINTR; } #ifdef HAVE_STRUCT_PROC_P_SIGMASK - xfs_curproc()->p_sigmask = oldsigmask; + proc->p_sigmask = oldsigmask; #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) - xfs_curproc()->p_sigwaitmask = oldsigmask; + proc->p_sigwaitmask = oldsigmask; #endif /* @@ -482,6 +553,16 @@ xfs_message_receive(int fd, (struct xfs_message_updatefid *)message, message->size, p); + case XFS_MSG_GC_NODES: + return xfs_message_gc_nodes(fd, + (struct xfs_message_gc_nodes *)message, + message->size, + p); + case XFS_MSG_VERSION: + return xfs_message_version(fd, + (struct xfs_message_version *)message, + message->size, + p); default: printf("XFS PANIC Warning xfs_dev: Unknown message opcode == %d\n", message->opcode); @@ -552,10 +633,10 @@ xfs_uprintf_device(void) for (i = 0; i < NXFS; i++) { uprintf("xfs_channel[%d] = {\n", i); - uprintf("messageq.next = %p ", xfs_channel[i].messageq.next); - uprintf("messageq.prev = %p ", xfs_channel[i].messageq.prev); - uprintf("sleepq.next = %p ", xfs_channel[i].sleepq.next); - uprintf("sleepq.prev = %p ", xfs_channel[i].sleepq.prev); + uprintf("messageq.next = %lx ", xfs_channel[i].messageq.next); + uprintf("messageq.prev = %lx ", xfs_channel[i].messageq.prev); + uprintf("sleepq.next = %lx ", xfs_channel[i].sleepq.next); + uprintf("sleepq.prev = %lx ", xfs_channel[i].sleepq.prev); uprintf("nsequence = %d status = %d\n", xfs_channel[i].nsequence, xfs_channel[i].status); |