Date: Mon, 1 Oct 2001 15:27:28 -0700 (PDT) From: Wencheng Chai <wchai@prismedia.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/30971: NFS client modification time resolution is not high enough, which may cause client side cache inconsistent Message-ID: <200110012227.f91MRSJ44207@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 30971
>Category: kern
>Synopsis: NFS client modification time resolution is not high enough, which may cause client side cache inconsistent
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Mon Oct 01 15:30:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Wencheng Chai
>Release: 4.1 release
>Organization:
PRISMedia Networks Inc.
>Environment:
>Description:
The NFS client side stores the value of va_mtime only in total number
of seconds(va_mtime.tv_sec), even the server sends the mtime in term of
seconds and nanoseconds.
>How-To-Repeat:
Two NFS clients mounted from the same exported FS,
Type "touch file1" and "touch file2" from different
clients simultaneously, then type "ls -l" from the
first client, the output of "ls" only shows file1.
>Fix:
*** /usr/src/sys/nfs/nfs_bio.c Tue Aug 21 12:39:09 2001
--- nfs_bio.c Wed Sep 12 03:45:03 2001
***************
*** 394,410 ****
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
} else {
error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
! if (np->n_mtime != vattr.va_mtime.tv_sec) {
if (vp->v_type == VDIR)
nfs_invaldir(vp);
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
}
}
}
--- 394,415 ----
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv_nsec;
} else {
error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
! if ((np->n_vattr.va_mtime.tv_sec != vattr.va_mtime.tv_se
c)||((np->n_vattr.va_mtime.tv_sec == vattr.va_mtime.tv_sec)&&(np->n_vattr.va_mti
me.tv_nsec != vattr.va_mtime.tv_nsec))) {
if (vp->v_type == VDIR)
nfs_invaldir(vp);
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_
sec;
+ np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv
_nsec;
+
}
}
}
======================================================================
*** /usr/src/sys/nfs/nfs_subs.c Sat Feb 12 19:32:06 2000
--- nfs_subs.c Wed Sep 12 03:46:13 2001
***************
*** 1285,1290 ****
--- 1285,1292 ----
addaliasu(vp, rdev);
}
np->n_mtime = mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_sec = mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_nsec = mtime.tv_nsec;
}
vap = &np->n_vattr;
vap->va_type = vtyp;
***************
*** 1303,1308 ****
--- 1305,1311 ----
fp->fa3_fileid.nfsuquad[1]);
fxdr_nfsv3time(&fp->fa3_atime, &vap->va_atime);
fxdr_nfsv3time(&fp->fa3_ctime, &vap->va_ctime);
+ fxdr_nfsv3time(&fp->fa3_mtime, &vap->va_mtime);
vap->va_flags = 0;
vap->va_filerev = 0;
} else {
***************
*** 1315,1320 ****
--- 1318,1324 ----
* NFS_FABLKSIZE;
vap->va_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid);
fxdr_nfsv2time(&fp->fa2_atime, &vap->va_atime);
+ fxdr_nfsv2time(&fp->fa2_mtime, &vap->va_mtime);
vap->va_flags = 0;
vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t,
fp->fa2_ctime.nfsv2_sec);
======================================================================
*** /usr/src/sys/nfs/nfs_vnops.c Tue Aug 21 12:39:09 2001
--- nfs_vnops.c Wed Sep 12 03:48:46 2001
***************
*** 507,523 ****
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
} else {
error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p);
if (error)
return (error);
! if (np->n_mtime != vattr.va_mtime.tv_sec) {
if (vp->v_type == VDIR)
np->n_direofoffset = 0;
if ((error = nfs_vinvalbuf(vp, V_SAVE,
ap->a_cred, ap->a_p, 1)) == EINTR)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
}
}
}
--- 507,528 ----
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv_nsec;
} else {
error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p);
if (error)
return (error);
! if ((np->n_vattr.va_mtime.tv_sec != vattr.va_mtime.tv_se
c)||((np->n_vattr.va_mtime.tv_sec == vattr.va_mtime.tv_sec)&&(np->n_vattr.va_mti
me.tv_nsec != vattr.va_mtime.tv_nsec))) {
!
if (vp->v_type == VDIR)
np->n_direofoffset = 0;
if ((error = nfs_vinvalbuf(vp, V_SAVE,
ap->a_cred, ap->a_p, 1)) == EINTR)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
+ np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_
sec;
+ np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv
_nsec;
}
}
}
***************
*** 1260,1266 ****
}
} else
nfsm_loadattr(vp, (struct vattr *)0);
! if (wccflag)
VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec;
m_freem(mrep);
if (error)
--- 1265,1271 ----
}
} else
nfsm_loadattr(vp, (struct vattr *)0);
! if (wccflag)
VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec;
m_freem(mrep);
if (error)
***************
*** 2064,2071 ****
nfsstats.direofcache_hits++;
return (0);
}
! } else if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp) =
= 0 &&
! np->n_mtime == vattr.va_mtime.tv_sec) {
nfsstats.direofcache_hits++;
return (0);
}
--- 2069,2075 ----
nfsstats.direofcache_hits++;
return (0);
}
! } else if ((VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp)
== 0) &&((np->n_vattr.va_mtime.tv_sec != vattr.va_mtime.tv_sec)||((np->n_vattr.v
a_mtime.tv_sec == vattr.va_mtime.tv_sec)&&(np->n_vattr.va_mtime.tv_nsec != vattr
.va_mtime.tv_nsec)))) {
nfsstats.direofcache_hits++;
return (0);
}
======================================================================
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110012227.f91MRSJ44207>
