rev. 1.167 of src/sys/dev/md/md.c
rev. 1.514, 1.515 of src/sys/kern/vfs_bio.c
rev. 1.319, 1.320 of src/sys/sys/vnode.h

Resolve two deadlocks that could be caused by busy md device backed by
vnode.
This commit is contained in:
kib 2007-01-05 09:51:14 +00:00
parent f3819dc428
commit 572798e9ab
3 changed files with 19 additions and 1 deletions

View File

@ -647,6 +647,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);
@ -877,6 +879,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)
@ -890,6 +893,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);
@ -920,6 +926,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);

View File

@ -796,6 +796,8 @@ int
bufwrite(struct buf *bp)
{
int oldflags;
struct vnode *vp;
int vp_md;
CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
if (bp->b_flags & B_INVAL) {
@ -810,6 +812,12 @@ bufwrite(struct buf *bp)
KASSERT(!(bp->b_vflags & BV_BKGRDINPROG),
("FFS background buffer should not get here %p", bp));
vp = bp->b_vp;
if (vp)
vp_md = vp->v_vflag & VV_MD;
else
vp_md = 0;
/* Mark the buffer clean */
bundirty(bp);
@ -847,7 +855,7 @@ 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 && !vp_md)
waitrunningbufspace();
}

View File

@ -253,6 +253,7 @@ struct xvnode {
#define VV_SYSTEM 0x0080 /* vnode being used by kernel */
#define VV_PROCDEP 0x0100 /* vnode is process dependent */
#define VV_NOKNOTE 0x0200 /* don't activate knotes on this vnode */
#define VV_MD 0x0800 /* vnode backs the md device */
/*
* Vnode attributes. A field value of VNOVAL represents a field whose value