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>