summaryrefslogtreecommitdiff
path: root/sys/xfs/xfs_dev-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/xfs/xfs_dev-common.c')
-rw-r--r--sys/xfs/xfs_dev-common.c149
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);