--- Net2/nfs/nfs_vnops.c 2018/04/24 18:03:57 1.1.1.1 +++ Net2/nfs/nfs_vnops.c 2018/04/24 18:09:42 1.1.1.3 @@ -34,6 +34,14 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 7.60 (Berkeley) 5/24/91 + * + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00090 + * -------------------- ----- ---------------------- + * + * 02 Mar 93 Greg Hackney Make NFS client POSIX compliant (anon) + * */ /* @@ -53,7 +61,6 @@ #include "vnode.h" #include "specdev.h" #include "fifo.h" -#include "map.h" #include "../ufs/quota.h" #include "../ufs/inode.h" @@ -67,8 +74,6 @@ #include "nfsm_subs.h" #include "nfsiom.h" -#include "machine/mtpr.h" - /* Defs */ #define TRUE 1 #define FALSE 0 @@ -195,11 +200,10 @@ struct vnodeops fifo_nfsv2nodeops = { extern u_long nfs_procids[NFS_NPROCS]; extern u_long nfs_prog, nfs_vers; extern char nfsiobuf[MAXPHYS+NBPG]; -struct map nfsmap[NFS_MSIZ]; struct buf nfs_bqueue; /* Queue head for nfsiod's */ struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; +enum vtype ntov_type[7] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON }; int nfs_numasync = 0; -static int nfsmap_want = 0; /* * nfs null call from vfs. @@ -260,7 +264,7 @@ nfs_access(vp, mode, cred, p) found: ; } - if ((vap->va_mode & mode) != 0) + if ((vap->va_mode & mode) == mode) return (0); return (EACCES); } @@ -1586,49 +1590,8 @@ nfs_doio(bp) if (bp->b_flags & B_DIRTY) uiop->uio_procp = pageproc; cr = crcopy(uiop->uio_procp->p_ucred); -#if defined(hp300) || defined(i386) /* mapping was already done by vmapbuf */ io.iov_base = bp->b_un.b_addr; -#else - o = (int)bp->b_un.b_addr & PGOFSET; - npf2 = npf = btoc(bp->b_bcount + o); - - /* - * Get some mapping page table entries - */ - while ((reg = rmalloc(nfsmap, (long)npf)) == 0) { - nfsmap_want++; - (void) tsleep((caddr_t)&nfsmap_want, PZERO-1, "nfsmap", - 0); - } - reg--; - if (bp->b_flags & B_PAGET) - pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; - else { - v = btop(bp->b_un.b_addr); - if (bp->b_flags & B_UAREA) - pte = &uiop->uio_procp->p_addr[v]; - else - pte = vtopte(uiop->uio_procp, v); - } - - /* - * Play vmaccess() but with the Nfsiomap page table - */ - ppte = &Nfsiomap[reg]; - vbase = vaddr = &nfsiobuf[reg*NBPG]; - while (npf != 0) { - mapin(ppte, (u_int)vaddr, pte->pg_pfnum, (int)(PG_V|PG_KW)); -#if defined(tahoe) - mtpr(P1DC, vaddr); -#endif - ppte++; - pte++; - vaddr += NBPG; - --npf; - } - io.iov_base = vbase+o; -#endif /* !defined(hp300) */ /* * And do the i/o rpc @@ -1650,13 +1613,6 @@ nfs_doio(bp) * Finally, release pte's used by physical i/o */ crfree(cr); -#if !defined(hp300) && !defined(i386) - rmfree(nfsmap, (long)npf2, (long)++reg); - if (nfsmap_want) { - nfsmap_want = 0; - wakeup((caddr_t)&nfsmap_want); - } -#endif } else { if (bp->b_flags & B_READ) { io.iov_len = uiop->uio_resid = bp->b_bcount; @@ -1786,3 +1742,159 @@ nfs_print(vp) printf(" waiting pid %d", np->n_lockwaiter); printf("\n"); } + + +/* + * Attribute cache routines. + * nfs_loadattrcache() - loads or updates the cache contents from attributes + * that are on the mbuf list + * nfs_getattrcache() - returns valid attributes if found in cache, returns + * error otherwise + */ + +/* + * Load the attribute cache (that lives in the nfsnode entry) with + * the values on the mbuf list and + * Iff vap not NULL + * copy the attributes to *vaper + */ +nfs_loadattrcache(vpp, mdp, dposp, vaper) + struct vnode **vpp; + struct mbuf **mdp; + caddr_t *dposp; + struct vattr *vaper; +{ + register struct vnode *vp = *vpp; + register struct vattr *vap; + register struct nfsv2_fattr *fp; + extern struct vnodeops spec_nfsv2nodeops; + register struct nfsnode *np; + register long t1; + caddr_t dpos, cp2; + int error = 0; + struct mbuf *md; + enum vtype type; + u_short mode; + long rdev; + struct timeval mtime; + struct vnode *nvp; + + md = *mdp; + dpos = *dposp; + t1 = (mtod(md, caddr_t)+md->m_len)-dpos; + if (error = nfsm_disct(&md, &dpos, NFSX_FATTR, t1, TRUE, &cp2)) + return (error); + fp = (struct nfsv2_fattr *)cp2; + type = nfstov_type(fp->fa_type); + mode = fxdr_unsigned(u_short, fp->fa_mode); + if (type == VNON) + type = IFTOVT(mode); + rdev = fxdr_unsigned(long, fp->fa_rdev); + fxdr_time(&fp->fa_mtime, &mtime); + /* + * If v_type == VNON it is a new node, so fill in the v_type, + * n_mtime fields. Check to see if it represents a special + * device, and if so, check for a possible alias. Once the + * correct vnode has been obtained, fill in the rest of the + * information. + */ + np = VTONFS(vp); + if (vp->v_type == VNON) { + if (type == VCHR && rdev == 0xffffffff) + vp->v_type = type = VFIFO; + else + vp->v_type = type; + if (vp->v_type == VFIFO) { +#ifdef FIFO + extern struct vnodeops fifo_nfsv2nodeops; + vp->v_op = &fifo_nfsv2nodeops; +#else + return (EOPNOTSUPP); +#endif /* FIFO */ + } + if (vp->v_type == VCHR || vp->v_type == VBLK) { + vp->v_op = &spec_nfsv2nodeops; + if (nvp = checkalias(vp, (dev_t)rdev, vp->v_mount)) { + /* + * Reinitialize aliased node. + */ + np = VTONFS(nvp); + np->n_vnode = nvp; + np->n_flag = 0; + nfs_lock(nvp); + bcopy((caddr_t)&VTONFS(vp)->n_fh, + (caddr_t)&np->n_fh, NFSX_FH); + insque(np, nfs_hash(&np->n_fh)); + np->n_attrstamp = 0; + np->n_sillyrename = (struct sillyrename *)0; + /* + * Discard unneeded vnode and update actual one + */ + vput(vp); + *vpp = nvp; + } + } + np->n_mtime = mtime.tv_sec; + } + vap = &np->n_vattr; + vap->va_type = type; + vap->va_mode = (mode & 07777); + vap->va_nlink = fxdr_unsigned(u_short, fp->fa_nlink); + vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid); + vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid); + vap->va_size = fxdr_unsigned(u_long, fp->fa_size); + if ((np->n_flag & NMODIFIED) == 0 || vap->va_size > np->n_size) { + np->n_size = vap->va_size; + vnode_pager_setsize(vp, np->n_size); + } + vap->va_size_rsv = 0; + vap->va_blocksize = fxdr_unsigned(long, fp->fa_blocksize); + vap->va_rdev = (dev_t)rdev; + vap->va_bytes = fxdr_unsigned(long, fp->fa_blocks) * NFS_FABLKSIZE; + vap->va_bytes_rsv = 0; + vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; + vap->va_fileid = fxdr_unsigned(long, fp->fa_fileid); + vap->va_atime.tv_sec = fxdr_unsigned(long, fp->fa_atime.tv_sec); + vap->va_atime.tv_usec = 0; + vap->va_flags = fxdr_unsigned(u_long, fp->fa_atime.tv_usec); + vap->va_mtime = mtime; + vap->va_ctime.tv_sec = fxdr_unsigned(long, fp->fa_ctime.tv_sec); + vap->va_ctime.tv_usec = 0; + vap->va_gen = fxdr_unsigned(u_long, fp->fa_ctime.tv_usec); + np->n_attrstamp = time.tv_sec; + *dposp = dpos; + *mdp = md; + if (vaper != NULL) { + bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap)); + if ((np->n_flag & NMODIFIED) && (np->n_size > vap->va_size)) + vaper->va_size = np->n_size; + } + return (0); +} + +/* + * Check the time stamp + * If the cache is valid, copy contents to *vap and return 0 + * otherwise return an error + */ +nfs_getattrcache(vp, vap) + register struct vnode *vp; + struct vattr *vap; +{ + register struct nfsnode *np; + + np = VTONFS(vp); + if ((time.tv_sec-np->n_attrstamp) < NFS_ATTRTIMEO) { + nfsstats.attrcache_hits++; + bcopy((caddr_t)&np->n_vattr,(caddr_t)vap,sizeof(struct vattr)); + if ((np->n_flag & NMODIFIED) == 0) { + np->n_size = vap->va_size; + vnode_pager_setsize(vp, np->n_size); + } else if (np->n_size > vap->va_size) + vap->va_size = np->n_size; + return (0); + } else { + nfsstats.attrcache_misses++; + return (ENOENT); + } +}