[BACK]Return to nfs_node.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / nfs

Annotation of src/sys/nfs/nfs_node.c, Revision 1.29.2.4

1.29.2.4! bouyer      1: /*     $NetBSD: nfs_node.c,v 1.29.2.3 2000/12/08 09:19:21 bouyer Exp $ */
1.12      cgd         2:
1.1       cgd         3: /*
1.9       mycroft     4:  * Copyright (c) 1989, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Rick Macklem at The University of Guelph.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the University of
                     21:  *     California, Berkeley and its contributors.
                     22:  * 4. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  *
1.16      fvdl       38:  *     @(#)nfs_node.c  8.6 (Berkeley) 5/22/95
1.1       cgd        39:  */
                     40:
1.29.2.1  bouyer     41: #include "opt_nfs.h"
1.16      fvdl       42:
1.4       mycroft    43: #include <sys/param.h>
                     44: #include <sys/systm.h>
                     45: #include <sys/proc.h>
                     46: #include <sys/mount.h>
                     47: #include <sys/namei.h>
                     48: #include <sys/vnode.h>
                     49: #include <sys/kernel.h>
                     50: #include <sys/malloc.h>
1.28      thorpej    51: #include <sys/pool.h>
1.22      fvdl       52: #include <sys/lock.h>
1.1       cgd        53:
1.9       mycroft    54: #include <nfs/rpcv2.h>
1.16      fvdl       55: #include <nfs/nfsproto.h>
1.4       mycroft    56: #include <nfs/nfs.h>
                     57: #include <nfs/nfsnode.h>
                     58: #include <nfs/nfsmount.h>
1.9       mycroft    59: #include <nfs/nqnfs.h>
1.15      christos   60: #include <nfs/nfs_var.h>
1.1       cgd        61:
1.13      mycroft    62: LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl;
                     63: u_long nfsnodehash;
1.22      fvdl       64: struct lock nfs_hashlock;
1.1       cgd        65:
1.28      thorpej    66: struct pool nfs_node_pool;             /* memory pool for nfs nodes */
                     67: struct pool nfs_vattr_pool;            /* memory pool for nfs vattrs */
                     68:
1.29.2.4! bouyer     69: extern int prtactive;
        !            70:
1.1       cgd        71: #define TRUE   1
                     72: #define        FALSE   0
                     73:
                     74: /*
                     75:  * Initialize hash links for nfsnodes
                     76:  * and build nfsnode free list.
                     77:  */
1.15      christos   78: void
1.1       cgd        79: nfs_nhinit()
                     80: {
                     81:
1.29.2.2  bouyer     82:        nfsnodehashtbl = hashinit(desiredvnodes, HASH_LIST, M_NFSNODE,
                     83:            M_WAITOK, &nfsnodehash);
1.22      fvdl       84:        lockinit(&nfs_hashlock, PINOD, "nfs_hashlock", 0, 0);
1.28      thorpej    85:
                     86:        pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl",
                     87:            0, pool_page_alloc_nointr, pool_page_free_nointr, M_NFSNODE);
                     88:        pool_init(&nfs_vattr_pool, sizeof(struct vattr), 0, 0, 0, "nfsvapl",
                     89:            0, pool_page_alloc_nointr, pool_page_free_nointr, M_NFSNODE);
1.1       cgd        90: }
                     91:
                     92: /*
1.29.2.1  bouyer     93:  * Free resources previoslu allocated in nfs_nhinit().
                     94:  */
                     95: void
                     96: nfs_nhdone()
                     97: {
                     98:        hashdone(nfsnodehashtbl, M_NFSNODE);
                     99:        pool_destroy(&nfs_node_pool);
                    100:        pool_destroy(&nfs_vattr_pool);
                    101: }
                    102:
                    103: /*
1.1       cgd       104:  * Compute an entry in the NFS hash table structure
                    105:  */
1.16      fvdl      106: u_long
                    107: nfs_hash(fhp, fhsize)
1.29.2.1  bouyer    108:        nfsfh_t *fhp;
1.16      fvdl      109:        int fhsize;
1.1       cgd       110: {
1.29.2.1  bouyer    111:        u_char *fhpp;
                    112:        u_long fhsum;
                    113:        int i;
1.1       cgd       114:
                    115:        fhpp = &fhp->fh_bytes[0];
                    116:        fhsum = 0;
1.16      fvdl      117:        for (i = 0; i < fhsize; i++)
1.1       cgd       118:                fhsum += *fhpp++;
1.16      fvdl      119:        return (fhsum);
1.1       cgd       120: }
                    121:
                    122: /*
                    123:  * Look up a vnode/nfsnode by file handle.
                    124:  * Callers must check for mount points!!
                    125:  * In all cases, a pointer to a
                    126:  * nfsnode structure is returned.
                    127:  */
