From owner-svn-src-all@FreeBSD.ORG Tue Sep 7 14:29:45 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 86E5D10656C0; Tue, 7 Sep 2010 14:29:45 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6BDBE8FC21; Tue, 7 Sep 2010 14:29:45 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o87ETjVa002404; Tue, 7 Sep 2010 14:29:45 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o87ETjLq002398; Tue, 7 Sep 2010 14:29:45 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201009071429.o87ETjLq002398@svn.freebsd.org> From: John Baldwin Date: Tue, 7 Sep 2010 14:29:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212293 - in head/sys: fs/nfsclient nfsclient X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Sep 2010 14:29:45 -0000 Author: jhb Date: Tue Sep 7 14:29:45 2010 New Revision: 212293 URL: http://svn.freebsd.org/changeset/base/212293 Log: Store the full timestamp when caching timestamps of files and directories for purposes of validating name cache entries. This closes races where two updates to a file or directory within the same second could result in stale entries in the name cache. While here, remove the 'n_expiry' field as it is no longer used. Reviewed by: rmacklem MFC after: 1 week Modified: head/sys/fs/nfsclient/nfs_clrpcops.c head/sys/fs/nfsclient/nfs_clvnops.c head/sys/fs/nfsclient/nfsnode.h head/sys/nfsclient/nfs_vnops.c head/sys/nfsclient/nfsnode.h Modified: head/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clrpcops.c Tue Sep 7 13:50:02 2010 (r212292) +++ head/sys/fs/nfsclient/nfs_clrpcops.c Tue Sep 7 14:29:45 2010 (r212293) @@ -3293,8 +3293,7 @@ nfsrpc_readdirplus(vnode_t vp, struct ui ndp->ni_vp = newvp; NFSCNHASH(cnp, HASHINIT); if (cnp->cn_namelen <= NCHNAMLEN) { - np->n_ctime = - np->n_vattr.na_ctime.tv_sec; + np->n_ctime = np->n_vattr.na_ctime; cache_enter(ndp->ni_dvp,ndp->ni_vp,cnp); } if (unlocknewvp) Modified: head/sys/fs/nfsclient/nfs_clvnops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clvnops.c Tue Sep 7 13:50:02 2010 (r212292) +++ head/sys/fs/nfsclient/nfs_clvnops.c Tue Sep 7 14:29:45 2010 (r212293) @@ -988,7 +988,7 @@ nfs_lookup(struct vop_lookup_args *ap) struct nfsfh *nfhp; struct nfsvattr dnfsva, nfsva; struct vattr vattr; - time_t dmtime; + struct timespec dmtime; *vpp = NULLVP; if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) && @@ -1038,7 +1038,7 @@ nfs_lookup(struct vop_lookup_args *ap) } if (nfscl_nodeleg(newvp, 0) == 0 || (VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 && - vattr.va_ctime.tv_sec == newnp->n_ctime)) { + timespeccmp(&vattr.va_ctime, &newnp->n_ctime, ==))) { NFSINCRGLOBAL(newnfsstats.lookupcache_hits); if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) @@ -1065,13 +1065,13 @@ nfs_lookup(struct vop_lookup_args *ap) if ((u_int)(ticks - np->n_dmtime_ticks) < (nmp->nm_negnametimeo * hz) && VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && - vattr.va_mtime.tv_sec == np->n_dmtime) { + timespeccmp(&vattr.va_mtime, &np->n_dmtime, ==)) { NFSINCRGLOBAL(newnfsstats.lookupcache_hits); return (ENOENT); } cache_purge_negative(dvp); mtx_lock(&np->n_mtx); - np->n_dmtime = 0; + timespecclear(&np->n_dmtime); mtx_unlock(&np->n_mtx); } @@ -1086,7 +1086,7 @@ nfs_lookup(struct vop_lookup_args *ap) * the lookup RPC has been performed on the server but before * n_dmtime is set at the end of this function. */ - dmtime = np->n_vattr.na_mtime.tv_sec; + dmtime = np->n_vattr.na_mtime; error = 0; newvp = NULLVP; NFSINCRGLOBAL(newnfsstats.lookupcache_misses); @@ -1139,8 +1139,8 @@ nfs_lookup(struct vop_lookup_args *ap) * lookup. */ mtx_lock(&np->n_mtx); - if (np->n_dmtime <= dmtime) { - if (np->n_dmtime == 0) { + if (timespeccmp(&np->n_dmtime, &dmtime, <=)) { + if (!timespecisset(&np->n_dmtime)) { np->n_dmtime = dmtime; np->n_dmtime_ticks = ticks; } @@ -1241,7 +1241,7 @@ nfs_lookup(struct vop_lookup_args *ap) cnp->cn_flags |= SAVENAME; if ((cnp->cn_flags & MAKEENTRY) && (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) { - np->n_ctime = np->n_vattr.na_vattr.va_ctime.tv_sec; + np->n_ctime = np->n_vattr.na_vattr.va_ctime; cache_enter(dvp, newvp, cnp); } *vpp = newvp; Modified: head/sys/fs/nfsclient/nfsnode.h ============================================================================== --- head/sys/fs/nfsclient/nfsnode.h Tue Sep 7 13:50:02 2010 (r212292) +++ head/sys/fs/nfsclient/nfsnode.h Tue Sep 7 14:29:45 2010 (r212293) @@ -96,10 +96,9 @@ struct nfsnode { time_t n_attrstamp; /* Attr. cache timestamp */ struct nfs_accesscache n_accesscache[NFS_ACCESSCACHESIZE]; struct timespec n_mtime; /* Prev modify time. */ - time_t n_ctime; /* Prev create time. */ - time_t n_dmtime; /* Prev dir modify time. */ + struct timespec n_ctime; /* Prev create time. */ + struct timespec n_dmtime; /* Prev dir modify time. */ int n_dmtime_ticks; /* Tick of -ve cache entry */ - time_t n_expiry; /* Lease expiry time */ struct nfsfh *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ struct vnode *n_dvp; /* parent vnode */ Modified: head/sys/nfsclient/nfs_vnops.c ============================================================================== --- head/sys/nfsclient/nfs_vnops.c Tue Sep 7 13:50:02 2010 (r212292) +++ head/sys/nfsclient/nfs_vnops.c Tue Sep 7 14:29:45 2010 (r212293) @@ -916,7 +916,7 @@ nfs_lookup(struct vop_lookup_args *ap) struct vnode **vpp = ap->a_vpp; struct mount *mp = dvp->v_mount; struct vattr vattr; - time_t dmtime; + struct timespec dmtime; int flags = cnp->cn_flags; struct vnode *newvp; struct nfsmount *nmp; @@ -970,7 +970,7 @@ nfs_lookup(struct vop_lookup_args *ap) mtx_unlock(&newnp->n_mtx); } if (VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 && - vattr.va_ctime.tv_sec == newnp->n_ctime) { + timespeccmp(&vattr.va_ctime, &newnp->n_ctime, ==)) { nfsstats.lookupcache_hits++; if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) @@ -997,13 +997,13 @@ nfs_lookup(struct vop_lookup_args *ap) if ((u_int)(ticks - np->n_dmtime_ticks) < (nmp->nm_negnametimeo * hz) && VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && - vattr.va_mtime.tv_sec == np->n_dmtime) { + timespeccmp(&vattr.va_mtime, &np->n_dmtime, ==)) { nfsstats.lookupcache_hits++; return (ENOENT); } cache_purge_negative(dvp); mtx_lock(&np->n_mtx); - np->n_dmtime = 0; + timespecclear(&np->n_dmtime); mtx_unlock(&np->n_mtx); } @@ -1018,7 +1018,7 @@ nfs_lookup(struct vop_lookup_args *ap) * the lookup RPC has been performed on the server but before * n_dmtime is set at the end of this function. */ - dmtime = np->n_vattr.va_mtime.tv_sec; + dmtime = np->n_vattr.va_mtime; error = 0; newvp = NULLVP; nfsstats.lookupcache_misses++; @@ -1137,7 +1137,7 @@ nfs_lookup(struct vop_lookup_args *ap) cnp->cn_flags |= SAVENAME; if ((cnp->cn_flags & MAKEENTRY) && (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) { - np->n_ctime = np->n_vattr.va_ctime.tv_sec; + np->n_ctime = np->n_vattr.va_ctime; cache_enter(dvp, newvp, cnp); } *vpp = newvp; @@ -1183,8 +1183,8 @@ nfsmout: * lookup. */ mtx_lock(&np->n_mtx); - if (np->n_dmtime <= dmtime) { - if (np->n_dmtime == 0) { + if (timespeccmp(&np->n_dmtime, &dmtime, <=)) { + if (!timespecisset(&np->n_dmtime)) { np->n_dmtime = dmtime; np->n_dmtime_ticks = ticks; } @@ -2657,8 +2657,11 @@ nfs_readdirplusrpc(struct vnode *vp, str dp->d_type = IFTODT(VTTOIF(np->n_vattr.va_type)); ndp->ni_vp = newvp; - /* Update n_ctime, so subsequent lookup doesn't purge entry */ - np->n_ctime = np->n_vattr.va_ctime.tv_sec; + /* + * Update n_ctime so subsequent lookup + * doesn't purge entry. + */ + np->n_ctime = np->n_vattr.va_ctime; cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp); } } else { Modified: head/sys/nfsclient/nfsnode.h ============================================================================== --- head/sys/nfsclient/nfsnode.h Tue Sep 7 13:50:02 2010 (r212292) +++ head/sys/nfsclient/nfsnode.h Tue Sep 7 14:29:45 2010 (r212293) @@ -102,10 +102,9 @@ struct nfsnode { time_t n_attrstamp; /* Attr. cache timestamp */ struct nfs_accesscache n_accesscache[NFS_ACCESSCACHESIZE]; struct timespec n_mtime; /* Prev modify time. */ - time_t n_ctime; /* Prev create time. */ - time_t n_dmtime; /* Prev dir modify time. */ + struct timespec n_ctime; /* Prev create time. */ + struct timespec n_dmtime; /* Prev dir modify time. */ int n_dmtime_ticks; /* Tick of -ve cache entry */ - time_t n_expiry; /* Lease expiry time */ nfsfh_t *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ struct vnode *n_dvp; /* parent vnode */