MFC
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:
parent
f3819dc428
commit
572798e9ab
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user