summaryrefslogtreecommitdiffstats
path: root/sys/dev/md
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2006-12-14 11:34:07 +0000
committerkib <kib@FreeBSD.org>2006-12-14 11:34:07 +0000
commite7cdcb324074afe862ff79dff4056e372d7a7dcc (patch)
treeb4491be126c4489f10c7fd21ffcd58a2b9876bfd /sys/dev/md
parentd828ea069054def0683feaaa0ab3b996287edc4e (diff)
downloadFreeBSD-src-e7cdcb324074afe862ff79dff4056e372d7a7dcc.zip
FreeBSD-src-e7cdcb324074afe862ff79dff4056e372d7a7dcc.tar.gz
Resolve two deadlocks that could be caused by busy md device backed
by vnode. Allow for md thread and the thread that owns lock on vnode backing the md device to do the write even when runningbufspace is exhausted. Tested by: Peter Holm Reviewed by: tegge MFC after: 2 weeks
Diffstat (limited to 'sys/dev/md')
-rw-r--r--sys/dev/md/md.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 3b6cc6b..06a813f 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -693,6 +693,8 @@ md_kthread(void *arg)
mtx_lock_spin(&sched_lock);
sched_prio(curthread, PRIBIO);
mtx_unlock_spin(&sched_lock);
+ if (sc->type == MD_VNODE)
+ curthread->td_pflags |= TDP_NORUNNINGBUF;
for (;;) {
mtx_lock(&sc->queue_mtx);
@@ -923,6 +925,7 @@ mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
VFS_UNLOCK_GIANT(vfslocked);
return (error ? error : EINVAL);
}
+ nd.ni_vp->v_vflag |= VV_MD;
VOP_UNLOCK(nd.ni_vp, 0, td);
if (mdio->md_fwsectors != 0)
@@ -936,6 +939,9 @@ mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
error = mdsetcred(sc, td->td_ucred);
if (error != 0) {
+ vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, td);
+ nd.ni_vp->v_vflag &= ~VV_MD;
+ VOP_UNLOCK(nd.ni_vp, 0, td);
(void)vn_close(nd.ni_vp, flags, td->td_ucred, td);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
@@ -966,6 +972,9 @@ mddestroy(struct md_s *sc, struct thread *td)
mtx_destroy(&sc->queue_mtx);
if (sc->vnode != NULL) {
vfslocked = VFS_LOCK_GIANT(sc->vnode->v_mount);
+ vn_lock(sc->vnode, LK_EXCLUSIVE | LK_RETRY, td);
+ sc->vnode->v_vflag &= ~VV_MD;
+ VOP_UNLOCK(sc->vnode, 0, td);
(void)vn_close(sc->vnode, sc->flags & MD_READONLY ?
FREAD : (FREAD|FWRITE), sc->cred, td);
VFS_UNLOCK_GIANT(vfslocked);
OpenPOWER on IntegriCloud