1.15      christos  128: int
1.16      fvdl      129: nfs_nget(mntp, fhp, fhsize, npp)
1.1       cgd       130:        struct mount *mntp;
1.29.2.1  bouyer    131:        nfsfh_t *fhp;
1.16      fvdl      132:        int fhsize;
1.1       cgd       133:        struct nfsnode **npp;
                    134: {
1.29.2.1  bouyer    135:        struct nfsnode *np;
1.13      mycroft   136:        struct nfsnodehashhead *nhpp;
1.29.2.1  bouyer    137:        struct vnode *vp;
1.1       cgd       138:        struct vnode *nvp;
                    139:        int error;
                    140:
1.16      fvdl      141:        nhpp = NFSNOHASH(nfs_hash(fhp, fhsize));
1.1       cgd       142: loop:
1.13      mycroft   143:        for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
1.16      fvdl      144:                if (mntp != NFSTOV(np)->v_mount || np->n_fhsize != fhsize ||
1.29.2.3  bouyer    145:                    memcmp(fhp, np->n_fhp, fhsize))
1.1       cgd       146:                        continue;
                    147:                vp = NFSTOV(np);
1.26      fvdl      148:                if (vget(vp, LK_EXCLUSIVE))
1.1       cgd       149:                        goto loop;
                    150:                *npp = np;
                    151:                return(0);
                    152:        }
1.26      fvdl      153:        if (lockmgr(&nfs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0))
1.22      fvdl      154:                goto loop;
1.15      christos  155:        error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp);
                    156:        if (error) {
1.1       cgd       157:                *npp = 0;
1.26      fvdl      158:                lockmgr(&nfs_hashlock, LK_RELEASE, 0);
1.1       cgd       159:                return (error);
                    160:        }
                    161:        vp = nvp;
1.28      thorpej   162:        np = pool_get(&nfs_node_pool, PR_WAITOK);
1.29.2.3  bouyer    163:        memset(np, 0, sizeof *np);
1.29.2.1  bouyer    164:        lockinit(&np->n_commitlock, PINOD, "nfsclock", 0, 0);
1.9       mycroft   165:        vp->v_data = np;
1.1       cgd       166:        np->n_vnode = vp;
1.29.2.3  bouyer    167:
1.1       cgd       168:        /*
                    169:         * Insert the nfsnode in the hash queue for its new file handle
                    170:         */
1.13      mycroft   171:        LIST_INSERT_HEAD(nhpp, np, n_hash);
1.16      fvdl      172:        if (fhsize > NFS_SMALLFH) {
1.29.2.1  bouyer    173:                np->n_fhp = malloc(fhsize, M_NFSBIGFH, M_WAITOK);
1.16      fvdl      174:        } else
                    175:                np->n_fhp = &np->n_fh;
1.29.2.3  bouyer    176:        memcpy(np->n_fhp, fhp, fhsize);
1.16      fvdl      177:        np->n_fhsize = fhsize;
1.29.2.1  bouyer    178:        np->n_accstamp = -1;
1.28      thorpej   179:        np->n_vattr = pool_get(&nfs_vattr_pool, PR_WAITOK);
1.29.2.3  bouyer    180:
1.29.2.4! bouyer    181:        lockmgr(&vp->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
        !           182:
1.29.2.3  bouyer    183:        /*
                    184:         * XXXUBC doing this while holding the nfs_hashlock is bad,
                    185:         * but there's no alternative at the moment.
                    186:         */
                    187:        error = VOP_GETATTR(vp, np->n_vattr, curproc->p_ucred, curproc);
                    188:        if (error) {
                    189:                return error;
                    190:        }
                    191:        uvm_vnp_setsize(vp, np->n_vattr->va_size);
                    192:
1.26      fvdl      193:        lockmgr(&nfs_hashlock, LK_RELEASE, 0);
1.1       cgd       194:        *npp = np;
                    195:        return (0);
                    196: }
                    197:
