Annotation of sys/nfs/nfs_node.c, Revision 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