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-all
mailing list