git: ccea961fcc83 - stable/13 - nfsclient: upgrade vnode lock in VOP_OPEN()/VOP_CLOSE() if we need to flush buffers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 19 Nov 2021 04:36:53 UTC
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=ccea961fcc83b0d9011d75c488216cf6770042c7 commit ccea961fcc83b0d9011d75c488216cf6770042c7 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-11-15 20:24:46 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-11-19 04:25:29 +0000 nfsclient: upgrade vnode lock in VOP_OPEN()/VOP_CLOSE() if we need to flush buffers (cherry picked from commit 8ef0c11e7ce79106130012cb929a8324045f7ff9) --- sys/fs/nfsclient/nfs_clvnops.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index cd8077e243ea..5ae731d1b5e3 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -645,6 +645,11 @@ nfs_open(struct vop_open_args *ap) NFSLOCKNODE(np); if (np->n_flag & NMODIFIED) { NFSUNLOCKNODE(np); + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp)) + return (EBADF); + } error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (error == EINTR || error == EIO) { if (NFS_ISV4(vp)) @@ -681,6 +686,11 @@ nfs_open(struct vop_open_args *ap) if (vp->v_type == VDIR) np->n_direofoffset = 0; NFSUNLOCKNODE(np); + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp)) + return (EBADF); + } error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (error == EINTR || error == EIO) { if (NFS_ISV4(vp)) @@ -701,6 +711,11 @@ nfs_open(struct vop_open_args *ap) (vp->v_type == VREG)) { if (np->n_directio_opens == 0) { NFSUNLOCKNODE(np); + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp)) + return (EBADF); + } error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (error) { if (NFS_ISV4(vp)) @@ -746,6 +761,11 @@ nfs_open(struct vop_open_args *ap) if (vp->v_writecount <= -1) { if ((obj = vp->v_object) != NULL && vm_object_mightbedirty(obj)) { + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp)) + return (EBADF); + } VM_OBJECT_WLOCK(obj); vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); VM_OBJECT_WUNLOCK(obj); @@ -829,6 +849,11 @@ nfs_close(struct vop_close_args *ap) * mmap'ed writes or via write(). */ if (nfs_clean_pages_on_close && vp->v_object) { + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp) && ap->a_fflag != FNONBLOCK) + return (EBADF); + } VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); VM_OBJECT_WUNLOCK(vp->v_object); @@ -853,11 +878,22 @@ nfs_close(struct vop_close_args *ap) * traditional vnode locking implemented for Vnode Ops. */ int cm = newnfs_commit_on_close ? 1 : 0; + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp) && ap->a_fflag != FNONBLOCK) + return (EBADF); + } error = ncl_flush(vp, MNT_WAIT, ap->a_td, cm, 0); /* np->n_flag &= ~NMODIFIED; */ } else if (NFS_ISV4(vp)) { if (nfscl_mustflush(vp) != 0) { int cm = newnfs_commit_on_close ? 1 : 0; + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp) && ap->a_fflag != + FNONBLOCK) + return (EBADF); + } error = ncl_flush(vp, MNT_WAIT, ap->a_td, cm, 0); /* @@ -867,6 +903,12 @@ nfs_close(struct vop_close_args *ap) */ } } else { + if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); + if (VN_IS_DOOMED(vp) && ap->a_fflag != + FNONBLOCK) + return (EBADF); + } error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); } NFSLOCKNODE(np);