Date: Mon, 19 Nov 2018 00:49:08 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r340590 - stable/12/sys/fs/nfsclient Message-ID: <201811190049.wAJ0n8TG045259@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Mon Nov 19 00:49:08 2018 New Revision: 340590 URL: https://svnweb.freebsd.org/changeset/base/340590 Log: MFC: r339999 Fix NFS client vnode locking to avoid a crash during forced dismount. A crash was reported where the crash occurred in nfs_advlock() when the NFS_ISV4(vp) macro was being executed. This was caused by the vnode being VI_DOOMED due to a forced dismount in progress. This patch fixes the problem by locking the vnode before executing the NFS_ISV4() macro. PR: 232673 Modified: stable/12/sys/fs/nfsclient/nfs_clvnops.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/fs/nfsclient/nfs_clvnops.c ============================================================================== --- stable/12/sys/fs/nfsclient/nfs_clvnops.c Sun Nov 18 23:48:15 2018 (r340589) +++ stable/12/sys/fs/nfsclient/nfs_clvnops.c Mon Nov 19 00:49:08 2018 (r340590) @@ -3008,14 +3008,19 @@ nfs_advlock(struct vop_advlock_args *ap) int ret, error = EOPNOTSUPP; u_quad_t size; + ret = NFSVOPLOCK(vp, LK_SHARED); + if (ret != 0) + return (EBADF); if (NFS_ISV4(vp) && (ap->a_flags & (F_POSIX | F_FLOCK)) != 0) { - if (vp->v_type != VREG) + if (vp->v_type != VREG) { + NFSVOPUNLOCK(vp, 0); return (EINVAL); + } if ((ap->a_flags & F_POSIX) != 0) cred = p->p_ucred; else cred = td->td_ucred; - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); + NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY); if (vp->v_iflag & VI_DOOMED) { NFSVOPUNLOCK(vp, 0); return (EBADF); @@ -3094,9 +3099,6 @@ nfs_advlock(struct vop_advlock_args *ap) NFSVOPUNLOCK(vp, 0); return (0); } else if (!NFS_ISV4(vp)) { - error = NFSVOPLOCK(vp, LK_SHARED); - if (error) - return (error); if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { size = VTONFS(vp)->n_size; NFSVOPUNLOCK(vp, 0); @@ -3119,7 +3121,8 @@ nfs_advlock(struct vop_advlock_args *ap) NFSVOPUNLOCK(vp, 0); } } - } + } else + NFSVOPUNLOCK(vp, 0); return (error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811190049.wAJ0n8TG045259>