diff options
author | ps <ps@FreeBSD.org> | 2004-12-01 06:48:54 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2004-12-01 06:48:54 +0000 |
commit | 531cb416aedb221d9b2ae727002a2893350f73da (patch) | |
tree | d8314293c655d56edf6d628250667be44f9aa0f0 /sys/nfsclient | |
parent | 69d7e65011bc973bc85975779d33f32217b72d74 (diff) | |
download | FreeBSD-src-531cb416aedb221d9b2ae727002a2893350f73da.zip FreeBSD-src-531cb416aedb221d9b2ae727002a2893350f73da.tar.gz |
Clean all dirty pages (dirtied by mmap'ed writes) in nfs_close().
This closes a major hole in close-to-open consistency support.
Added a new sysctl so that this can be disabled for single NFS
client applications with very large amounts of mmap'ed IO (for
performance).
Submitted by: Mohan Srinivasan mohans at yahoo-inc dot com
Reviewed by: rwatson
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index bd0fcb3..50edb58 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -213,6 +213,11 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, static int nfsv3_commit_on_close = 0; SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, &nfsv3_commit_on_close, 0, "write+commit on close, else only write"); + +static int nfs_clean_pages_on_close = 1; +SYSCTL_INT(_vfs_nfs, OID_AUTO, clean_pages_on_close, CTLFLAG_RW, + &nfs_clean_pages_on_close, 0, "NFS clean dirty pages on close"); + #if 0 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); @@ -475,6 +480,19 @@ nfs_close(struct vop_close_args *ap) int error = 0; if (vp->v_type == VREG) { + /* + * Examine and clean dirty pages, regardless of NMODIFIED. + * This closes a major hole in close-to-open consistency. + * We want to push out all dirty pages (and buffers) on + * close, regardless of whether they were dirtied by + * mmap'ed writes or via write(). + */ + if (nfs_clean_pages_on_close && vp->v_object) { + VM_OBJECT_LOCK(vp->v_object); + vm_object_page_clean(vp->v_object, 0, 0, 0); + VM_OBJECT_UNLOCK(vp->v_object); + } + if (np->n_flag & NMODIFIED) { if (NFS_ISV3(vp)) { /* |