git: b70042adfebb - main - nfscl: Check for mmap(2)'d file before doing direct output
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 20 Dec 2021 21:13:28 UTC
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=b70042adfebbc4ee90d6a88dd6dc34d3f8ed5c37 commit b70042adfebbc4ee90d6a88dd6dc34d3f8ed5c37 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2021-12-20 21:08:51 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2021-12-20 21:10:26 +0000 nfscl: Check for mmap(2)'d file before doing direct output Commit 867c27c23a5c modified the NFS client so that it does IO_APPEND writes directly to the NFS server, bypassing the buffer cache. However, this could result in stale data in client pages when the file is mmap(2)'d. As such, the NFS client needs to call vm_object_is_active() to check if the file is mmap(2)'d and only do direct output if the file is not mmap(2)'d. This patch adds this check. Although a simple patch, I have given it a long MFC, since the related commit 867c27c23a5c made a significant semantics change and, as such, has a long MFC. MFC after: 3 months --- sys/fs/nfsclient/nfs_clbio.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index c3339617acce..06b51c050d34 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -1001,12 +1001,24 @@ ncl_write(struct vop_write_args *ap) if (uio->uio_resid == 0) return (0); + /* + * If the file in not mmap()'d, do IO_APPEND writing via a + * synchronous direct write. This can result in a significant + * performance improvement. + * If the file is mmap()'d, this cannot be done, since there + * is no way to maintain consistency between the file on the + * NFS server and the file's mmap()'d pages. + */ + NFSLOCKNODE(np); if (vp->v_type == VREG && ((newnfs_directio_enable && (ioflag & - IO_DIRECT)) || (ioflag & IO_APPEND))) { + IO_DIRECT)) || ((ioflag & IO_APPEND) && + (vp->v_object == NULL || !vm_object_is_active(vp->v_object))))) { + NFSUNLOCKNODE(np); if ((ioflag & IO_APPEND) != 0) ioflag |= IO_SYNC; return nfs_directio_write(vp, uio, cred, ioflag); } + NFSUNLOCKNODE(np); /* * Maybe this should be above the vnode op call, but so long as