root/xfs/xfs_message.c

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

DEFINITIONS

This source file includes following definitions.
  1. send_inactive_node
  2. xfs_message_installroot
  3. xfs_message_installnode
  4. xfs_message_installattr
  5. xfs_message_installdata
  6. xfs_message_invalidnode
  7. xfs_message_updatefid
  8. gc_vnode
  9. gc_vnode
  10. xfs_message_gc_nodes
  11. xfs_message_version

    1 /*
    2  * Copyright (c) 1995 - 2002 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 #include <xfs/xfs_locl.h>
   35 #include <xfs/xfs_deb.h>
   36 #include <xfs/xfs_fs.h>
   37 #include <xfs/xfs_message.h>
   38 #include <xfs/xfs_msg_locl.h>
   39 #include <xfs/xfs_syscalls.h>
   40 #include <xfs/xfs_vfsops.h>
   41 #include <xfs/xfs_vnodeops.h>
   42 #include <xfs/xfs_dev.h>
   43 
   44 RCSID("$arla: xfs_message.c,v 1.84 2003/06/02 18:25:20 lha Exp $");
   45 
   46 static void
   47 send_inactive_node(int fd, xfs_handle *handle)
   48 {
   49     struct xfs_message_inactivenode msg;
   50     
   51     msg.header.opcode = NNPFS_MSG_INACTIVENODE;
   52     msg.handle = *handle;
   53     msg.flag   = NNPFS_NOREFS | NNPFS_DELETE;
   54     xfs_message_send(fd, &msg.header, sizeof(msg));
   55 }
   56 
   57 
   58 int
   59 xfs_message_installroot(int fd,
   60                         struct xfs_message_installroot * message,
   61                         u_int size,
   62                         d_thread_t *p)
   63 {
   64     int error = 0;
   65 
   66     NNPFSDEB(XDEBMSG, ("xfs_message_installroot (%d,%d,%d,%d)\n",
   67                      message->node.handle.a,
   68                      message->node.handle.b,
   69                      message->node.handle.c,
   70                      message->node.handle.d));
   71 
   72     if (xfs[fd].root != NULL) {
   73         printf("NNPFS PANIC WARNING! xfs_message_installroot: called again!\n");
   74         error = EBUSY;
   75     } else {
   76         error = new_xfs_node(&xfs[fd], &message->node, &xfs[fd].root, p);
   77         if (error)
   78             return error;
   79         NNPFS_MAKE_VROOT(xfs[fd].root->vn);
   80     }
   81     return error;
   82 }
   83 
   84 int
   85 xfs_message_installnode(int fd,
   86                         struct xfs_message_installnode * message,
   87                         u_int size,
   88                         d_thread_t *p)
   89 {
   90     int error = 0;
   91     struct xfs_node *n, *dp;
   92 
   93     NNPFSDEB(XDEBMSG, ("xfs_message_installnode (%d,%d,%d,%d)\n",
   94                      message->node.handle.a,
   95                      message->node.handle.b,
   96                      message->node.handle.c,
   97                      message->node.handle.d));
   98 
   99 retry:
  100     dp = xfs_node_find(&xfs[fd].nodehead, &message->parent_handle);
  101     if (dp) {
  102         struct vnode *t_vnode = XNODE_TO_VNODE(dp);
  103 
  104         NNPFSDEB(XDEBMSG, ("xfs_message_installnode: t_vnode = %lx\n",
  105                            (unsigned long)t_vnode));
  106 
  107         if (xfs_do_vget(t_vnode, 0 /* LK_SHARED */, p))
  108                 goto retry;
  109 
  110         error = new_xfs_node(&xfs[fd], &message->node, &n, p);
  111         if (error) {
  112             vrele (t_vnode);
  113             return error;
  114         }
  115 
  116         xfs_dnlc_enter_name(t_vnode,
  117                             message->name,
  118                             XNODE_TO_VNODE(n));
  119         vrele (XNODE_TO_VNODE(n));
  120         vrele (t_vnode);
  121     } else {
  122         printf("NNPFS PANIC WARNING! xfs_message_installnode: no parent\n");
  123         error = ENOENT;
  124     }
  125     NNPFSDEB(XDEBMSG, ("return: xfs_message_installnode: %d\n", error));
  126 
  127     return error;
  128 }
  129 
  130 int
  131 xfs_message_installattr(int fd,
  132                         struct xfs_message_installattr * message,
  133                         u_int size,
  134                         d_thread_t *p)
  135 {
  136     int error = 0;
  137     struct xfs_node *t;
  138 
  139     NNPFSDEB(XDEBMSG, ("xfs_message_installattr (%d,%d,%d,%d) \n",
  140                      message->node.handle.a,
  141                      message->node.handle.b,
  142                      message->node.handle.c,
  143                      message->node.handle.d));
  144 
  145     t = xfs_node_find(&xfs[fd].nodehead, &message->node.handle);
  146     if (t != 0) {
  147         t->tokens = message->node.tokens;
  148         if ((t->tokens & NNPFS_DATA_MASK) && DATA_FROM_XNODE(t) == NULL) {
  149             printf ("xfs_message_installattr: tokens and no data\n");
  150             t->tokens &= ~NNPFS_DATA_MASK;
  151         }
  152         xfs_attr2vattr(&message->node.attr, &t->attr, 0);
  153         if ((t->flags & NNPFS_VMOPEN) == 0)
  154             xfs_set_vp_size(XNODE_TO_VNODE(t), t->attr.va_size);
  155         bcopy(message->node.id, t->id, sizeof(t->id));
  156         bcopy(message->node.rights, t->rights, sizeof(t->rights));
  157         t->anonrights = message->node.anonrights;
  158     } else {
  159         NNPFSDEB(XDEBMSG, ("xfs_message_installattr: no such node\n"));
  160     }
  161     
  162     return error;
  163 }
  164 
  165 int
  166 xfs_message_installdata(int fd,
  167                         struct xfs_message_installdata * message,
  168                         u_int size,
  169                         d_thread_t *p)
  170 {
  171     struct xfs_node *t;
  172     int error = 0;
  173 
  174     NNPFSDEB(XDEBMSG, ("xfs_message_installdata (%d,%d,%d,%d)\n",
  175                      message->node.handle.a,
  176                      message->node.handle.b,
  177                      message->node.handle.c,
  178                      message->node.handle.d));
  179 
  180 retry:
  181     t = xfs_node_find(&xfs[fd].nodehead, &message->node.handle);
  182     if (t != NULL) {
  183         struct xfs_fhandle_t *fh = 
  184             (struct xfs_fhandle_t *)&message->cache_handle;
  185         struct vnode *t_vnode = XNODE_TO_VNODE(t);
  186         struct vnode *vp;
  187 
  188         message->cache_name[sizeof(message->cache_name)-1] = '\0';
  189         NNPFSDEB(XDEBMSG, ("cache_name = '%s'\n", message->cache_name));
  190 
  191         if (xfs_do_vget(t_vnode, 0 /* LK_SHARED */, p))
  192                 goto retry;
  193 
  194         if (message->flag & NNPFS_ID_HANDLE_VALID) {
  195             error = xfs_fhlookup (p, fh, &vp);
  196         } else {
  197             error = EINVAL;
  198         }
  199         if (error != 0) {
  200 #ifdef __osf__
  201             struct nameidata *ndp = &u.u_nd;
  202 #else
  203             struct nameidata nd;
  204             struct nameidata *ndp = &nd;
  205 #endif
  206 
  207             NNPFSDEB(XDEBMSG,
  208                    ("xfs_message_installdata: fhlookup failed: %d, "
  209                     "opening by name\n", error));
  210 
  211             NDINIT(ndp, LOOKUP, FOLLOW | NNPFS_LOCKLEAF, UIO_SYSSPACE,
  212                    message->cache_name, p);
  213             error = namei(ndp);
  214             vp = ndp->ni_vp;
  215         }
  216 
  217         if (error == 0) {
  218 #ifndef __osf__
  219             xfs_vfs_unlock(vp, p);
  220 #endif
  221             if (DATA_FROM_XNODE(t))
  222                 vrele(DATA_FROM_XNODE(t));
  223             DATA_FROM_XNODE(t) = vp;
  224 
  225             NNPFSDEB(XDEBMSG, ("xfs_message_installdata: t = %lx;"
  226                              " tokens = %x\n",
  227                              (unsigned long)t, message->node.tokens));
  228 
  229             t->tokens = message->node.tokens;
  230             xfs_attr2vattr(&message->node.attr, &t->attr, 1);
  231             if ((t->flags & NNPFS_VMOPEN) == 0)
  232                 xfs_set_vp_size(XNODE_TO_VNODE(t), t->attr.va_size);
  233             if (XNODE_TO_VNODE(t)->v_type == VDIR
  234                 && (message->flag & NNPFS_ID_INVALID_DNLC))
  235                 xfs_dnlc_purge (XNODE_TO_VNODE(t));
  236             bcopy(message->node.id, t->id, sizeof(t->id));
  237             bcopy(message->node.rights, t->rights, sizeof(t->rights));
  238             t->anonrights = message->node.anonrights;
  239             t->offset = message->offset;
  240 #if 0
  241             if (message->flag & NNPFS_ID_AFSDIR)
  242                 t->flags |= NNPFS_AFSDIR;
  243 #endif
  244         } else {
  245             printf("NNPFS PANIC WARNING! xfs_message_installdata failed!\n");
  246             printf("Reason: lookup failed on cache file '%s', error = %d\n",
  247                    message->cache_name, error);
  248         }
  249         vrele (t_vnode);
  250     } else {
  251         printf("NNPFS PANIC WARNING! xfs_message_installdata failed\n");
  252         printf("Reason: No node to install the data into!\n");
  253         error = ENOENT;
  254     }
  255 
  256     return error;
  257 }
  258 
  259 #ifdef __osf__
  260 #define xfs_writecount v_wrcnt
  261 #else
  262 #define xfs_writecount v_writecount
  263 #endif
  264 
  265 int
  266 xfs_message_invalidnode(int fd,
  267                         struct xfs_message_invalidnode * message,
  268                         u_int size,
  269                         d_thread_t *p)
  270 {
  271     int error = 0;
  272     struct xfs_node *t;
  273 
  274     NNPFSDEB(XDEBMSG, ("xfs_message_invalidnode (%d,%d,%d,%d)\n",
  275                      message->handle.a,
  276                      message->handle.b,
  277                      message->handle.c,
  278                      message->handle.d));
  279 
  280 #ifdef __APPLE__
  281  retry:
  282 #endif
  283     t = xfs_node_find(&xfs[fd].nodehead, &message->handle);
  284     if (t != 0) {
  285         struct vnode *vp = XNODE_TO_VNODE(t);
  286 
  287         /* If open for writing, return immediately. Last close:er wins! */
  288         if (vp->v_usecount >= 0 && vp->xfs_writecount >= 1)
  289             return 0;
  290 
  291 #ifdef __FreeBSD__
  292         {
  293             vm_object_t obj = vp->v_object;
  294 
  295             if (obj != NULL
  296                 && (obj->ref_count != 0
  297 #ifdef OBJ_MIGHTBEDIRTY
  298                 || (obj->flags & OBJ_MIGHTBEDIRTY) != 0
  299 #endif
  300                     ))
  301                 return 0;
  302 
  303         }
  304 #endif /* __FreeBSD__ */
  305 
  306         /* If node is in use, mark as stale */
  307         if (vp->v_usecount > 0 && vp->v_type != VDIR) {
  308 #ifdef __APPLE__
  309             if (vget(vp, 0, p))
  310                 goto retry;
  311 
  312             if (UBCISVALID(vp) && !ubc_isinuse(vp, 1)) {
  313                 ubc_setsize(vp, 0);
  314                 vrele(vp);
  315             } else {
  316                 vrele(vp);
  317                 t->flags |= NNPFS_STALE;
  318                 return 0;
  319             }
  320 #else
  321             t->flags |= NNPFS_STALE;
  322             return 0;
  323 #endif
  324         }
  325 
  326         if (DATA_FROM_XNODE(t)) {
  327             vrele(DATA_FROM_XNODE(t));
  328             DATA_FROM_XNODE(t) = (struct vnode *) 0;
  329         }
  330         NNPFS_TOKEN_CLEAR(t, ~0,
  331                         NNPFS_OPEN_MASK | NNPFS_ATTR_MASK |
  332                         NNPFS_DATA_MASK | NNPFS_LOCK_MASK);
  333         /* Dir changed, must invalidate DNLC. */
  334         if (vp->v_type == VDIR)
  335             xfs_dnlc_purge(vp);
  336         if (vp->v_usecount == 0) {
  337 #ifndef __osf__
  338             NNPFSDEB(XDEBVNOPS, ("xfs_message_invalidnode: vrecycle\n"));
  339             vrecycle(vp, p);
  340 #else
  341             /* XXX */
  342 #endif /* __osf__ */
  343         }
  344     } else {
  345         NNPFSDEB(XDEBMSG, ("xfs_message_invalidnode: no such node\n"));
  346         send_inactive_node(fd, &message->handle);
  347         error = ENOENT;
  348     }
  349 
  350     return error;
  351 }
  352 
  353 int
  354 xfs_message_updatefid(int fd,
  355                       struct xfs_message_updatefid * message,
  356                       u_int size,
  357                       d_thread_t *p)
  358 {
  359     int error = 0;
  360 
  361     NNPFSDEB(XDEBMSG, ("xfs_message_updatefid (%d,%d,%d,%d) (%d,%d,%d,%d)\n",
  362                        message->old_handle.a,
  363                        message->old_handle.b,
  364                        message->old_handle.c,
  365                        message->old_handle.d,
  366                        message->new_handle.a,
  367                        message->new_handle.b,
  368                        message->new_handle.c,
  369                        message->new_handle.d));
  370 
  371     error = xfs_update_handle(&xfs[fd].nodehead, 
  372                                 &message->old_handle,
  373                                 &message->new_handle);
  374     if (error)
  375         printf ("NNPFS PANIC WARNING! xfs_message_updatefid: %d\n", error);
  376     return error;
  377 }
  378 
  379 #if __osf__
  380 
  381 /*
  382  * Try to clean out nodes for the userland daemon
  383  */
  384 
  385 static void
  386 gc_vnode (struct vnode *vp,
  387           d_thread_t *p)
  388 {
  389     /* This node is on the freelist */
  390     if (vp->v_usecount <= 0) {
  391         
  392         /*  DIAGNOSTIC */
  393         if (vp->v_usecount < 0) {
  394                     vprint("vrele: bad ref count", vp);
  395                     panic("vrele: ref cnt");
  396         }
  397         
  398         NNPFSDEB(XDEBMSG, ("xfs_message_gc: success\n"));
  399         
  400         vgone(vp, VX_NOSLEEP, NULL);
  401     } else {
  402         NNPFSDEB(XDEBMSG, ("xfs_message_gc: used\n"));
  403     }
  404 
  405 }
  406 
  407 
  408 #else /* !__osf__ */
  409 
  410 /*
  411  * Try to clean out nodes for the userland daemon
  412  */
  413 
  414 static void
  415 gc_vnode (struct vnode *vp,
  416           d_thread_t *p)
  417 {
  418 #ifdef HAVE_SYS_MUTEX_H
  419     mtx_lock(&vp->v_interlock);
  420 #else
  421     simple_lock(&vp->v_interlock);
  422 #endif
  423     
  424     /* This node is on the freelist */
  425     if (vp->v_usecount <= 0) {
  426 #if __FreeBSD__
  427         vm_object_t obj;
  428 
  429         obj = vp->v_object;
  430 
  431         if (obj != NULL
  432             && (obj->ref_count != 0
  433 #ifdef OBJ_MIGHTBEDIRTY
  434                 || (obj->flags & OBJ_MIGHTBEDIRTY) != 0
  435 #endif
  436                 )) {
  437 #ifdef HAVE_SYS_MUTEX_H
  438             mtx_unlock(&vp->v_interlock);
  439 #else
  440             simple_unlock (&vp->v_interlock);
  441 #endif
  442             return;
  443         }
  444 #endif /* __FreeBSD__ */
  445 
  446 #ifdef DIAGNOSTIC
  447         if (vp->v_usecount < 0 || vp->v_writecount != 0) {
  448                     vprint("vrele: bad ref count", vp);
  449                     panic("vrele: ref cnt");
  450         }
  451 #endif /* DIAGNOSTIC */
  452         
  453         NNPFSDEB(XDEBMSG, ("xfs_message_gc: success\n"));
  454         
  455 #ifdef HAVE_KERNEL_VGONEL
  456         vgonel (vp, p);
  457 #else
  458 #ifdef HAVE_SYS_MUTEX_H
  459         mtx_unlock(&vp->v_interlock);
  460 #else
  461         simple_unlock(&vp->v_interlock); 
  462 #endif
  463         vgone (vp);
  464 #endif
  465 
  466     } else {
  467 #ifdef HAVE_SYS_MUTEX_H
  468         mtx_unlock(&vp->v_interlock);
  469 #else
  470         simple_unlock(&vp->v_interlock);
  471 #endif
  472         NNPFSDEB(XDEBMSG, ("xfs_message_gc: used\n"));
  473     }
  474 
  475 }
  476 
  477 #endif
  478 
  479 int
  480 xfs_message_gc_nodes(int fd,
  481                        struct xfs_message_gc_nodes *message,
  482                        u_int size,
  483                        d_thread_t *p)
  484 {
  485     struct xfs_node *node;
  486     int i;
  487 
  488     NNPFSDEB(XDEBMSG, ("xfs_message_gc\n"));
  489 
  490     for (i = 0; i < message->len; i++) {
  491         node = xfs_node_find (&xfs[fd].nodehead, &message->handle[i]);
  492         if (node)
  493             gc_vnode(XNODE_TO_VNODE(node), p);
  494         else {
  495             NNPFSDEB(XDEBMSG, ("xfs_message_gc_nodes: no such node\n"));
  496             send_inactive_node(fd, &message->handle[i]);
  497         }
  498     }
  499 
  500     return 0;
  501 }
  502 
  503 
  504 /*
  505  * Probe what version of xfs this support
  506  */
  507 
  508 int
  509 xfs_message_version(int fd,
  510                     struct xfs_message_version *message,
  511                     u_int size,
  512                     d_thread_t *p)
  513 {
  514     struct xfs_message_wakeup msg;
  515     int ret;
  516 
  517     ret = NNPFS_VERSION;
  518 
  519     msg.header.opcode = NNPFS_MSG_WAKEUP;
  520     msg.sleepers_sequence_num = message->header.sequence_num;
  521     msg.error = ret;
  522 
  523     return xfs_message_send(fd, 
  524                               (struct xfs_message_header *) &msg, sizeof(msg));
  525 }

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