Index: head/sys/kern/vfs_default.c =================================================================== --- head/sys/kern/vfs_default.c +++ head/sys/kern/vfs_default.c @@ -588,22 +588,28 @@ } */ *ap; { struct mount *mp; + struct vnode *vp; /* - * XXX Since this is called unlocked we may be recycled while - * attempting to ref the mount. If this is the case or mountpoint - * will be set to NULL. We only have to prevent this call from - * returning with a ref to an incorrect mountpoint. It is not - * harmful to return with a ref to our previous mountpoint. + * Note that having a reference does not prevent forced unmount from + * setting ->v_mount to NULL after the lock gets released. This is of + * no consequence for typical consumers (most notably vn_start_write) + * since in this case the vnode is VI_DOOMED. Unmount might have + * progressed far enough that its completion is only delayed by the + * reference obtained here. The consumer only needs to concern itself + * with releasing it. */ - mp = ap->a_vp->v_mount; - if (mp != NULL) { - vfs_ref(mp); - if (mp != ap->a_vp->v_mount) { - vfs_rel(mp); - mp = NULL; - } + vp = ap->a_vp; + mp = vp->v_mount; + MNT_ILOCK(mp); + if (mp != vp->v_mount) { + MNT_IUNLOCK(mp); + mp = NULL; + goto out; } + MNT_REF(mp); + MNT_IUNLOCK(mp); +out: *(ap->a_mpp) = mp; return (0); }