FreeBSD/sys/fs/nfsclient/nfs_clbio.c
/*
 * For nfs, cache consistency can only be maintained approximately.
 * Although RFC1094 does not specify the criteria, the following is
 * believed to be compatible with the reference port.
 * For nfs:
 * If the file's modify time on the server has changed since the
 * last read rpc or you have written to the file,
 * you may have lost data cache consistency with the
 * server, so flush all of the file's data out of the cache.
 * Then force a getattr rpc to ensure that you have up to date
 * attributes.
 * NB: This implies that cache data can be read when up to
 * NFS_ATTRTIMEO seconds out of date. If you find that you need current
 * attributes this could be forced by setting n_attrstamp to 0 before
 * the VOP_GETATTR() call.
 */
For nfs, cache consistency can only be maintained approximately.
Although RFC1094 does not specify the criteria, the following is
believed to be compatible with the reference port.
For nfs:
If the file's modify time on the server has changed since the
last read rpc or you have written to the file,
you may have lost data cache consistency with the
server, so flush all of the file's data out of the cache.
Then force a getattr rpc to ensure that you have up to date
attributes.
NB: This implies that cache data can be read when up to
NFS_ATTRTIMEO seconds out of date. If you find that you need current
attributes this could be forced by setting n_attrstamp to 0 before
the VOP_GETATTR() call.
For nfs cache consistency can only be maintained approximately . Although RFC1094 does not specify the criteria the following is believed to be compatible with the reference port . For nfs : If the file ' s modify time on the server has changed since the last read rpc or you have written to the file you may have lost data cache consistency with the server so flush all of the file ' s data out of the cache . Then force a getattr rpc to ensure that you have up to date attributes . NB : This implies that cache data can be read when up to NFS_ATTRTIMEO seconds out of date . If you find that you need current attributes this could be forced by setting n_attrstamp to 0 before the VOP_GETATTR () call .
static inline int
nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred)
{
	int error = 0;
	struct vattr vattr;
	struct nfsnode *np = VTONFS(vp);
	int old_lock;
	old_lock = ncl_upgrade_vnlock(vp);
	if (vp->v_iflag & VI_DOOMED) {
		ncl_downgrade_vnlock(vp, old_lock);
		return (EBADF);
	}
	mtx_lock(&np->n_mtx);
	if (np->n_flag & NMODIFIED) {
		mtx_unlock(&np->n_mtx);
		if (vp->v_type != VREG) {
			if (vp->v_type != VDIR)
				panic("nfs: bioread, not dir");
			ncl_invaldir(vp);
			error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
			if (error)
				goto out;
		}
		np->n_attrstamp = 0;
		KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
		error = VOP_GETATTR(vp, &vattr, cred);
		if (error)
			goto out;
		mtx_lock(&np->n_mtx);
		np->n_mtime = vattr.va_mtime;
		mtx_unlock(&np->n_mtx);
	} else {
		mtx_unlock(&np->n_mtx);
		error = VOP_GETATTR(vp, &vattr, cred);
		if (error)
			return (error);
		mtx_lock(&np->n_mtx);
		if ((np->n_flag & NSIZECHANGED)
		    || (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime))) {
			mtx_unlock(&np->n_mtx);
			if (vp->v_type == VDIR)
				ncl_invaldir(vp);
			error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
			if (error)
				goto out;
			mtx_lock(&np->n_mtx);
			np->n_mtime = vattr.va_mtime;
			np->n_flag &= ~NSIZECHANGED;
		}
		mtx_unlock(&np->n_mtx);
	}
out:
	ncl_downgrade_vnlock(vp, old_lock);
	return error;
}
static inline int nfs_bioread_check_cons ( struct vnode * vp , struct thread * td , struct ucred * cred ) { int error = 0 ; struct vattr vattr ; struct nfsnode * np = VTONFS ( vp ) ; int old_lock ; old_lock = ncl_upgrade_vnlock ( vp ) ; if ( vp -> v_iflag & VI_DOOMED ) { ncl_downgrade_vnlock ( vp , old_lock ) ; return ( EBADF ) ; } mtx_lock ( & np -> n_mtx ) ; if ( np -> n_flag & NMODIFIED ) { mtx_unlock ( & np -> n_mtx ) ; if ( vp -> v_type != VREG ) { if ( vp -> v_type != VDIR ) panic ( " " ) ; ncl_invaldir ( vp ) ; error = ncl_vinvalbuf ( vp , V_SAVE , td , 1 ) ; if ( error ) goto out ; } np -> n_attrstamp = 0 ; KDTRACE_NFS_ATTRCACHE_FLUSH_DONE ( vp ) ; error = VOP_GETATTR ( vp , & vattr , cred ) ; if ( error ) goto out ; mtx_lock ( & np -> n_mtx ) ; np -> n_mtime = vattr . va_mtime ; mtx_unlock ( & np -> n_mtx ) ; } else { mtx_unlock ( & np -> n_mtx ) ; error = VOP_GETATTR ( vp , & vattr , cred ) ; if ( error ) return ( error ) ; mtx_lock ( & np -> n_mtx ) ; if ( ( np -> n_flag & NSIZECHANGED ) || ( NFS_TIMESPEC_COMPARE ( & np -> n_mtime , & vattr . va_mtime ) ) ) { mtx_unlock ( & np -> n_mtx ) ; if ( vp -> v_type == VDIR ) ncl_invaldir ( vp ) ; error = ncl_vinvalbuf ( vp , V_SAVE , td , 1 ) ; if ( error ) goto out ; mtx_lock ( & np -> n_mtx ) ; np -> n_mtime = vattr . va_mtime ; np -> n_flag &= ~ NSIZECHANGED ; } mtx_unlock ( & np -> n_mtx ) ; } out : ncl_downgrade_vnlock ( vp , old_lock ) ; return error ; }
For nfs, cache consistency can only be maintained approximately.
For nfs cache consistency can only be maintained approximately .
/*
	 * Grab the exclusive lock before checking whether the cache is
	 * consistent.
	 * XXX - We can make this cheaper later (by acquiring cheaper locks).
	 * But for now, this suffices.
	 */