FreeBSD/sys/fs/nfsclient/nfs_clsubs.c
/*
 * Check the time stamp
 * If the cache is valid, copy contents to *vap and return 0
 * otherwise return an error
 */
Check the time stamp
If the cache is valid, copy contents to *vap and return 0
otherwise return an error
Check the time stamp If the cache is valid copy contents to * vap and return 0 otherwise return an error
int
ncl_getattrcache(struct vnode *vp, struct vattr *vaper)
{
	struct nfsnode *np;
	struct vattr *vap;
	struct nfsmount *nmp;
	int timeo, mustflush;
	np = VTONFS(vp);
	vap = &np->n_vattr.na_vattr;
	nmp = VFSTONFS(vp->v_mount);
	mustflush = nfscl_mustflush(vp);	
	mtx_lock(&np->n_mtx);
	timeo = (time_second - np->n_mtime.tv_sec) / 10;
#ifdef NFS_ACDEBUG
	if (nfs_acdebug>1)
		printf("ncl_getattrcache: initial timeo = %d\n", timeo);
#endif
	if (vap->va_type == VDIR) {
		if ((np->n_flag & NMODIFIED) || timeo < nmp->nm_acdirmin)
			timeo = nmp->nm_acdirmin;
		else if (timeo > nmp->nm_acdirmax)
			timeo = nmp->nm_acdirmax;
	} else {
		if ((np->n_flag & NMODIFIED) || timeo < nmp->nm_acregmin)
			timeo = nmp->nm_acregmin;
		else if (timeo > nmp->nm_acregmax)
			timeo = nmp->nm_acregmax;
	}
#ifdef NFS_ACDEBUG
	if (nfs_acdebug > 2)
		printf("acregmin %d; acregmax %d; acdirmin %d; acdirmax %d\n",
		    nmp->nm_acregmin, nmp->nm_acregmax,
		    nmp->nm_acdirmin, nmp->nm_acdirmax);
	if (nfs_acdebug)
		printf("ncl_getattrcache: age = %d; final timeo = %d\n",
		    (time_second - np->n_attrstamp), timeo);
#endif
	if ((time_second - np->n_attrstamp) >= timeo &&
	    (mustflush != 0 || np->n_attrstamp == 0)) {
		newnfsstats.attrcache_misses++;
		mtx_unlock(&np->n_mtx);
		KDTRACE_NFS_ATTRCACHE_GET_MISS(vp);
		return( ENOENT);
	}
	newnfsstats.attrcache_hits++;
	if (vap->va_size != np->n_size) {
		if (vap->va_type == VREG) {
			if (np->n_flag & NMODIFIED) {
				if (vap->va_size < np->n_size)
					vap->va_size = np->n_size;
				else
					np->n_size = vap->va_size;
			} else {
				np->n_size = vap->va_size;
			}
			vnode_pager_setsize(vp, np->n_size);
		} else {
			np->n_size = vap->va_size;
		}
	}
	bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(struct vattr));
	if (np->n_flag & NCHG) {
		if (np->n_flag & NACC)
			vaper->va_atime = np->n_atim;
		if (np->n_flag & NUPD)
			vaper->va_mtime = np->n_mtim;
	}
	mtx_unlock(&np->n_mtx);
	KDTRACE_NFS_ATTRCACHE_GET_HIT(vp, vap);
	return (0);
}
int ncl_getattrcache ( struct vnode * vp , struct vattr * vaper ) { struct nfsnode * np ; struct vattr * vap ; struct nfsmount * nmp ; int timeo , mustflush ; np = VTONFS ( vp ) ; vap = & np -> n_vattr . na_vattr ; nmp = VFSTONFS ( vp -> v_mount ) ; mustflush = nfscl_mustflush ( vp ) ; mtx_lock ( & np -> n_mtx ) ; timeo = ( time_second - np -> n_mtime . tv_sec ) / 10 ; #ifdef NFS_ACDEBUG if ( nfs_acdebug > 1 ) printf ( " \n " , timeo ) ; #endif if ( vap -> va_type == VDIR ) { if ( ( np -> n_flag & NMODIFIED ) || timeo < nmp -> nm_acdirmin ) timeo = nmp -> nm_acdirmin ; else if ( timeo > nmp -> nm_acdirmax ) timeo = nmp -> nm_acdirmax ; } else { if ( ( np -> n_flag & NMODIFIED ) || timeo < nmp -> nm_acregmin ) timeo = nmp -> nm_acregmin ; else if ( timeo > nmp -> nm_acregmax ) timeo = nmp -> nm_acregmax ; } #ifdef NFS_ACDEBUG if ( nfs_acdebug > 2 ) printf ( " \n " , nmp -> nm_acregmin , nmp -> nm_acregmax , nmp -> nm_acdirmin , nmp -> nm_acdirmax ) ; if ( nfs_acdebug ) printf ( " \n " , ( time_second - np -> n_attrstamp ) , timeo ) ; #endif if ( ( time_second - np -> n_attrstamp ) >= timeo && ( mustflush != 0 || np -> n_attrstamp == 0 ) ) { newnfsstats . attrcache_misses ++ ; mtx_unlock ( & np -> n_mtx ) ; KDTRACE_NFS_ATTRCACHE_GET_MISS ( vp ) ; return ( ENOENT ) ; } newnfsstats . attrcache_hits ++ ; if ( vap -> va_size != np -> n_size ) { if ( vap -> va_type == VREG ) { if ( np -> n_flag & NMODIFIED ) { if ( vap -> va_size < np -> n_size ) vap -> va_size = np -> n_size ; else np -> n_size = vap -> va_size ; } else { np -> n_size = vap -> va_size ; } vnode_pager_setsize ( vp , np -> n_size ) ; } else { np -> n_size = vap -> va_size ; } } bcopy ( ( caddr_t ) vap , ( caddr_t ) vaper , sizeof ( struct vattr ) ) ; if ( np -> n_flag & NCHG ) { if ( np -> n_flag & NACC ) vaper -> va_atime = np -> n_atim ; if ( np -> n_flag & NUPD ) vaper -> va_mtime = np -> n_mtim ; } mtx_unlock ( & np -> n_mtx ) ; KDTRACE_NFS_ATTRCACHE_GET_HIT ( vp , vap ) ; return ( 0 ) ; }
Check the time stamp
 If the cache is valid, copy contents to *vap and return 0
 otherwise return an error
Check the time stamp If the cache is valid copy contents to * vap and return 0 otherwise return an error
/* must be before mtx_lock() */ /* XXX n_mtime doesn't seem to be updated on a miss-and-reload */