diff options
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_subs.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 21 | ||||
-rw-r--r-- | sys/nfsclient/nfsnode.h | 4 |
4 files changed, 24 insertions, 17 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 9fd12a1..bc2cf53 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -396,19 +396,19 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) error = VOP_GETATTR(vp, &vattr, cred, td); if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; + np->n_mtime = vattr.va_mtime; } else { error = VOP_GETATTR(vp, &vattr, cred, td); if (error) return (error); if ((np->n_flag & NSIZECHANGED) - || (np->n_mtime != vattr.va_mtime.tv_sec)) { + || (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime))) { if (vp->v_type == VDIR) (nmp->nm_rpcops->nr_invaldir)(vp); error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; + np->n_mtime = vattr.va_mtime; np->n_flag &= ~NSIZECHANGED; } } @@ -1318,7 +1318,7 @@ nfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td) } /* ASSERT_VOP_LOCKED(vp, "nfs_doio"); */ if (p && (vp->v_vflag & VV_TEXT) && - (np->n_mtime != np->n_vattr.va_mtime.tv_sec)) { + (NFS_TIMESPEC_COMPARE(&np->n_mtime, &np->n_vattr.va_mtime))) { PROC_LOCK(p); killproc(p, "text file modification"); PROC_UNLOCK(p); diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index b91adae..8668a99 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -534,7 +534,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, vp->v_type = vtyp; if (vp->v_type == VFIFO) vp->v_op = &nfs_fifoops; - np->n_mtime = mtime.tv_sec; + np->n_mtime = mtime; } vap = &np->n_vattr; vap->va_type = vtyp; @@ -639,7 +639,7 @@ nfs_getattrcache(struct vnode *vp, struct vattr *vaper) vap = &np->n_vattr; nmp = VFSTONFS(vp->v_mount); /* XXX n_mtime doesn't seem to be updated on a miss-and-reload */ - timeo = (time_second - np->n_mtime) / 10; + timeo = (time_second - np->n_mtime.tv_sec) / 10; #ifdef NFS_ACDEBUG if (nfs_acdebug>1) @@ -941,8 +941,8 @@ nfsm_wcc_data_xx(struct vnode **v, int *f, struct mbuf **md, caddr_t *dpos) if (tl == NULL) return EBADRPC; if (*f) - ttretf = (VTONFS(*v)->n_mtime == - fxdr_unsigned(u_int32_t, *(tl + 2))); + ttretf = (VTONFS(*v)->n_mtime.tv_sec == fxdr_unsigned(u_int32_t, *(tl + 2)) && + VTONFS(*v)->n_mtime.tv_nsec == fxdr_unsigned(u_int32_t, *(tl + 3))); } t1 = nfsm_postop_attr_xx(v, &ttattrf, md, dpos); if (t1) diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index b9fd2a6..a4dbe18 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -417,22 +417,22 @@ nfs_open(struct vop_open_args *ap) error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; + np->n_mtime = vattr.va_mtime; } else { + np->n_attrstamp = 0; error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); if (error) return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { + if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { if (vp->v_type == VDIR) np->n_direofoffset = 0; error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_td, 1); if (error == EINTR || error == EIO) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; + np->n_mtime = vattr.va_mtime; } } - np->n_attrstamp = 0; /* For Open/Close consistency */ return (0); } @@ -484,7 +484,6 @@ nfs_close(struct vop_close_args *ap) vm_object_page_clean(vp->v_object, 0, 0, 0); VM_OBJECT_UNLOCK(vp->v_object); } - if (np->n_flag & NMODIFIED) { if (NFS_ISV3(vp)) { /* @@ -506,8 +505,14 @@ nfs_close(struct vop_close_args *ap) } else { error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_td, 1); } - np->n_attrstamp = 0; } + /* + * Invalidate the attribute cache in all cases. + * An open is going to fetch fresh attrs any way, other procs + * on this node that have file open will be forced to do an + * otw attr fetch, but this is safe. + */ + np->n_attrstamp = 0; if (np->n_flag & NWRITEERR) { np->n_flag &= ~NWRITEERR; error = np->n_error; @@ -1153,7 +1158,7 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, } else nfsm_loadattr(vp, NULL); if (wccflag) - VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec; + VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime; m_freem(mrep); if (error) break; @@ -1912,7 +1917,7 @@ nfs_readdir(struct vop_readdir_args *ap) if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && (np->n_flag & NMODIFIED) == 0) { if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_td) == 0 && - np->n_mtime == vattr.va_mtime.tv_sec) { + !NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { nfsstats.direofcache_hits++; return (0); } diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 21bb0d1..4a4d835 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -97,7 +97,7 @@ struct nfsnode { u_int32_t n_mode; /* ACCESS mode cache */ uid_t n_modeuid; /* credentials having mode */ time_t n_modestamp; /* mode cache timestamp */ - time_t n_mtime; /* Prev modify time. */ + struct timespec n_mtime; /* Prev modify time. */ time_t n_ctime; /* Prev create time. */ time_t n_expiry; /* Lease expiry time */ nfsfh_t *n_fhp; /* NFS File Handle */ @@ -155,6 +155,8 @@ struct nfsnode { #define VTONFS(vp) ((struct nfsnode *)(vp)->v_data) #define NFSTOV(np) ((struct vnode *)(np)->n_vnode) +#define NFS_TIMESPEC_COMPARE(T1, T2) (((T1)->tv_sec != (T2)->tv_sec) || ((T1)->tv_nsec != (T2)->tv_nsec)) + /* * Queue head for nfsiod's */ |