1.15      christos  198: int
                    199: nfs_inactive(v)
                    200:        void *v;
                    201: {
1.9       mycroft   202:        struct vop_inactive_args /* {
                    203:                struct vnode *a_vp;
1.16      fvdl      204:                struct proc *a_p;
1.15      christos  205:        } */ *ap = v;
1.29.2.1  bouyer    206:        struct nfsnode *np;
                    207:        struct sillyrename *sp;
1.26      fvdl      208:        struct proc *p = ap->a_p;
1.29.2.4! bouyer    209:        struct vnode *vp = ap->a_vp;
1.1       cgd       210:
1.29.2.4! bouyer    211:        np = VTONFS(vp);
        !           212:        if (prtactive && vp->v_usecount != 0)
        !           213:                vprint("nfs_inactive: pushing active", vp);
        !           214:        if (vp->v_type != VDIR) {
1.16      fvdl      215:                sp = np->n_sillyrename;
1.18      fvdl      216:                np->n_sillyrename = (struct sillyrename *)0;
                    217:        } else
1.16      fvdl      218:                sp = (struct sillyrename *)0;
1.1       cgd       219:        if (sp) {
1.29.2.4! bouyer    220:                nfs_vinvalbuf(vp, 0, sp->s_cred, p, 1);
1.19      fvdl      221:
                    222:                /*
1.1       cgd       223:                 * Remove the silly file that was rename'd earlier
                    224:                 */
1.29.2.4! bouyer    225:
        !           226:                vn_lock(sp->s_dvp, LK_EXCLUSIVE | LK_RETRY);
1.9       mycroft   227:                nfs_removeit(sp);
1.1       cgd       228:                crfree(sp->s_cred);
1.29.2.4! bouyer    229:                vput(sp->s_dvp);
1.29.2.3  bouyer    230:                FREE(sp, M_NFSREQ);
1.1       cgd       231:        }
1.9       mycroft   232:        np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NQNFSEVICTED |
                    233:                NQNFSNONCACHE | NQNFSWRITE);
1.29.2.4! bouyer    234:        VOP_UNLOCK(vp, 0);
1.1       cgd       235:        return (0);
                    236: }
                    237:
                    238: /*
                    239:  * Reclaim an nfsnode so that it can be used for other purposes.
                    240:  */
1.15      christos  241: int
                    242: nfs_reclaim(v)
                    243:        void *v;
                    244: {
1.9       mycroft   245:        struct vop_reclaim_args /* {
                    246:                struct vnode *a_vp;
1.15      christos  247:        } */ *ap = v;
1.29.2.1  bouyer    248:        struct vnode *vp = ap->a_vp;
                    249:        struct nfsnode *np = VTONFS(vp);
                    250:        struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1.1       cgd       251:
                    252:        if (prtactive && vp->v_usecount != 0)
                    253:                vprint("nfs_reclaim: pushing active", vp);
1.16      fvdl      254:
1.13      mycroft   255:        LIST_REMOVE(np, n_hash);
1.9       mycroft   256:
                    257:        /*
                    258:         * For nqnfs, take it off the timer queue as required.
                    259:         */
1.13      mycroft   260:        if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_timer.cqe_next != 0) {
                    261:                CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer);
1.9       mycroft   262:        }
1.16      fvdl      263:
                    264:        /*
                    265:         * Free up any directory cookie structures and
                    266:         * large file handle structures that might be associated with
                    267:         * this nfs node.
                    268:         */
1.23      fvdl      269:        if (vp->v_type == VDIR && np->n_dircache) {
1.24      fvdl      270:                nfs_invaldircache(vp, 1);
1.23      fvdl      271:                FREE(np->n_dircache, M_NFSDIROFF);
1.16      fvdl      272:        }
                    273:        if (np->n_fhsize > NFS_SMALLFH) {
1.29.2.3  bouyer    274:                free(np->n_fhp, M_NFSBIGFH);
1.16      fvdl      275:        }
                    276:
1.28      thorpej   277:        pool_put(&nfs_vattr_pool, np->n_vattr);
1.29.2.3  bouyer    278:        if (np->n_rcred) {
                    279:                crfree(np->n_rcred);
                    280:        }
                    281:        if (np->n_wcred) {
                    282:                crfree(np->n_wcred);
                    283:        }
1.1       cgd       284:        cache_purge(vp);
1.28      thorpej   285:        pool_put(&nfs_node_pool, vp->v_data);
1.29.2.3  bouyer    286:        vp->v_data = NULL;
1.1       cgd       287:        return (0);
                    288: }

CVSweb <webmaster@jp.NetBSD.org>