[BACK]Return to xfs_dev-common.c CVS log [TXT][DIR] Up to [local] / sys / xfs

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