--- Net2/nfs/nfs_vnops.c 2018/04/24 18:03:57 1.1.1.1 +++ Net2/nfs/nfs_vnops.c 2018/04/24 18:15:29 1.1.1.4 @@ -33,7 +33,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)nfs_vnops.c 7.60 (Berkeley) 5/24/91 + * from: @(#)nfs_vnops.c 7.60 (Berkeley) 5/24/91 + * nfs_vnops.c,v 1.9 1993/07/13 10:50:06 cgd Exp */ /* @@ -53,7 +54,6 @@ #include "vnode.h" #include "specdev.h" #include "fifo.h" -#include "map.h" #include "../ufs/quota.h" #include "../ufs/inode.h" @@ -67,8 +67,6 @@ #include "nfsm_subs.h" #include "nfsiom.h" -#include "machine/mtpr.h" - /* Defs */ #define TRUE 1 #define FALSE 0 @@ -195,11 +193,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 +257,7 @@ nfs_access(vp, mode, cred, p) found: ; } - if ((vap->va_mode & mode) != 0) + if ((vap->va_mode & mode) == mode) return (0); return (EACCES); } @@ -340,7 +337,8 @@ nfs_dogetattr(vp, vap, cred, tryhard, p) struct mbuf *mreq, *mrep, *md, *mb, *mb2; /* First look in the cache.. */ - if (nfs_getattrcache(vp, vap) == 0) + /* cred == NOCRED when we are called by mountroot */ + if (cred != NOCRED && nfs_getattrcache(vp, vap) == 0) return (0); nfsstats.rpccnt[NFSPROC_GETATTR]++; nfsm_reqhead(nfs_procids[NFSPROC_GETATTR], cred, NFSX_FH); @@ -386,8 +384,13 @@ nfs_setattr(vp, vap, cred, p) else sp->sa_gid = txdr_unsigned(vap->va_gid); sp->sa_size = txdr_unsigned(vap->va_size); + /* jfw@ksr.com 6/2/93 */ +#if 0 /* bad assumption; Suns (at least) make full use of usec field */ sp->sa_atime.tv_sec = txdr_unsigned(vap->va_atime.tv_sec); sp->sa_atime.tv_usec = txdr_unsigned(vap->va_flags); +#else + txdr_time(&vap->va_atime, &sp->sa_atime); +#endif txdr_time(&vap->va_mtime, &sp->sa_mtime); if (vap->va_size != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || vap->va_atime.tv_sec != VNOVAL) { @@ -1586,49 +1589,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 +1612,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; @@ -1760,8 +1715,9 @@ nfs_advlock(vp, id, op, fl, flags) struct flock *fl; int flags; { + register struct nfsnode *np = VTONFS(vp); - return (EOPNOTSUPP); + return (lf_advlock(&(np->n_lockf), np->n_size, id, op, fl, flags)); } /* @@ -1786,3 +1742,168 @@ 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); + /* jfw@ksr.com 6/2/93 */ +#if 0 /* bad assumption; Suns make full (and obvious) use of .usec fields */ + 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); +#else + fxdr_time(&fp->fa_atime, &vap->va_atime); + vap->va_mtime = mtime; + fxdr_time(&fp->fa_ctime, &vap->va_ctime); + vap->va_gen = 0; /* can reliably learn nothing about this via NFS. */ + vap->va_flags = 0; /* can reliably learn nothing about this via NFS. */ +#endif + 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); + } +}