root/xfs/xfs_dev-common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xfs_initq
  2. xfs_emptyq
  3. xfs_onq
  4. xfs_appendq
  5. xfs_outq
  6. xfs_devopen_common
  7. xfs_devclose_common
  8. xfs_cursig
  9. xfs_devread
  10. xfs_devwrite
  11. xfs_message_send
  12. xfs_block_sigset
  13. xfs_message_rpc
  14. xfs_message_receive
  15. xfs_message_wakeup
  16. xfs_message_wakeup_data
  17. xfs_uprintf_device

    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 }

/* [<][>][^][v][top][bottom][index][help] */