[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.3.2.1

1.1       cgd         1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Rick Macklem at The University of Guelph.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     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:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
1.2       cgd        36:  *     from: @(#)nfs_node.c    7.34 (Berkeley) 5/15/91
1.3.2.1 ! mycroft    37:  *     $Id: nfs_node.c,v 1.3 1993/07/28 02:22:25 cgd Exp $
1.1       cgd        38:  */
                     39:
1.3.2.1 ! mycroft    40: #include <sys/param.h>
        !            41: #include <sys/systm.h>
        !            42: #include <sys/proc.h>
        !            43: #include <sys/mount.h>
        !            44: #include <sys/namei.h>
        !            45: #include <sys/vnode.h>
        !            46: #include <sys/kernel.h>
        !            47: #include <sys/malloc.h>
1.1       cgd        48:
1.3.2.1 ! mycroft    49: #include <nfs/nfsv2.h>
        !            50: #include <nfs/nfs.h>
        !            51: #include <nfs/nfsnode.h>
        !            52: #include <nfs/nfsmount.h>
1.1       cgd        53:
                     54: /* The request list head */
                     55: extern struct nfsreq nfsreqh;
                     56:
                     57: #define        NFSNOHSZ        512
                     58: #if    ((NFSNOHSZ&(NFSNOHSZ-1)) == 0)
                     59: #define        NFSNOHASH(fhsum)        ((fhsum)&(NFSNOHSZ-1))
                     60: #else
                     61: #define        NFSNOHASH(fhsum)        (((unsigned)(fhsum))%NFSNOHSZ)
                     62: #endif
                     63:
                     64: union nhead {
                     65:        union  nhead *nh_head[2];
                     66:        struct nfsnode *nh_chain[2];
                     67: } nhead[NFSNOHSZ];
                     68:
                     69: #define TRUE   1
                     70: #define        FALSE   0
                     71:
                     72: /*
                     73:  * Initialize hash links for nfsnodes
                     74:  * and build nfsnode free list.
                     75:  */
                     76: nfs_nhinit()
                     77: {
                     78:        register int i;
                     79:        register union  nhead *nh = nhead;
                     80:
                     81: #ifndef lint
                     82:        if (VN_MAXPRIVATE < sizeof(struct nfsnode))
                     83:                panic("nfs_nhinit: too small");
                     84: #endif /* not lint */
                     85:        for (i = NFSNOHSZ; --i >= 0; nh++) {
                     86:                nh->nh_head[0] = nh;
                     87:                nh->nh_head[1] = nh;
                     88:        }
                     89: }
                     90:
                     91: /*
                     92:  * Compute an entry in the NFS hash table structure
                     93:  */
                     94: union nhead *
                     95: nfs_hash(fhp)
                     96:        register nfsv2fh_t *fhp;
                     97: {
                     98:        register u_char *fhpp;
                     99:        register u_long fhsum;
                    100:        int i;
                    101:
                    102:        fhpp = &fhp->fh_bytes[0];
                    103:        fhsum = 0;
                    104:        for (i = 0; i < NFSX_FH; i++)
                    105:                fhsum += *fhpp++;
                    106:        return (&nhead[NFSNOHASH(fhsum)]);
                    107: }
                    108:
                    109: /*
                    110:  * Look up a vnode/nfsnode by file handle.
                    111:  * Callers must check for mount points!!
                    112:  * In all cases, a pointer to a
                    113:  * nfsnode structure is returned.
                    114:  */
                    115: nfs_nget(mntp, fhp, npp)
                    116:        struct mount *mntp;
                    117:        register nfsv2fh_t *fhp;
                    118:        struct nfsnode **npp;
                    119: {
                    120:        register struct nfsnode *np;
                    121:        register struct vnode *vp;
                    122:        extern struct vnodeops nfsv2_vnodeops;
                    123:        struct vnode *nvp;
                    124:        union nhead *nh;
                    125:        int error;
                    126:
                    127:        nh = nfs_hash(fhp);
                    128: loop:
                    129:        for (np = nh->nh_chain[0]; np != (struct nfsnode *)nh; np = np->n_forw) {
                    130:                if (mntp != NFSTOV(np)->v_mount ||
                    131:                    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
                    132:                        continue;
                    133:                if ((np->n_flag & NLOCKED) != 0) {
                    134:                        np->n_flag |= NWANT;
                    135:                        (void) tsleep((caddr_t)np, PINOD, "nfsnode", 0);
                    136:                        goto loop;
                    137:                }
                    138:                vp = NFSTOV(np);
                    139:                if (vget(vp))
                    140:                        goto loop;
                    141:                *npp = np;
                    142:                return(0);
                    143:        }
                    144:        if (error = getnewvnode(VT_NFS, mntp, &nfsv2_vnodeops, &nvp)) {
                    145:                *npp = 0;
                    146:                return (error);
                    147:        }
                    148:        vp = nvp;
                    149:        np = VTONFS(vp);
                    150:        np->n_vnode = vp;
                    151:        /*
                    152:         * Insert the nfsnode in the hash queue for its new file handle
                    153:         */
                    154:        np->n_flag = 0;
                    155:        insque(np, nh);
                    156:        nfs_lock(vp);
                    157:        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
                    158:        np->n_attrstamp = 0;
                    159:        np->n_direofoffset = 0;
                    160:        np->n_sillyrename = (struct sillyrename *)0;
                    161:        np->n_size = 0;
                    162:        np->n_mtime = 0;
1.3       cgd       163:        np->n_lockf = 0;
1.1       cgd       164:        *npp = np;
                    165:        return (0);
                    166: }
                    167:
                    168: nfs_inactive(vp, p)
                    169:        struct vnode *vp;
                    170:        struct proc *p;
                    171: {
                    172:        register struct nfsnode *np;
                    173:        register struct sillyrename *sp;
                    174:        struct nfsnode *dnp;
                    175:        extern int prtactive;
                    176:
                    177:        np = VTONFS(vp);
                    178:        if (prtactive && vp->v_usecount != 0)
                    179:                vprint("nfs_inactive: pushing active", vp);
                    180:        nfs_lock(vp);
                    181:        sp = np->n_sillyrename;
                    182:        np->n_sillyrename = (struct sillyrename *)0;
                    183:        if (sp) {
                    184:                /*
                    185:                 * Remove the silly file that was rename'd earlier
                    186:                 */
                    187:                if (!nfs_nget(vp->v_mount, &sp->s_fh, &dnp)) {
                    188:                        sp->s_dvp = NFSTOV(dnp);
                    189:                        nfs_removeit(sp, p);
                    190:                        nfs_nput(sp->s_dvp);
                    191:                }
                    192:                crfree(sp->s_cred);
                    193:                vrele(sp->s_dvp);
                    194:                free((caddr_t)sp, M_NFSREQ);
                    195:        }
                    196:        nfs_unlock(vp);
                    197:        np->n_flag &= NMODIFIED;
                    198: #ifdef notdef
                    199:        /*
                    200:         * Scan the request list for any requests left hanging about
                    201:         */
                    202:        s = splnet();
                    203:        rep = nfsreqh.r_next;
                    204:        while (rep && rep != &nfsreqh) {
                    205:                if (rep->r_vp == vp) {
                    206:                        rep->r_prev->r_next = rep2 = rep->r_next;
                    207:                        rep->r_next->r_prev = rep->r_prev;
                    208:                        m_freem(rep->r_mreq);
                    209:                        if (rep->r_mrep != NULL)
                    210:                                m_freem(rep->r_mrep);
                    211:                        free((caddr_t)rep, M_NFSREQ);
                    212:                        rep = rep2;
                    213:                } else
                    214:                        rep = rep->r_next;
                    215:        }
                    216:        splx(s);
                    217: #endif
                    218:        return (0);
                    219: }
                    220:
                    221: /*
                    222:  * Reclaim an nfsnode so that it can be used for other purposes.
                    223:  */
                    224: nfs_reclaim(vp)
                    225:        register struct vnode *vp;
                    226: {
                    227:        register struct nfsnode *np = VTONFS(vp);
                    228:        extern int prtactive;
                    229:
                    230:        if (prtactive && vp->v_usecount != 0)
                    231:                vprint("nfs_reclaim: pushing active", vp);
                    232:        /*
                    233:         * Remove the nfsnode from its hash chain.
                    234:         */
                    235:        remque(np);
                    236:        np->n_forw = np;
                    237:        np->n_back = np;
                    238:        cache_purge(vp);
                    239:        np->n_flag = 0;
                    240:        np->n_direofoffset = 0;
                    241:        return (0);
                    242: }
                    243:
                    244: /*
                    245:  * In theory, NFS does not need locking, but we make provision
                    246:  * for doing it just in case it is needed.
                    247:  */
                    248: int donfslocking = 0;
                    249: /*
                    250:  * Lock an nfsnode
                    251:  */
                    252:
                    253: nfs_lock(vp)
                    254:        struct vnode *vp;
                    255: {
                    256:        register struct nfsnode *np = VTONFS(vp);
                    257:
                    258:        if (!donfslocking)
                    259:                return;
                    260:        while (np->n_flag & NLOCKED) {
                    261:                np->n_flag |= NWANT;
                    262:                if (np->n_lockholder == curproc->p_pid)
                    263:                        panic("locking against myself");
                    264:                np->n_lockwaiter = curproc->p_pid;
                    265:                (void) tsleep((caddr_t)np, PINOD, "nfslock", 0);
                    266:        }
                    267:        np->n_lockwaiter = 0;
                    268:        np->n_lockholder = curproc->p_pid;
                    269:        np->n_flag |= NLOCKED;
                    270: }
                    271:
                    272: /*
                    273:  * Unlock an nfsnode
                    274:  */
                    275: nfs_unlock(vp)
                    276:        struct vnode *vp;
                    277: {
                    278:        register struct nfsnode *np = VTONFS(vp);
                    279:
                    280:        np->n_lockholder = 0;
                    281:        np->n_flag &= ~NLOCKED;
                    282:        if (np->n_flag & NWANT) {
                    283:                np->n_flag &= ~NWANT;
                    284:                wakeup((caddr_t)np);
                    285:        }
                    286: }
                    287:
                    288: /*
                    289:  * Check for a locked nfsnode
                    290:  */
                    291: nfs_islocked(vp)
                    292:        struct vnode *vp;
                    293: {
                    294:
                    295:        if (VTONFS(vp)->n_flag & NLOCKED)
                    296:                return (1);
                    297:        return (0);
                    298: }
                    299:
                    300: /*
                    301:  * Unlock and vrele()
                    302:  * since I can't decide if dirs. should be locked, I will check for
                    303:  * the lock and be flexible
                    304:  */
                    305: nfs_nput(vp)
                    306:        struct vnode *vp;
                    307: {
                    308:        register struct nfsnode *np = VTONFS(vp);
                    309:
                    310:        if (np->n_flag & NLOCKED)
                    311:                nfs_unlock(vp);
                    312:        vrele(vp);
                    313: }
                    314:
                    315: /*
                    316:  * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
                    317:  * done. Currently nothing to do.
                    318:  */
                    319: /* ARGSUSED */
                    320: nfs_abortop(ndp)
                    321:        struct nameidata *ndp;
                    322: {
                    323:
                    324:        if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
                    325:                FREE(ndp->ni_pnbuf, M_NAMEI);
                    326:        return (0);
                    327: }

CVSweb <webmaster@jp.NetBSD.org>