Annotation of sys/xfs/xfs_dev-common.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan
! 3: * (Royal Institute of Technology, Stockholm, Sweden).
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: *
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: *
! 17: * 3. Neither the name of the Institute nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: */
! 33:
! 34:
! 35: #include <xfs/xfs_locl.h>
! 36: #include <xfs/xfs_message.h>
! 37: #include <xfs/xfs_msg_locl.h>
! 38: #include <xfs/xfs_fs.h>
! 39: #include <xfs/xfs_dev.h>
! 40: #include <xfs/xfs_deb.h>
! 41:
! 42: RCSID("$arla: xfs_dev-common.c,v 1.61 2003/07/15 16:25:42 lha Exp $");
! 43:
! 44: struct xfs_channel xfs_channel[NNNPFS];
! 45:
! 46: void
! 47: xfs_initq(struct xfs_link *q)
! 48: {
! 49: q->next = q;
! 50: q->prev = q;
! 51: }
! 52:
! 53: /* Is this queue empty? */
! 54: int
! 55: xfs_emptyq(const struct xfs_link *q)
! 56: {
! 57: return q->next == q;
! 58: }
! 59:
! 60: /* Is this link on any queue? Link *must* be inited! */
! 61: int
! 62: xfs_onq(const struct xfs_link *link)
! 63: {
! 64: return link->next != NULL || link->prev != NULL;
! 65: }
! 66:
! 67: /* Append q with p */
! 68: void
! 69: xfs_appendq(struct xfs_link *q, struct xfs_link *p)
! 70: {
! 71: p->next = q;
! 72: p->prev = q->prev;
! 73: p->prev->next = p;
! 74: q->prev = p;
! 75: }
! 76:
! 77: /* remove `p' from its queue */
! 78: void
! 79: xfs_outq(struct xfs_link *p)
! 80: {
! 81: p->next->prev = p->prev;
! 82: p->prev->next = p->next;
! 83: p->next = p->prev = NULL;
! 84: }
! 85:
! 86: /*
! 87: * Only allow one open.
! 88: */
! 89: int
! 90: xfs_devopen_common(dev_t dev)
! 91: {
! 92: struct xfs_channel *chan;
! 93:
! 94: if (minor(dev) < 0 || minor(dev) >= NNNPFS)
! 95: return ENXIO;
! 96:
! 97: chan = &xfs_channel[minor(dev)];
! 98:
! 99: /* Only allow one reader/writer */
! 100: if (chan->status & CHANNEL_OPENED) {
! 101: NNPFSDEB(XDEBDEV, ("xfs_devopen: already open\n"));
! 102: return EBUSY;
! 103: } else {
! 104: chan->status |= CHANNEL_OPENED;
! 105: }
! 106:
! 107: chan->message_buffer = xfs_alloc(MAX_XMSG_SIZE, M_NNPFS_MSG);
! 108:
! 109: /* initialize the queues if they have not been initialized before */
! 110: xfs_initq(&chan->sleepq);
! 111: xfs_initq(&chan->messageq);
! 112:
! 113: return 0;
! 114: }
! 115:
! 116: #if defined(HAVE_TWO_ARGUMENT_VFS_BUSY)
! 117: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags))
! 118: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
! 119: #elif defined(HAVE_THREE_ARGUMENT_VFS_BUSY)
! 120: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock))
! 121: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
! 122: #elif defined(HAVE_FOUR_ARGUMENT_VFS_BUSY)
! 123: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock), (proc))
! 124: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp), (proc))
! 125: #elif defined(__osf__)
! 126: #define xfs_vfs_busy(mp, flags, lock, proc) (0)
! 127: #define xfs_vfs_unbusy(mp, proc) (0)
! 128: #else
! 129: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp))
! 130: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
! 131: #endif
! 132:
! 133: /*
! 134: * Wakeup all sleepers and cleanup.
! 135: */
! 136: int
! 137: xfs_devclose_common(dev_t dev, d_thread_t *proc)
! 138: {
! 139: struct xfs_channel *chan = &xfs_channel[minor(dev)];
! 140: struct xfs_link *first;
! 141:
! 142: /* Sanity check, paranoia? */
! 143: if (!(chan->status & CHANNEL_OPENED))
! 144: panic("xfs_devclose never opened?");
! 145:
! 146: chan->status &= ~CHANNEL_OPENED;
! 147:
! 148: /* No one is going to read those messages so empty queue! */
! 149: while (!xfs_emptyq(&chan->messageq)) {
! 150: NNPFSDEB(XDEBDEV, ("before outq(messageq)\n"));
! 151:
! 152: first = chan->messageq.next;
! 153: xfs_outq(first);
! 154: if (first->error_or_size != 0)
! 155: xfs_free(first, first->error_or_size, M_NNPFS_LINK);
! 156:
! 157: NNPFSDEB(XDEBDEV, ("after outq(messageq)\n"));
! 158: }
! 159:
! 160: /* Wakeup those waiting for replies that will never arrive. */
! 161: while (!xfs_emptyq(&chan->sleepq)) {
! 162: NNPFSDEB(XDEBDEV, ("before outq(sleepq)\n"));
! 163: first = chan->sleepq.next;
! 164: xfs_outq(first);
! 165: first->error_or_size = ENODEV;
! 166: wakeup((caddr_t) first);
! 167: NNPFSDEB(XDEBDEV, ("after outq(sleepq)\n"));
! 168: }
! 169:
! 170: if (chan->status & CHANNEL_WAITING)
! 171: wakeup((caddr_t) chan);
! 172:
! 173: if (chan->message_buffer) {
! 174: xfs_free(chan->message_buffer, MAX_XMSG_SIZE, M_NNPFS_MSG);
! 175: chan->message_buffer = NULL;
! 176: }
! 177:
! 178: /*
! 179: * Free all xfs nodes.
! 180: */
! 181:
! 182: if (xfs[minor(dev)].mp != NULL) {
! 183: if (xfs_vfs_busy(xfs[minor(dev)].mp, VB_READ|VB_WAIT, NULL, proc)) {
! 184: NNPFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n"));
! 185: return EBUSY;
! 186: }
! 187: free_all_xfs_nodes(&xfs[minor(dev)], FORCECLOSE, 0);
! 188:
! 189: xfs_vfs_unbusy(xfs[minor(dev)].mp, proc);
! 190: }
! 191:
! 192: return 0;
! 193: }
! 194:
! 195: #ifdef NNPFS_DEBUG
! 196: /*
! 197: * debugging glue for CURSIG
! 198: */
! 199:
! 200: static long
! 201: xfs_cursig (d_thread_t *p)
! 202: {
! 203: #if defined(__osf__)
! 204: thread_t th = current_thread();
! 205: struct np_uthread *npu = thread_to_np_uthread(th);
! 206: return CURSIG(p,npu);
! 207: #elif defined(HAVE_FREEBSD_THREAD)
! 208: #ifndef CURSIG
! 209: return 0; /* XXX we would like to use sig_ffs, but that isn't
! 210: * exported */
! 211: #else
! 212: return CURSIG(p->td_proc);
! 213: #endif
! 214: #else
! 215: #if defined(__NetBSD__) && __NetBSD_Version__ >= 106130000
! 216: return 0; /* XXX CURSIG operates on a struct lwp */
! 217: #else
! 218: return CURSIG(p);
! 219: #endif
! 220: #endif
! 221: }
! 222: #endif
! 223:
! 224: /*
! 225: * Move messages from kernel to user space.
! 226: */
! 227:
! 228: int
! 229: xfs_devread(dev_t dev, struct uio * uiop, int ioflag)
! 230: {
! 231: struct xfs_channel *chan = &xfs_channel[minor(dev)];
! 232: struct xfs_link *first;
! 233: int error = 0;
! 234: #ifdef NNPFS_DEBUG
! 235: char devname[64];
! 236: #endif
! 237:
! 238: NNPFSDEB(XDEBDEV, ("xfs_devread dev = %s\n",
! 239: xfs_devtoname_r(dev, devname, sizeof(devname))));
! 240:
! 241: NNPFSDEB(XDEBDEV, ("xfs_devread: m = %lx, m->prev = %lx, m->next = %lx\n",
! 242: (unsigned long)&chan->messageq,
! 243: (unsigned long)chan->messageq.prev,
! 244: (unsigned long)chan->messageq.next));
! 245:
! 246: #ifdef HAVE_FREEBSD_THREAD
! 247: chan->proc = xfs_uio_to_thread(uiop);
! 248: #else
! 249: chan->proc = xfs_uio_to_proc(uiop);
! 250: #endif
! 251:
! 252: again:
! 253:
! 254: if (!xfs_emptyq (&chan->messageq)) {
! 255: while (!xfs_emptyq (&chan->messageq)) {
! 256: /* Remove message */
! 257: first = chan->messageq.next;
! 258: NNPFSDEB(XDEBDEV, ("xfs_devread: first = %lx, "
! 259: "first->prev = %lx, first->next = %lx\n",
! 260: (unsigned long)first,
! 261: (unsigned long)first->prev,
! 262: (unsigned long)first->next));
! 263:
! 264: NNPFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n",
! 265: first->message->size));
! 266:
! 267: if (first->message->size > uiop->uio_resid)
! 268: break;
! 269:
! 270: error = uiomove((caddr_t) first->message, first->message->size,
! 271: uiop);
! 272: if (error)
! 273: break;
! 274:
! 275: xfs_outq(first);
! 276:
! 277: if (first->error_or_size != 0)
! 278: xfs_free(first, first->error_or_size, M_NNPFS_LINK);
! 279: }
! 280: } else {
! 281: chan->status |= CHANNEL_WAITING;
! 282: if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsread", 0)) {
! 283: #ifdef HAVE_FREEBSD_THREAD
! 284: NNPFSDEB(XDEBMSG,
! 285: ("caught signal xfs_devread: %ld\n",
! 286: xfs_cursig(xfs_uio_to_thread(uiop))));
! 287: #else
! 288: NNPFSDEB(XDEBMSG,
! 289: ("caught signal xfs_devread: %ld\n",
! 290: xfs_cursig(xfs_uio_to_proc(uiop))));
! 291: #endif
! 292: error = EINTR;
! 293: } else if ((chan->status & CHANNEL_WAITING) == 0) {
! 294: goto again;
! 295: } else
! 296: error = EIO;
! 297: }
! 298:
! 299: NNPFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error));
! 300:
! 301: return error;
! 302: }
! 303:
! 304: /*
! 305: * Move messages from user space to kernel space,
! 306: * wakeup sleepers, insert new data in VFS.
! 307: */
! 308: int
! 309: xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag)
! 310: {
! 311: struct xfs_channel *chan = &xfs_channel[minor(dev)];
! 312: char *p;
! 313: int error;
! 314: u_int cnt;
! 315: struct xfs_message_header *msg_buf;
! 316: #ifdef NNPFS_DEBUG
! 317: char devname[64];
! 318: #endif
! 319:
! 320: NNPFSDEB(XDEBDEV, ("xfs_devwrite dev = %s\n",
! 321: xfs_devtoname_r (dev, devname, sizeof(devname))));
! 322:
! 323: #ifdef HAVE_FREEBSD_THREAD
! 324: chan->proc = xfs_uio_to_thread(uiop);
! 325: #else
! 326: chan->proc = xfs_uio_to_proc(uiop);
! 327: #endif
! 328: cnt = uiop->uio_resid;
! 329: error = uiomove((caddr_t) chan->message_buffer, MAX_XMSG_SIZE, uiop);
! 330: if (error != 0)
! 331: return error;
! 332:
! 333: cnt -= uiop->uio_resid;
! 334:
! 335: /*
! 336: * This thread handles the received message.
! 337: */
! 338: for (p = (char *)chan->message_buffer;
! 339: cnt > 0;
! 340: p += msg_buf->size, cnt -= msg_buf->size) {
! 341: #ifdef HAVE_FREEBSD_THREAD
! 342: d_thread_t *pp = xfs_uio_to_thread(uiop);
! 343: #else
! 344: d_thread_t *pp = xfs_uio_to_proc(uiop);
! 345: #endif
! 346:
! 347: msg_buf = (struct xfs_message_header *)p;
! 348: error = xfs_message_receive (minor(dev),
! 349: msg_buf,
! 350: msg_buf->size,
! 351: pp);
! 352: }
! 353: NNPFSDEB(XDEBDEV, ("xfs_devwrite error = %d\n", error));
! 354: return error;
! 355: }
! 356:
! 357: /*
! 358: * Send a message to user space.
! 359: */
! 360: int
! 361: xfs_message_send(int fd, struct xfs_message_header * message, u_int size)
! 362: {
! 363: struct xfs_channel *chan = &xfs_channel[fd];
! 364: struct {
! 365: struct xfs_link this_message;
! 366: struct xfs_message_header msg;
! 367: } *t;
! 368:
! 369: NNPFSDEB(XDEBMSG, ("xfs_message_send opcode = %d\n", message->opcode));
! 370:
! 371: if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */
! 372: return ENODEV;
! 373:
! 374: /* Prepare message and copy it later */
! 375: message->size = size;
! 376: message->sequence_num = chan->nsequence++;
! 377:
! 378: t = xfs_alloc(sizeof(t->this_message) + size, M_NNPFS);
! 379: t->this_message.error_or_size = sizeof(t->this_message) + size;
! 380: bcopy(message, &t->msg, size);
! 381:
! 382: t->this_message.message = &t->msg;
! 383: xfs_appendq(&chan->messageq, &t->this_message);
! 384: if (chan->status & CHANNEL_WAITING) {
! 385: chan->status &= ~CHANNEL_WAITING;
! 386: wakeup((caddr_t) chan);
! 387: }
! 388: xfs_select_wakeup(chan);
! 389:
! 390: return 0;
! 391: }
! 392:
! 393: #if defined(SWEXIT)
! 394: #define NNPFS_P_EXIT SWEXIT
! 395: #elif defined(P_WEXIT)
! 396: #define NNPFS_P_EXIT P_WEXIT
! 397: #else
! 398: #error what is your exit named ?
! 399: #endif
! 400:
! 401: #if defined(HAVE_STRUCT_PROC_P_SIGMASK) || defined(HAVE_STRUCT_PROC_P_SIGCTX) || defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) || defined(__osf__) || defined(HAVE_FREEBSD_THREAD)
! 402: static void
! 403: xfs_block_sigset (sigset_t *sigset)
! 404: {
! 405:
! 406: #if defined(__sigaddset)
! 407: #define xfs_sig_block(ss,signo) __sigaddset((ss), (signo))
! 408: #elif defined(SIGADDSET)
! 409: #define xfs_sig_block(ss,signo) SIGADDSET(*(ss), (signo))
! 410: #else
! 411: #define xfs_sig_block(ss,signo) *(ss) |= sigmask(signo)
! 412: #endif
! 413:
! 414: xfs_sig_block(sigset, SIGIO);
! 415: xfs_sig_block(sigset, SIGALRM);
! 416: xfs_sig_block(sigset, SIGVTALRM);
! 417: xfs_sig_block(sigset, SIGCHLD);
! 418: #ifdef SIGINFO
! 419: xfs_sig_block(sigset, SIGINFO);
! 420: #endif
! 421: #undef xfs_sig_block
! 422: }
! 423: #endif
! 424:
! 425: /*
! 426: * Send a message to user space and wait for reply.
! 427: */
! 428:
! 429: int
! 430: xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size,
! 431: d_thread_t *proc)
! 432: {
! 433: int ret;
! 434: struct xfs_channel *chan = &xfs_channel[fd];
! 435: struct xfs_link *this_message;
! 436: struct xfs_link *this_process;
! 437: struct xfs_message_header *msg;
! 438: #if defined(HAVE_STRUCT_PROC_P_SIGMASK) || defined(HAVE_STRUCT_PROC_P_SIGCTX) || defined(__osf__) || defined(HAVE_FREEBSD_THREAD)
! 439: sigset_t oldsigmask;
! 440: #endif
! 441: int catch;
! 442:
! 443: NNPFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode));
! 444:
! 445: if (proc == NULL) {
! 446: #ifdef HAVE_FREEBSD_THREAD
! 447: proc = xfs_curthread();
! 448: #else
! 449: proc = xfs_curproc();
! 450: #endif
! 451: }
! 452: if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */
! 453: return ENODEV;
! 454:
! 455: #ifdef HAVE_FREEBSD_THREAD
! 456: if (chan->proc != NULL && chan->proc->td_proc != NULL &&
! 457: proc->td_proc->p_pid == chan->proc->td_proc->p_pid) {
! 458: printf("xfs_message_rpc: deadlock avoided "
! 459: "pid = %u == %u\n", proc->td_proc->p_pid, chan->proc->td_proc->p_pid);
! 460: #else
! 461: if (chan->proc != NULL && proc->p_pid == chan->proc->p_pid) {
! 462: printf("xfs_message_rpc: deadlock avoided "
! 463: "pid = %u == %u\n", proc->p_pid, chan->proc->p_pid);
! 464: #endif
! 465: #if 0
! 466: psignal (proc, SIGABRT);
! 467: #endif
! 468: return EDEADLK;
! 469: }
! 470:
! 471: if (size < sizeof(struct xfs_message_wakeup)) {
! 472: printf("NNPFS PANIC Error: Message to small to receive wakeup, opcode = %d\n", message->opcode);
! 473: return ENOMEM;
! 474: }
! 475: this_message = xfs_alloc(sizeof(struct xfs_link), M_NNPFS_LINK);
! 476: this_process = xfs_alloc(sizeof(struct xfs_link), M_NNPFS_LINK);
! 477: msg = xfs_alloc(size, M_NNPFS_MSG);
! 478: bcopy(message, msg, size);
! 479:
! 480: msg->size = size;
! 481: msg->sequence_num = chan->nsequence++;
! 482: this_message->error_or_size = 0;
! 483: this_message->message = msg;
! 484: this_process->message = msg;
! 485: xfs_appendq(&chan->messageq, this_message);
! 486: xfs_appendq(&chan->sleepq, this_process);
! 487: xfs_select_wakeup(chan);
! 488: this_process->error_or_size = 0;
! 489:
! 490: if (chan->status & CHANNEL_WAITING) {
! 491: chan->status &= ~CHANNEL_WAITING;
! 492: wakeup((caddr_t) chan);
! 493: }
! 494:
! 495: /*
! 496: * Remove signals from the sigmask so no IO will wake us up from
! 497: * tsleep(). We don't want to wake up from since program (emacs,
! 498: * bash & co can't handle them.
! 499: */
! 500:
! 501: #ifdef HAVE_FREEBSD_THREAD
! 502: /* FreeBSD 5.1 */
! 503: oldsigmask = proc->td_sigmask;
! 504: xfs_block_sigset (&proc->td_sigmask);
! 505: #elif HAVE_STRUCT_PROC_P_SIGMASK
! 506: /* NetBSD 1.5, Darwin 1.3, FreeBSD 4.3, 5.0, OpenBSD 2.8 */
! 507: oldsigmask = proc->p_sigmask;
! 508: xfs_block_sigset (&proc->p_sigmask);
! 509: #elif defined(HAVE_STRUCT_PROC_P_SIGCTX)
! 510: /* NetBSD 1.6 */
! 511: oldsigmask = proc->p_sigctx.ps_sigmask;
! 512: xfs_block_sigset (&proc->p_sigctx.ps_sigmask);
! 513: #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
! 514: /* OSF 4.0 */
! 515: oldsigmask = proc->p_sigwaitmask;
! 516: xfs_block_sigset (&proc->p_sigwaitmask);
! 517: #elif defined(__osf__)
! 518: /* OSF 5.0 */
! 519: oldsigmask = u.u_sigmask;
! 520: xfs_block_sigset (&u.u_sigmask);
! 521: #endif
! 522:
! 523: /*
! 524: * if we are exiting we should not try to catch signals, since
! 525: * there might not be enough context left in the process to handle
! 526: * signal delivery, and besides, most BSD-variants ignore all
! 527: * signals while closing anyway.
! 528: */
! 529:
! 530: catch = 0;
! 531: #ifdef HAVE_FREEBSD_THREAD
! 532: if (!(proc->td_proc->p_flag & NNPFS_P_EXIT))
! 533: #else
! 534: if (!(proc->p_flag & NNPFS_P_EXIT))
! 535: #endif
! 536: catch |= PCATCH;
! 537:
! 538: /*
! 539: * We have to check if we have a receiver here too because the
! 540: * daemon could have terminated before we sleep. This seems to
! 541: * happen sometimes when rebooting. */
! 542:
! 543: if (!(chan->status & CHANNEL_OPENED)) {
! 544: NNPFSDEB(XDEBMSG, ("xfs_message_rpc: channel went away\n"));
! 545: this_process->error_or_size = EINTR;
! 546: } else if ((ret = tsleep((caddr_t) this_process,
! 547: (PZERO + 1) | catch, "xfs", 0)) != 0) {
! 548: NNPFSDEB(XDEBMSG, ("caught signal (%d): %ld\n",
! 549: ret, xfs_cursig(proc)));
! 550: this_process->error_or_size = EINTR;
! 551: }
! 552:
! 553: #ifdef HAVE_FREEBSD_THREAD
! 554: proc->td_sigmask = oldsigmask;
! 555: #elif HAVE_STRUCT_PROC_P_SIGMASK
! 556: proc->p_sigmask = oldsigmask;
! 557: #elif defined(HAVE_STRUCT_PROC_P_SIGCTX)
! 558: proc->p_sigctx.ps_sigmask = oldsigmask;
! 559: #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
! 560: proc->p_sigwaitmask = oldsigmask;
! 561: #elif defined(__osf__)
! 562: u.u_sigmask = oldsigmask;
! 563: #endif
! 564:
! 565: /*
! 566: * Caught signal, got reply message or device was closed.
! 567: * Need to clean up both messageq and sleepq.
! 568: */
! 569: if (xfs_onq(this_message)) {
! 570: xfs_outq(this_message);
! 571: }
! 572: if (xfs_onq(this_process)) {
! 573: xfs_outq(this_process);
! 574: }
! 575: ret = this_process->error_or_size;
! 576:
! 577: NNPFSDEB(XDEBMSG, ("xfs_message_rpc this_process->error_or_size = %d\n",
! 578: this_process->error_or_size));
! 579: NNPFSDEB(XDEBMSG, ("xfs_message_rpc opcode ((xfs_message_wakeup*)(this_process->message))->error = %d\n", ((struct xfs_message_wakeup *) (this_process->message))->error));
! 580:
! 581: bcopy(msg, message, size);
! 582:
! 583: xfs_free(this_message, sizeof(*this_message), M_NNPFS_LINK);
! 584: xfs_free(this_process, sizeof(*this_process), M_NNPFS_LINK);
! 585: xfs_free(msg, size, M_NNPFS_MSG);
! 586:
! 587: return ret;
! 588: }
! 589:
! 590: /*
! 591: * For each message type there is a message handler
! 592: * that implements its action, xfs_message_receive
! 593: * invokes the correct function.
! 594: */
! 595: int
! 596: xfs_message_receive(int fd,
! 597: struct xfs_message_header *message,
! 598: u_int size,
! 599: d_thread_t *p)
! 600: {
! 601: NNPFSDEB(XDEBMSG, ("xfs_message_receive opcode = %d\n", message->opcode));
! 602:
! 603: /* Dispatch and coerce message type */
! 604: switch (message->opcode) {
! 605: case NNPFS_MSG_WAKEUP:
! 606: return xfs_message_wakeup(fd,
! 607: (struct xfs_message_wakeup *) message,
! 608: message->size,
! 609: p);
! 610: case NNPFS_MSG_WAKEUP_DATA:
! 611: return xfs_message_wakeup_data(fd,
! 612: (struct xfs_message_wakeup_data *) message,
! 613: message->size,
! 614: p);
! 615: case NNPFS_MSG_INSTALLROOT:
! 616: return xfs_message_installroot(fd,
! 617: (struct xfs_message_installroot *) message,
! 618: message->size,
! 619: p);
! 620: case NNPFS_MSG_INSTALLNODE:
! 621: return xfs_message_installnode(fd,
! 622: (struct xfs_message_installnode *) message,
! 623: message->size,
! 624: p);
! 625: case NNPFS_MSG_INSTALLATTR:
! 626: return xfs_message_installattr(fd,
! 627: (struct xfs_message_installattr *) message,
! 628: message->size,
! 629: p);
! 630: case NNPFS_MSG_INSTALLDATA:
! 631: return xfs_message_installdata(fd,
! 632: (struct xfs_message_installdata *) message,
! 633: message->size,
! 634: p);
! 635: case NNPFS_MSG_INVALIDNODE:
! 636: return xfs_message_invalidnode(fd,
! 637: (struct xfs_message_invalidnode *) message,
! 638: message->size,
! 639: p);
! 640: case NNPFS_MSG_UPDATEFID:
! 641: return xfs_message_updatefid(fd,
! 642: (struct xfs_message_updatefid *)message,
! 643: message->size,
! 644: p);
! 645: case NNPFS_MSG_GC_NODES:
! 646: return xfs_message_gc_nodes(fd,
! 647: (struct xfs_message_gc_nodes *)message,
! 648: message->size,
! 649: p);
! 650: case NNPFS_MSG_VERSION:
! 651: return xfs_message_version(fd,
! 652: (struct xfs_message_version *)message,
! 653: message->size,
! 654: p);
! 655: default:
! 656: printf("NNPFS PANIC Warning xfs_dev: Unknown message opcode == %d\n",
! 657: message->opcode);
! 658: return EINVAL;
! 659: }
! 660: }
! 661:
! 662: int
! 663: xfs_message_wakeup(int fd,
! 664: struct xfs_message_wakeup *message,
! 665: u_int size,
! 666: d_thread_t *p)
! 667: {
! 668: struct xfs_channel *chan = &xfs_channel[fd];
! 669: struct xfs_link *sleepq = &chan->sleepq;
! 670: struct xfs_link *t = chan->sleepq.next; /* Really first in q */
! 671:
! 672: NNPFSDEB(XDEBMSG, ("xfs_message_wakeup error: %d\n", message->error));
! 673:
! 674: for (; t != sleepq; t = t->next)
! 675: if (t->message->sequence_num == message->sleepers_sequence_num) {
! 676: if (t->message->size < size) {
! 677: printf("NNPFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode);
! 678: t->error_or_size = ENOMEM;
! 679: } else
! 680: bcopy(message, t->message, size);
! 681:
! 682: wakeup((caddr_t) t);
! 683: break;
! 684: }
! 685:
! 686: return 0;
! 687: }
! 688:
! 689: int
! 690: xfs_message_wakeup_data(int fd,
! 691: struct xfs_message_wakeup_data * message,
! 692: u_int size,
! 693: d_thread_t *p)
! 694: {
! 695: struct xfs_channel *chan = &xfs_channel[fd];
! 696: struct xfs_link *sleepq = &chan->sleepq;
! 697: struct xfs_link *t = chan->sleepq.next; /* Really first in q */
! 698:
! 699: NNPFSDEB(XDEBMSG, ("xfs_message_wakeup_data error: %d\n", message->error));
! 700:
! 701: for (; t != sleepq; t = t->next)
! 702: if (t->message->sequence_num == message->sleepers_sequence_num) {
! 703: if (t->message->size < size) {
! 704: printf("NNPFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode);
! 705: t->error_or_size = ENOMEM;
! 706: } else
! 707: bcopy(message, t->message, size);
! 708: wakeup((caddr_t) t);
! 709: break;
! 710: }
! 711: return 0;
! 712: }
! 713:
! 714: /*
! 715: *
! 716: */
! 717: int
! 718: xfs_uprintf_device(void)
! 719: {
! 720: #if 0
! 721: int i;
! 722:
! 723: for (i = 0; i < NNNPFS; i++) {
! 724: uprintf("xfs_channel[%d] = {\n", i);
! 725: uprintf("messageq.next = %lx ", xfs_channel[i].messageq.next);
! 726: uprintf("messageq.prev = %lx ", xfs_channel[i].messageq.prev);
! 727: uprintf("sleepq.next = %lx ", xfs_channel[i].sleepq.next);
! 728: uprintf("sleepq.prev = %lx ", xfs_channel[i].sleepq.prev);
! 729: uprintf("nsequence = %d status = %d\n",
! 730: xfs_channel[i].nsequence,
! 731: xfs_channel[i].status);
! 732: uprintf("}\n");
! 733: }
! 734: #endif
! 735: return 0;
! 736: }
CVSweb