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
This commit is contained in:
parent
7eb5016ab5
commit
3b7b5496a7
@ -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);
|
||||
|
@ -871,7 +871,8 @@ bufwrite(struct buf *bp)
|
||||
* or syncer daemon trying to clean up as that can lead
|
||||
* to deadlock.
|
||||
*/
|
||||
if ((curthread->td_pflags & TDP_NORUNNINGBUF) == 0)
|
||||
if ((curthread->td_pflags & TDP_NORUNNINGBUF) == 0 &&
|
||||
(bp->b_vp->v_vflag & VV_MD) == 0)
|
||||
waitrunningbufspace();
|
||||
}
|
||||
|
||||
|
@ -254,6 +254,7 @@ struct xvnode {
|
||||
#define VV_PROCDEP 0x0100 /* vnode is process dependent */
|
||||
#define VV_NOKNOTE 0x0200 /* don't activate knotes on this vnode */
|
||||
#define VV_DELETED 0x0400 /* should be removed */
|
||||
#define VV_MD 0x0800 /* vnode backs the md device */
|
||||
|
||||
/*
|
||||
* Vnode attributes. A field value of VNOVAL represents a field whose value
|
||||
|
Loading…
x
Reference in New Issue
Block a user