[BACK]Return to nfs_node.c CVS log [TXT][DIR] Up to [local] / sys / nfs

Annotation of sys/nfs/nfs_node.c, Revision 1.1.1.1

1.1       nbrk        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:

CVSweb