Annotation of 43BSDReno/sys/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 is only permitted until one year after the first shipment
                      9:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                     10:  * binary forms are permitted provided that: (1) source distributions retain
                     11:  * this entire copyright notice and comment, and (2) distributions including
                     12:  * binaries display the following acknowledgement:  This product includes
                     13:  * software developed by the University of California, Berkeley and its
                     14:  * contributors'' in the documentation or other materials provided with the
                     15:  * distribution and in all advertising materials mentioning features or use
                     16:  * of this software.  Neither the name of the University nor the names of
                     17:  * its contributors may be used to endorse or promote products derived from
                     18:  * this software without specific prior written permission.
                     19:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     20:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     21:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     22:  *
                     23:  *     @(#)nfs_node.c  7.29 (Berkeley) 6/28/90
                     24:  */
                     25: 
                     26: #include "param.h"
                     27: #include "systm.h"
                     28: #include "user.h"
                     29: #include "proc.h"
                     30: #include "mount.h"
                     31: #include "vnode.h"
                     32: #include "errno.h"
                     33: #include "nfsv2.h"
                     34: #include "nfs.h"
                     35: #include "nfsnode.h"
                     36: #include "nfsmount.h"
                     37: #include "kernel.h"
                     38: #include "malloc.h"
                     39: 
                     40: /* The request list head */
                     41: extern struct nfsreq nfsreqh;
                     42: 
                     43: #define        NFSNOHSZ        512
                     44: #if    ((NFSNOHSZ&(NFSNOHSZ-1)) == 0)
                     45: #define        NFSNOHASH(fhsum)        ((fhsum)&(NFSNOHSZ-1))
                     46: #else
                     47: #define        NFSNOHASH(fhsum)        (((unsigned)(fhsum))%NFSNOHSZ)
                     48: #endif
                     49: 
                     50: union nhead {
                     51:        union  nhead *nh_head[2];
                     52:        struct nfsnode *nh_chain[2];
                     53: } nhead[NFSNOHSZ];
                     54: 
                     55: #define TRUE   1
                     56: #define        FALSE   0
                     57: 
                     58: /*
                     59:  * Initialize hash links for nfsnodes
                     60:  * and build nfsnode free list.
                     61:  */
                     62: nfs_nhinit()
                     63: {
                     64:        register int i;
                     65:        register union  nhead *nh = nhead;
                     66: 
                     67: #ifndef lint
                     68:        if (VN_MAXPRIVATE < sizeof(struct nfsnode))
                     69:                panic("nfs_nhinit: too small");
                     70: #endif /* not lint */
                     71:        for (i = NFSNOHSZ; --i >= 0; nh++) {
                     72:                nh->nh_head[0] = nh;
                     73:                nh->nh_head[1] = nh;
                     74:        }
                     75: }
                     76: 
                     77: /*
                     78:  * Compute an entry in the NFS hash table structure
                     79:  */
                     80: union nhead *
                     81: nfs_hash(fhp)
                     82:        register nfsv2fh_t *fhp;
                     83: {
                     84:        register u_char *fhpp;
                     85:        register u_long fhsum;
                     86:        int i;
                     87: 
                     88:        fhpp = &fhp->fh_bytes[0];
                     89:        fhsum = 0;
                     90:        for (i = 0; i < NFSX_FH; i++)
                     91:                fhsum += *fhpp++;
                     92:        return (&nhead[NFSNOHASH(fhsum)]);
                     93: }
                     94: 
                     95: /*
                     96:  * Look up a vnode/nfsnode by file handle.
                     97:  * Callers must check for mount points!!
                     98:  * In all cases, a pointer to a
                     99:  * nfsnode structure is returned.
                    100:  */
                    101: nfs_nget(mntp, fhp, npp)
                    102:        struct mount *mntp;
                    103:        register nfsv2fh_t *fhp;
                    104:        struct nfsnode **npp;
                    105: {
                    106:        register struct nfsnode *np;
                    107:        register struct vnode *vp;
                    108:        extern struct vnodeops nfsv2_vnodeops;
                    109:        struct vnode *nvp;
                    110:        union nhead *nh;
                    111:        int error;
                    112: 
                    113:        nh = nfs_hash(fhp);
                    114: loop:
                    115:        for (np = nh->nh_chain[0]; np != (struct nfsnode *)nh; np = np->n_forw) {
                    116:                if (mntp != NFSTOV(np)->v_mount ||
                    117:                    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
                    118:                        continue;
                    119:                if ((np->n_flag & NLOCKED) != 0) {
                    120:                        np->n_flag |= NWANT;
                    121:                        (void) tsleep((caddr_t)np, PINOD, "nfsnode", 0);
                    122:                        goto loop;
                    123:                }
                    124:                vp = NFSTOV(np);
                    125:                if (vget(vp))
                    126:                        goto loop;
                    127:                *npp = np;
                    128:                return(0);
                    129:        }
                    130:        if (error = getnewvnode(VT_NFS, mntp, &nfsv2_vnodeops, &nvp)) {
                    131:                *npp = 0;
                    132:                return (error);
                    133:        }
                    134:        vp = nvp;
                    135:        np = VTONFS(vp);
                    136:        np->n_vnode = vp;
                    137:        /*
                    138:         * Insert the nfsnode in the hash queue for its new file handle
                    139:         */
                    140:        np->n_flag = 0;
                    141:        insque(np, nh);
                    142:        nfs_lock(vp);
                    143:        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
                    144:        np->n_attrstamp = 0;
                    145:        np->n_direofoffset = 0;
                    146:        np->n_sillyrename = (struct sillyrename *)0;
                    147:        np->n_size = 0;
                    148:        np->n_mtime = 0;
                    149:        *npp = np;
                    150:        return (0);
                    151: }
                    152: 
                    153: nfs_inactive(vp)
                    154:        struct vnode *vp;
                    155: {
                    156:        register struct nfsnode *np;
                    157:        register struct nameidata *ndp;
                    158:        register struct sillyrename *sp;
                    159:        struct nfsnode *dnp;
                    160:        extern int prtactive;
                    161: 
                    162:        np = VTONFS(vp);
                    163:        if (prtactive && vp->v_usecount != 0)
                    164:                vprint("nfs_inactive: pushing active", vp);
                    165:        nfs_lock(vp);
                    166:        sp = np->n_sillyrename;
                    167:        np->n_sillyrename = (struct sillyrename *)0;
                    168:        if (sp) {
                    169:                /*
                    170:                 * Remove the silly file that was rename'd earlier
                    171:                 */
                    172:                ndp = &sp->s_namei;
                    173:                if (!nfs_nget(vp->v_mount, &sp->s_fh, &dnp)) {
                    174:                        ndp->ni_dvp = NFSTOV(dnp);
                    175:                        nfs_removeit(ndp);
                    176:                        nfs_nput(ndp->ni_dvp);
                    177:                }
                    178:                crfree(ndp->ni_cred);
                    179:                free((caddr_t)sp, M_TEMP);
                    180:        }
                    181:        nfs_unlock(vp);
                    182:        np->n_flag &= NMODIFIED;
                    183: #ifdef notdef
                    184:        /*
                    185:         * Scan the request list for any requests left hanging about
                    186:         */
                    187:        s = splnet();
                    188:        rep = nfsreqh.r_next;
                    189:        while (rep && rep != &nfsreqh) {
                    190:                if (rep->r_vp == vp) {
                    191:                        rep->r_prev->r_next = rep2 = rep->r_next;
                    192:                        rep->r_next->r_prev = rep->r_prev;
                    193:                        m_freem(rep->r_mreq);
                    194:                        if (rep->r_mrep != NULL)
                    195:                                m_freem(rep->r_mrep);
                    196:                        free((caddr_t)rep, M_NFSREQ);
                    197:                        rep = rep2;
                    198:                } else
                    199:                        rep = rep->r_next;
                    200:        }
                    201:        splx(s);
                    202: #endif
                    203:        return (0);
                    204: }
                    205: 
                    206: /*
                    207:  * Reclaim an nfsnode so that it can be used for other purposes.
                    208:  */
                    209: nfs_reclaim(vp)
                    210:        register struct vnode *vp;
                    211: {
                    212:        register struct nfsnode *np = VTONFS(vp);
                    213:        extern int prtactive;
                    214: 
                    215:        if (prtactive && vp->v_usecount != 0)
                    216:                vprint("nfs_reclaim: pushing active", vp);
                    217:        /*
                    218:         * Remove the nfsnode from its hash chain.
                    219:         */
                    220:        remque(np);
                    221:        np->n_forw = np;
                    222:        np->n_back = np;
                    223:        cache_purge(vp);
                    224:        np->n_flag = 0;
                    225:        np->n_direofoffset = 0;
                    226:        return (0);
                    227: }
                    228: 
                    229: /*
                    230:  * Lock an nfsnode
                    231:  */
                    232: nfs_lock(vp)
                    233:        struct vnode *vp;
                    234: {
                    235:        register struct nfsnode *np = VTONFS(vp);
                    236: 
                    237:        while (np->n_flag & NLOCKED) {
                    238:                np->n_flag |= NWANT;
                    239:                if (np->n_lockholder == u.u_procp->p_pid)
                    240:                        panic("locking against myself");
                    241:                np->n_lockwaiter = u.u_procp->p_pid;
                    242:                (void) tsleep((caddr_t)np, PINOD, "nfslock", 0);
                    243:        }
                    244:        np->n_lockwaiter = 0;
                    245:        np->n_lockholder = u.u_procp->p_pid;
                    246:        u.u_spare[0]++;
                    247:        np->n_flag |= NLOCKED;
                    248: }
                    249: 
                    250: /*
                    251:  * Unlock an nfsnode
                    252:  */
                    253: nfs_unlock(vp)
                    254:        struct vnode *vp;
                    255: {
                    256:        register struct nfsnode *np = VTONFS(vp);
                    257: 
                    258:        if ((np->n_flag & NLOCKED) == 0)
                    259:                vprint("nfs_unlock: unlocked nfsnode", vp);
                    260:        np->n_lockholder = 0;
                    261:        u.u_spare[0]--;
                    262:        np->n_flag &= ~NLOCKED;
                    263:        if (np->n_flag & NWANT) {
                    264:                np->n_flag &= ~NWANT;
                    265:                wakeup((caddr_t)np);
                    266:        }
                    267: }
                    268: 
                    269: /*
                    270:  * Check for a locked nfsnode
                    271:  */
                    272: nfs_islocked(vp)
                    273:        struct vnode *vp;
                    274: {
                    275: 
                    276:        if (VTONFS(vp)->n_flag & NLOCKED)
                    277:                return (1);
                    278:        return (0);
                    279: }
                    280: 
                    281: /*
                    282:  * Unlock and vrele()
                    283:  * since I can't decide if dirs. should be locked, I will check for
                    284:  * the lock and be flexible
                    285:  */
                    286: nfs_nput(vp)
                    287:        struct vnode *vp;
                    288: {
                    289:        register struct nfsnode *np = VTONFS(vp);
                    290: 
                    291:        if (np->n_flag & NLOCKED)
                    292:                nfs_unlock(vp);
                    293:        vrele(vp);
                    294: }
                    295: 
                    296: /*
                    297:  * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
                    298:  * done. Currently nothing to do.
                    299:  */
                    300: /* ARGSUSED */
                    301: nfs_abortop(ndp)
                    302:        struct nameidata *ndp;
                    303: {
                    304: 
                    305:        return (0);
                    306: }

unix.superglobalmegacorp.com

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