Annotation of Net2/nfs/nfs_node.c, revision 1.1.1.1

1.1       root        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:  *
                     36:  *     @(#)nfs_node.c  7.34 (Berkeley) 5/15/91
                     37:  */
                     38: 
                     39: #include "param.h"
                     40: #include "systm.h"
                     41: #include "proc.h"
                     42: #include "mount.h"
                     43: #include "namei.h"
                     44: #include "vnode.h"
                     45: #include "kernel.h"
                     46: #include "malloc.h"
                     47: 
                     48: #include "nfsv2.h"
                     49: #include "nfs.h"
                     50: #include "nfsnode.h"
                     51: #include "nfsmount.h"
                     52: 
                     53: /* The request list head */
                     54: extern struct nfsreq nfsreqh;
                     55: 
                     56: #define        NFSNOHSZ        512
                     57: #if    ((NFSNOHSZ&(NFSNOHSZ-1)) == 0)
                     58: #define        NFSNOHASH(fhsum)        ((fhsum)&(NFSNOHSZ-1))
                     59: #else
                     60: #define        NFSNOHASH(fhsum)        (((unsigned)(fhsum))%NFSNOHSZ)
                     61: #endif
                     62: 
                     63: union nhead {
                     64:        union  nhead *nh_head[2];
                     65:        struct nfsnode *nh_chain[2];
                     66: } nhead[NFSNOHSZ];
                     67: 
                     68: #define TRUE   1
                     69: #define        FALSE   0
                     70: 
                     71: /*
                     72:  * Initialize hash links for nfsnodes
                     73:  * and build nfsnode free list.
                     74:  */
                     75: nfs_nhinit()
                     76: {
                     77:        register int i;
                     78:        register union  nhead *nh = nhead;
                     79: 
                     80: #ifndef lint
                     81:        if (VN_MAXPRIVATE < sizeof(struct nfsnode))
                     82:                panic("nfs_nhinit: too small");
                     83: #endif /* not lint */
                     84:        for (i = NFSNOHSZ; --i >= 0; nh++) {
                     85:                nh->nh_head[0] = nh;
                     86:                nh->nh_head[1] = nh;
                     87:        }
                     88: }
                     89: 
                     90: /*
                     91:  * Compute an entry in the NFS hash table structure
                     92:  */
                     93: union nhead *
                     94: nfs_hash(fhp)
                     95:        register nfsv2fh_t *fhp;
                     96: {
                     97:        register u_char *fhpp;
                     98:        register u_long fhsum;
                     99:        int i;
                    100: 
                    101:        fhpp = &fhp->fh_bytes[0];
                    102:        fhsum = 0;
                    103:        for (i = 0; i < NFSX_FH; i++)
                    104:                fhsum += *fhpp++;
                    105:        return (&nhead[NFSNOHASH(fhsum)]);
                    106: }
                    107: 
                    108: /*
                    109:  * Look up a vnode/nfsnode by file handle.
                    110:  * Callers must check for mount points!!
                    111:  * In all cases, a pointer to a
                    112:  * nfsnode structure is returned.
                    113:  */
                    114: nfs_nget(mntp, fhp, npp)
                    115:        struct mount *mntp;
                    116:        register nfsv2fh_t *fhp;
                    117:        struct nfsnode **npp;
                    118: {
                    119:        register struct nfsnode *np;
                    120:        register struct vnode *vp;
                    121:        extern struct vnodeops nfsv2_vnodeops;
                    122:        struct vnode *nvp;
                    123:        union nhead *nh;
                    124:        int error;
                    125: 
                    126:        nh = nfs_hash(fhp);
                    127: loop:
                    128:        for (np = nh->nh_chain[0]; np != (struct nfsnode *)nh; np = np->n_forw) {
                    129:                if (mntp != NFSTOV(np)->v_mount ||
                    130:                    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
                    131:                        continue;
                    132:                if ((np->n_flag & NLOCKED) != 0) {
                    133:                        np->n_flag |= NWANT;
                    134:                        (void) tsleep((caddr_t)np, PINOD, "nfsnode", 0);
                    135:                        goto loop;
                    136:                }
                    137:                vp = NFSTOV(np);
                    138:                if (vget(vp))
                    139:                        goto loop;
                    140:                *npp = np;
                    141:                return(0);
                    142:        }
                    143:        if (error = getnewvnode(VT_NFS, mntp, &nfsv2_vnodeops, &nvp)) {
                    144:                *npp = 0;
                    145:                return (error);
                    146:        }
                    147:        vp = nvp;
                    148:        np = VTONFS(vp);
                    149:        np->n_vnode = vp;
                    150:        /*
                    151:         * Insert the nfsnode in the hash queue for its new file handle
                    152:         */
                    153:        np->n_flag = 0;
                    154:        insque(np, nh);
                    155:        nfs_lock(vp);
                    156:        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
                    157:        np->n_attrstamp = 0;
                    158:        np->n_direofoffset = 0;
                    159:        np->n_sillyrename = (struct sillyrename *)0;
                    160:        np->n_size = 0;
                    161:        np->n_mtime = 0;
                    162:        *npp = np;
                    163:        return (0);
                    164: }
                    165: 
                    166: nfs_inactive(vp, p)
                    167:        struct vnode *vp;
                    168:        struct proc *p;
                    169: {
                    170:        register struct nfsnode *np;
                    171:        register struct sillyrename *sp;
                    172:        struct nfsnode *dnp;
                    173:        extern int prtactive;
                    174: 
                    175:        np = VTONFS(vp);
                    176:        if (prtactive && vp->v_usecount != 0)
                    177:                vprint("nfs_inactive: pushing active", vp);
                    178:        nfs_lock(vp);
                    179:        sp = np->n_sillyrename;
                    180:        np->n_sillyrename = (struct sillyrename *)0;
                    181:        if (sp) {
                    182:                /*
                    183:                 * Remove the silly file that was rename'd earlier
                    184:                 */
                    185:                if (!nfs_nget(vp->v_mount, &sp->s_fh, &dnp)) {
                    186:                        sp->s_dvp = NFSTOV(dnp);
                    187:                        nfs_removeit(sp, p);
                    188:                        nfs_nput(sp->s_dvp);
                    189:                }
                    190:                crfree(sp->s_cred);
                    191:                vrele(sp->s_dvp);
                    192:                free((caddr_t)sp, M_NFSREQ);
                    193:        }
                    194:        nfs_unlock(vp);
                    195:        np->n_flag &= NMODIFIED;
                    196: #ifdef notdef
                    197:        /*
                    198:         * Scan the request list for any requests left hanging about
                    199:         */
                    200:        s = splnet();
                    201:        rep = nfsreqh.r_next;
                    202:        while (rep && rep != &nfsreqh) {
                    203:                if (rep->r_vp == vp) {
                    204:                        rep->r_prev->r_next = rep2 = rep->r_next;
                    205:                        rep->r_next->r_prev = rep->r_prev;
                    206:                        m_freem(rep->r_mreq);
                    207:                        if (rep->r_mrep != NULL)
                    208:                                m_freem(rep->r_mrep);
                    209:                        free((caddr_t)rep, M_NFSREQ);
                    210:                        rep = rep2;
                    211:                } else
                    212:                        rep = rep->r_next;
                    213:        }
                    214:        splx(s);
                    215: #endif
                    216:        return (0);
                    217: }
                    218: 
                    219: /*
                    220:  * Reclaim an nfsnode so that it can be used for other purposes.
                    221:  */
                    222: nfs_reclaim(vp)
                    223:        register struct vnode *vp;
                    224: {
                    225:        register struct nfsnode *np = VTONFS(vp);
                    226:        extern int prtactive;
                    227: 
                    228:        if (prtactive && vp->v_usecount != 0)
                    229:                vprint("nfs_reclaim: pushing active", vp);
                    230:        /*
                    231:         * Remove the nfsnode from its hash chain.
                    232:         */
                    233:        remque(np);
                    234:        np->n_forw = np;
                    235:        np->n_back = np;
                    236:        cache_purge(vp);
                    237:        np->n_flag = 0;
                    238:        np->n_direofoffset = 0;
                    239:        return (0);
                    240: }
                    241: 
                    242: /*
                    243:  * In theory, NFS does not need locking, but we make provision
                    244:  * for doing it just in case it is needed.
                    245:  */
                    246: int donfslocking = 0;
                    247: /*
                    248:  * Lock an nfsnode
                    249:  */
                    250: 
                    251: nfs_lock(vp)
                    252:        struct vnode *vp;
                    253: {
                    254:        register struct nfsnode *np = VTONFS(vp);
                    255: 
                    256:        if (!donfslocking)
                    257:                return;
                    258:        while (np->n_flag & NLOCKED) {
                    259:                np->n_flag |= NWANT;
                    260:                if (np->n_lockholder == curproc->p_pid)
                    261:                        panic("locking against myself");
                    262:                np->n_lockwaiter = curproc->p_pid;
                    263:                (void) tsleep((caddr_t)np, PINOD, "nfslock", 0);
                    264:        }
                    265:        np->n_lockwaiter = 0;
                    266:        np->n_lockholder = curproc->p_pid;
                    267:        np->n_flag |= NLOCKED;
                    268: }
                    269: 
                    270: /*
                    271:  * Unlock an nfsnode
                    272:  */
                    273: nfs_unlock(vp)
                    274:        struct vnode *vp;
                    275: {
                    276:        register struct nfsnode *np = VTONFS(vp);
                    277: 
                    278:        np->n_lockholder = 0;
                    279:        np->n_flag &= ~NLOCKED;
                    280:        if (np->n_flag & NWANT) {
                    281:                np->n_flag &= ~NWANT;
                    282:                wakeup((caddr_t)np);
                    283:        }
                    284: }
                    285: 
                    286: /*
                    287:  * Check for a locked nfsnode
                    288:  */
                    289: nfs_islocked(vp)
                    290:        struct vnode *vp;
                    291: {
                    292: 
                    293:        if (VTONFS(vp)->n_flag & NLOCKED)
                    294:                return (1);
                    295:        return (0);
                    296: }
                    297: 
                    298: /*
                    299:  * Unlock and vrele()
                    300:  * since I can't decide if dirs. should be locked, I will check for
                    301:  * the lock and be flexible
                    302:  */
                    303: nfs_nput(vp)
                    304:        struct vnode *vp;
                    305: {
                    306:        register struct nfsnode *np = VTONFS(vp);
                    307: 
                    308:        if (np->n_flag & NLOCKED)
                    309:                nfs_unlock(vp);
                    310:        vrele(vp);
                    311: }
                    312: 
                    313: /*
                    314:  * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
                    315:  * done. Currently nothing to do.
                    316:  */
                    317: /* ARGSUSED */
                    318: nfs_abortop(ndp)
                    319:        struct nameidata *ndp;
                    320: {
                    321: 
                    322:        if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
                    323:                FREE(ndp->ni_pnbuf, M_NAMEI);
                    324:        return (0);
                    325: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.