root/nfs/nfs_node.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfs_nhinit
  2. nfs_nget
  3. nfs_inactive
  4. nfs_reclaim

    1 /*      $OpenBSD: nfs_node.c,v 1.35 2007/06/01 23:47:57 deraadt Exp $   */
    2 /*      $NetBSD: nfs_node.c,v 1.16 1996/02/18 11:53:42 fvdl Exp $       */
    3 
    4 /*
    5  * Copyright (c) 1989, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * This code is derived from software contributed to Berkeley by
    9  * Rick Macklem at The University of Guelph.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  *      @(#)nfs_node.c  8.6 (Berkeley) 5/22/95
   36  */
   37 
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/proc.h>
   42 #include <sys/mount.h>
   43 #include <sys/namei.h>
   44 #include <sys/vnode.h>
   45 #include <sys/kernel.h>
   46 #include <sys/malloc.h>
   47 #include <sys/pool.h>
   48 #include <sys/hash.h>
   49 #include <sys/rwlock.h>
   50 
   51 #include <nfs/rpcv2.h>
   52 #include <nfs/nfsproto.h>
   53 #include <nfs/nfs.h>
   54 #include <nfs/nfsnode.h>
   55 #include <nfs/nfsmount.h>
   56 #include <nfs/nfs_var.h>
   57 
   58 LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl;
   59 u_long nfsnodehash;
   60 struct rwlock nfs_hashlock = RWLOCK_INITIALIZER("nfshshlk");
   61 
   62 struct pool nfs_node_pool;
   63 
   64 extern int prtactive;
   65 
   66 #define TRUE    1
   67 #define FALSE   0
   68 
   69 #define nfs_hash(x,y)   hash32_buf((x), (y), HASHINIT)
   70 
   71 /*
   72  * Initialize hash links for nfsnodes
   73  * and build nfsnode free list.
   74  */
   75 void
   76 nfs_nhinit()
   77 {
   78         nfsnodehashtbl = hashinit(desiredvnodes, M_NFSNODE, M_WAITOK, &nfsnodehash);
   79         pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl",
   80             &pool_allocator_nointr);
   81 }
   82 
   83 /*
   84  * Look up a vnode/nfsnode by file handle.
   85  * Callers must check for mount points!!
   86  * In all cases, a pointer to a
   87  * nfsnode structure is returned.
   88  */
   89 int
   90 nfs_nget(mntp, fhp, fhsize, npp)
   91         struct mount *mntp;
   92         nfsfh_t *fhp;
   93         int fhsize;
   94         struct nfsnode **npp;
   95 {
   96         struct proc *p = curproc;       /* XXX */
   97         struct nfsnode *np;
   98         struct nfsnodehashhead *nhpp;
   99         struct vnode *vp;
  100         extern int (**nfsv2_vnodeop_p)(void *);
  101         struct vnode *nvp;
  102         int error;
  103 
  104         nhpp = NFSNOHASH(nfs_hash(fhp, fhsize));
  105 loop:
  106         for (np = LIST_FIRST(nhpp); np != NULL; np = LIST_NEXT(np, n_hash)) {
  107                 if (mntp != NFSTOV(np)->v_mount || np->n_fhsize != fhsize ||
  108                     bcmp((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize))
  109                         continue;
  110                 vp = NFSTOV(np);
  111                 if (vget(vp, LK_EXCLUSIVE, p))
  112                         goto loop;
  113                 *npp = np;
  114                 return(0);
  115         }
  116         if (rw_enter(&nfs_hashlock, RW_WRITE|RW_SLEEPFAIL))
  117                 goto loop;
  118         error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp);
  119         if (error) {
  120                 *npp = 0;
  121                 rw_exit(&nfs_hashlock);
  122                 return (error);
  123         }
  124         vp = nvp;
  125         np = pool_get(&nfs_node_pool, PR_WAITOK);
  126         bzero((caddr_t)np, sizeof *np);
  127         vp->v_data = np;
  128         np->n_vnode = vp;
  129 
  130         rw_init(&np->n_commitlock, "nfs_commitlk");
  131 
  132         /* 
  133          * Are we getting the root? If so, make sure the vnode flags
  134          * are correct 
  135          */
  136         {
  137                 struct nfsmount *nmp = VFSTONFS(mntp);
  138                 if ((fhsize == nmp->nm_fhsize) &&
  139                     !bcmp(fhp, nmp->nm_fh, fhsize)) {
  140                         if (vp->v_type == VNON)
  141                                 vp->v_type = VDIR;
  142                         vp->v_flag |= VROOT;
  143                 }
  144         }
  145         
  146         LIST_INSERT_HEAD(nhpp, np, n_hash);
  147         if (fhsize > NFS_SMALLFH) {
  148                 np->n_fhp = malloc(fhsize, M_NFSBIGFH, M_WAITOK);
  149         } else
  150                 np->n_fhp = &np->n_fh;
  151         bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
  152         np->n_fhsize = fhsize;
  153         rw_exit(&nfs_hashlock);
  154         *npp = np;
  155         return (0);
  156 }
  157 
  158 int
  159 nfs_inactive(v)
  160         void *v;
  161 {
  162         struct vop_inactive_args *ap = v;
  163         struct nfsnode *np;
  164         struct sillyrename *sp;
  165         struct proc *p = curproc;       /* XXX */
  166 
  167         np = VTONFS(ap->a_vp);
  168 
  169 #ifdef DIAGNOSTIC
  170         if (prtactive && ap->a_vp->v_usecount != 0)
  171                 vprint("nfs_inactive: pushing active", ap->a_vp);
  172 #endif
  173 
  174         if (ap->a_vp->v_type != VDIR) {
  175                 sp = np->n_sillyrename;
  176                 np->n_sillyrename = (struct sillyrename *)0;
  177         } else
  178                 sp = (struct sillyrename *)0;
  179         if (sp) {
  180                 /*
  181                  * Remove the silly file that was rename'd earlier
  182                  */
  183                 (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, p, 1);
  184                 nfs_removeit(sp);
  185                 crfree(sp->s_cred);
  186                 vrele(sp->s_dvp);
  187                 FREE((caddr_t)sp, M_NFSREQ);
  188         }
  189         np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT);
  190 
  191         VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
  192         return (0);
  193 }
  194 
  195 /*
  196  * Reclaim an nfsnode so that it can be used for other purposes.
  197  */
  198 int
  199 nfs_reclaim(v)
  200         void *v;
  201 {
  202         struct vop_reclaim_args *ap = v;
  203         struct vnode *vp = ap->a_vp;
  204         struct nfsnode *np = VTONFS(vp);
  205         struct nfsdmap *dp, *dp2;
  206 
  207 #ifdef DIAGNOSTIC
  208         if (prtactive && vp->v_usecount != 0)
  209                 vprint("nfs_reclaim: pushing active", vp);
  210 #endif
  211 
  212         if (np->n_hash.le_prev != NULL)
  213                 LIST_REMOVE(np, n_hash);
  214 
  215         /*
  216          * Free up any directory cookie structures and
  217          * large file handle structures that might be associated with
  218          * this nfs node.
  219          */
  220         if (vp->v_type == VDIR) {
  221                 dp = LIST_FIRST(&np->n_cookies);
  222                 while (dp) {
  223                         dp2 = dp;
  224                         dp = LIST_NEXT(dp, ndm_list);
  225                         FREE((caddr_t)dp2, M_NFSDIROFF);
  226                 }
  227         }
  228         if (np->n_fhsize > NFS_SMALLFH) {
  229                 free(np->n_fhp, M_NFSBIGFH);
  230         }
  231 
  232         if (np->n_rcred)
  233                 crfree(np->n_rcred);
  234         if (np->n_wcred)
  235                 crfree(np->n_wcred);    
  236         cache_purge(vp);
  237         pool_put(&nfs_node_pool, vp->v_data);
  238         vp->v_data = NULL;
  239         return (0);
  240 }
  241 

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