svn commit: r357770 - head/sys/kern

Mateusz Guzik mjg at FreeBSD.org
Tue Feb 11 18:19:56 UTC 2020


Author: mjg
Date: Tue Feb 11 18:19:56 2020
New Revision: 357770
URL: https://svnweb.freebsd.org/changeset/base/357770

Log:
  vfs: fix vhold race in mnt_vnode_next_lazy_relock
  
  vdrop can set the hold count to 0 and wait for the ->mnt_listmtx held by
  mnt_vnode_next_lazy_relock caller. The routine incorrectly asserted the
  count has to be > 0.
  
  Reported by:	pho
  Tested by:	pho

Modified:
  head/sys/kern/vfs_subr.c

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c	Tue Feb 11 18:16:29 2020	(r357769)
+++ head/sys/kern/vfs_subr.c	Tue Feb 11 18:19:56 2020	(r357770)
@@ -6264,7 +6264,13 @@ mnt_vnode_next_lazy_relock(struct vnode *mvp, struct m
 	TAILQ_REMOVE(&mp->mnt_lazyvnodelist, mvp, v_lazylist);
 	TAILQ_INSERT_BEFORE(vp, mvp, v_lazylist);
 
-	vholdnz(vp);
+	/*
+	 * Note we may be racing against vdrop which transitioned the hold
+	 * count to 0 and now waits for the ->mnt_listmtx lock. This is fine,
+	 * if we are the only user after we get the interlock we will just
+	 * vdrop.
+	 */
+	vhold(vp);
 	mtx_unlock(&mp->mnt_listmtx);
 	VI_LOCK(vp);
 	if (VN_IS_DOOMED(vp)) {
@@ -6273,8 +6279,7 @@ mnt_vnode_next_lazy_relock(struct vnode *mvp, struct m
 	}
 	VNPASS(vp->v_mflag & VMP_LAZYLIST, vp);
 	/*
-	 * Since we had a period with no locks held we may be the last
-	 * remaining user, in which case there is nothing to do.
+	 * There is nothing to do if we are the last user.
 	 */
 	if (!refcount_release_if_not_last(&vp->v_holdcnt))
 		goto out_lost;


More information about the svn-src-head mailing list