- Lock access to the buf lists in spec_sync()

- Fixup interlock locking in spec_close()
This commit is contained in:
Jeff Roberson 2002-09-25 02:29:49 +00:00
parent 75cabb639a
commit c944ebed73

View File

@ -377,6 +377,7 @@ spec_fsync(ap)
if (!vn_isdisk(vp, NULL)) if (!vn_isdisk(vp, NULL))
return (0); return (0);
VI_LOCK(vp);
loop1: loop1:
/* /*
* MARK/SCAN initialization to avoid infinite loops. * MARK/SCAN initialization to avoid infinite loops.
@ -396,9 +397,12 @@ loop2:
nbp = TAILQ_NEXT(bp, b_vnbufs); nbp = TAILQ_NEXT(bp, b_vnbufs);
if ((bp->b_flags & B_SCANNED) != 0) if ((bp->b_flags & B_SCANNED) != 0)
continue; continue;
VI_UNLOCK(vp);
bp->b_flags |= B_SCANNED; bp->b_flags |= B_SCANNED;
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
VI_LOCK(vp);
continue; continue;
}
if ((bp->b_flags & B_DELWRI) == 0) if ((bp->b_flags & B_DELWRI) == 0)
panic("spec_fsync: not dirty"); panic("spec_fsync: not dirty");
if ((vp->v_vflag & VV_OBJBUF) && (bp->b_flags & B_CLUSTEROK)) { if ((vp->v_vflag & VV_OBJBUF) && (bp->b_flags & B_CLUSTEROK)) {
@ -410,6 +414,7 @@ loop2:
splx(s); splx(s);
bawrite(bp); bawrite(bp);
} }
VI_LOCK(vp);
goto loop2; goto loop2;
} }
@ -420,13 +425,11 @@ loop2:
* retry if dirty blocks still exist. * retry if dirty blocks still exist.
*/ */
if (ap->a_waitfor == MNT_WAIT) { if (ap->a_waitfor == MNT_WAIT) {
VI_LOCK(vp);
while (vp->v_numoutput) { while (vp->v_numoutput) {
vp->v_iflag |= VI_BWAIT; vp->v_iflag |= VI_BWAIT;
msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp), msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp),
PRIBIO + 1, "spfsyn", 0); PRIBIO + 1, "spfsyn", 0);
} }
VI_UNLOCK(vp);
if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) { if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
if (--maxretry != 0) { if (--maxretry != 0) {
splx(s); splx(s);
@ -435,6 +438,7 @@ loop2:
vprint("spec_fsync: giving up on dirty", vp); vprint("spec_fsync: giving up on dirty", vp);
} }
} }
VI_UNLOCK(vp);
splx(s); splx(s);
return (0); return (0);
} }
@ -584,7 +588,6 @@ spec_close(ap)
struct thread *td = ap->a_td; struct thread *td = ap->a_td;
dev_t dev = vp->v_rdev; dev_t dev = vp->v_rdev;
mp_fixme("Use of v_iflags bogusly locked.");
/* /*
* Hack: a tty device that is a controlling terminal * Hack: a tty device that is a controlling terminal
* has a reference from the session structure. * has a reference from the session structure.
@ -602,10 +605,12 @@ spec_close(ap)
oldvp = NULL; oldvp = NULL;
sx_xlock(&proctree_lock); sx_xlock(&proctree_lock);
if (vcount(vp) == 2 && td && (vp->v_iflag & VI_XLOCK) == 0 && if (td && vp == td->td_proc->p_session->s_ttyvp) {
vp == td->td_proc->p_session->s_ttyvp) {
SESS_LOCK(td->td_proc->p_session); SESS_LOCK(td->td_proc->p_session);
td->td_proc->p_session->s_ttyvp = NULL; VI_LOCK(vp);
if (vcount(vp) == 2 && (vp->v_iflag & VI_XLOCK) == 0)
td->td_proc->p_session->s_ttyvp = NULL;
VI_UNLOCK(vp);
SESS_UNLOCK(td->td_proc->p_session); SESS_UNLOCK(td->td_proc->p_session);
oldvp = vp; oldvp = vp;
} }
@ -621,13 +626,16 @@ spec_close(ap)
* sum of the reference counts on all the aliased * sum of the reference counts on all the aliased
* vnodes descends to one, we are on last close. * vnodes descends to one, we are on last close.
*/ */
VI_LOCK(vp);
if (vp->v_iflag & VI_XLOCK) { if (vp->v_iflag & VI_XLOCK) {
/* Forced close. */ /* Forced close. */
} else if (devsw(dev)->d_flags & D_TRACKCLOSE) { } else if (devsw(dev)->d_flags & D_TRACKCLOSE) {
/* Keep device updated on status. */ /* Keep device updated on status. */
} else if (vcount(vp) > 1) { } else if (vcount(vp) > 1) {
VI_UNLOCK(vp);
return (0); return (0);
} }
VI_UNLOCK(vp);
return (devsw(dev)->d_close(dev, ap->a_fflag, S_IFCHR, td)); return (devsw(dev)->d_close(dev, ap->a_fflag, S_IFCHR, td));
} }