summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2002-12-08 05:06:50 +0000
committerAlan Cox <alc@FreeBSD.org>2002-12-08 05:06:50 +0000
commit2e29a1f21f46ccd16e742f83a7c270435c5be540 (patch)
treeb6d69fcd682b4b6d102c923770974076108d0c53 /sys/kern
parente6f88402ff9d8a0d14cfbfb1ed65f6ff29544647 (diff)
Notes
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_subr.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index d6e2d9a09c7c..240f3ce725ca 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -885,6 +885,7 @@ getnewvnode(tag, mp, vops, vpp)
int s;
struct thread *td = curthread; /* XXX */
struct vnode *vp = NULL;
+ struct vpollinfo *pollinfo = NULL;
struct mount *vnmp;
s = splbio();
@@ -958,9 +959,12 @@ getnewvnode(tag, mp, vops, vpp)
panic("Non-zero write count");
}
#endif
- if (vp->v_pollinfo) {
- mtx_destroy(&vp->v_pollinfo->vpi_lock);
- uma_zfree(vnodepoll_zone, vp->v_pollinfo);
+ if ((pollinfo = vp->v_pollinfo) != NULL) {
+ /*
+ * To avoid lock order reversals, the call to
+ * uma_zfree() must be delayed until the vnode
+ * interlock is released.
+ */
vp->v_pollinfo = NULL;
}
#ifdef MAC
@@ -1002,6 +1006,10 @@ getnewvnode(tag, mp, vops, vpp)
vp->v_data = 0;
vp->v_cachedid = -1;
VI_UNLOCK(vp);
+ if (pollinfo != NULL) {
+ mtx_destroy(&pollinfo->vpi_lock);
+ uma_zfree(vnodepoll_zone, pollinfo);
+ }
#ifdef MAC
mac_init_vnode(vp);
if (mp != NULL && (mp->mnt_flag & MNT_MULTILABEL) == 0)