Author: rmacklem
Date: Sun Nov 18 22:59:54 2018
New Revision: 340588
URL: https://svnweb.freebsd.org/changeset/base/340588

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/11/sys/fs/nfsclient/nfs_clvnops.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- stable/11/sys/fs/nfsclient/nfs_clvnops.c    Sun Nov 18 19:55:03 2018        
(r340587)
+++ stable/11/sys/fs/nfsclient/nfs_clvnops.c    Sun Nov 18 22:59:54 2018        
(r340588)
@@ -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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to