summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2002-12-08 05:06:50 +0000
committeralc <alc@FreeBSD.org>2002-12-08 05:06:50 +0000
commita7482ae294664d142373a8b5ad6022c247d63528 (patch)
treeb6d69fcd682b4b6d102c923770974076108d0c53 /sys/kern/vfs_subr.c
parent8e140c31c1375b9e1258337b0522695692809293 (diff)
downloadFreeBSD-src-a7482ae294664d142373a8b5ad6022c247d63528.zip
FreeBSD-src-a7482ae294664d142373a8b5ad6022c247d63528.tar.gz
To avoid lock order reversals in getnewvnode(), the call to uma_zfree()
must be delayed until the vnode interlock is released. Reported by: kris@ Approved by: re (jhb)
Diffstat (limited to 'sys/kern/vfs_subr.c')
-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 d6e2d9a..240f3ce 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)
OpenPOWER on IntegriCloud