Protect vn worklist and vn->v_{clean,dirty}blkhd at splbio().

Get rid of extra LIST_REMOVE()

Reviewed by:	hsu@FreeBSD.ORG (Jeffrey Hsu), mckusick@McKusick.COM
Submitted by:	hsu@FreeBSD.ORG (Jeffrey Hsu), dillon@backplane.com ( Matthew Dillon )
This commit is contained in:
Matthew Dillon 1999-02-19 17:36:58 +00:00
parent b1028ad122
commit 42e26d47bd
2 changed files with 34 additions and 18 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $Id: vfs_subr.c,v 1.185 1999/01/29 23:18:49 dillon Exp $
* $Id: vfs_subr.c,v 1.186 1999/02/04 18:25:39 dillon Exp $
*/
/*
@ -881,10 +881,8 @@ brelvp(bp)
/*
* Add an item to the syncer work queue.
*/
void
vn_syncer_add_to_worklist(vp, delay)
struct vnode *vp;
int delay;
static void
vn_syncer_add_to_worklist(struct vnode *vp, int delay)
{
int s, slot;
@ -928,7 +926,8 @@ sched_sync(void)
starttime = time_second;
/*
* Push files whose dirty time has expired.
* Push files whose dirty time has expired. Be careful
* of interrupt race on slp queue.
*/
s = splbio();
slp = &syncer_workitem_pending[syncer_delayno];
@ -941,16 +940,20 @@ sched_sync(void)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
VOP_UNLOCK(vp, 0, p);
s = splbio();
if (LIST_FIRST(slp) == vp) {
if (TAILQ_EMPTY(&vp->v_dirtyblkhd) &&
vp->v_type != VBLK)
panic("sched_sync: fsync failed");
panic("sched_sync: fsync failed vp %p tag %d", vp, vp->v_tag);
/*
* Move ourselves to the back of the sync list.
* Put us back on the worklist. The worklist
* routine will remove us from our current
* position and then add us back in at a later
* position.
*/
LIST_REMOVE(vp, v_synclist);
vn_syncer_add_to_worklist(vp, syncdelay);
}
splx(s);
}
/*
@ -2841,6 +2844,8 @@ sync_inactive(ap)
/*
* The syncer vnode is no longer needed and is being decommissioned.
*
* Modifications to the worklist must be protected at splbio().
*/
static int
sync_reclaim(ap)
@ -2849,12 +2854,15 @@ sync_reclaim(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
int s;
s = splbio();
vp->v_mount->mnt_syncer = NULL;
if (vp->v_flag & VONWORKLST) {
LIST_REMOVE(vp, v_synclist);
vp->v_flag &= ~VONWORKLST;
}
splx(s);
return (0);
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $Id: vfs_subr.c,v 1.185 1999/01/29 23:18:49 dillon Exp $
* $Id: vfs_subr.c,v 1.186 1999/02/04 18:25:39 dillon Exp $
*/
/*
@ -881,10 +881,8 @@ brelvp(bp)
/*
* Add an item to the syncer work queue.
*/
void
vn_syncer_add_to_worklist(vp, delay)
struct vnode *vp;
int delay;
static void
vn_syncer_add_to_worklist(struct vnode *vp, int delay)
{
int s, slot;
@ -928,7 +926,8 @@ sched_sync(void)
starttime = time_second;
/*
* Push files whose dirty time has expired.
* Push files whose dirty time has expired. Be careful
* of interrupt race on slp queue.
*/
s = splbio();
slp = &syncer_workitem_pending[syncer_delayno];
@ -941,16 +940,20 @@ sched_sync(void)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
VOP_UNLOCK(vp, 0, p);
s = splbio();
if (LIST_FIRST(slp) == vp) {
if (TAILQ_EMPTY(&vp->v_dirtyblkhd) &&
vp->v_type != VBLK)
panic("sched_sync: fsync failed");
panic("sched_sync: fsync failed vp %p tag %d", vp, vp->v_tag);
/*
* Move ourselves to the back of the sync list.
* Put us back on the worklist. The worklist
* routine will remove us from our current
* position and then add us back in at a later
* position.
*/
LIST_REMOVE(vp, v_synclist);
vn_syncer_add_to_worklist(vp, syncdelay);
}
splx(s);
}
/*
@ -2841,6 +2844,8 @@ sync_inactive(ap)
/*
* The syncer vnode is no longer needed and is being decommissioned.
*
* Modifications to the worklist must be protected at splbio().
*/
static int
sync_reclaim(ap)
@ -2849,12 +2854,15 @@ sync_reclaim(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
int s;
s = splbio();
vp->v_mount->mnt_syncer = NULL;
if (vp->v_flag & VONWORKLST) {
LIST_REMOVE(vp, v_synclist);
vp->v_flag &= ~VONWORKLST;
}
splx(s);
return (0);
}