diff options
author | dillon <dillon@FreeBSD.org> | 1999-02-19 17:36:58 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1999-02-19 17:36:58 +0000 |
commit | 17b6679e7ec69114e86c338181f15ac8276580c2 (patch) | |
tree | 6a244b141e0dd5469713ce480641a97ca64b442f /sys/kern/vfs_export.c | |
parent | 082d37c1acacd0403f5fb2883c7a0203c86baa10 (diff) | |
download | FreeBSD-src-17b6679e7ec69114e86c338181f15ac8276580c2.zip FreeBSD-src-17b6679e7ec69114e86c338181f15ac8276580c2.tar.gz |
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 )
Diffstat (limited to 'sys/kern/vfs_export.c')
-rw-r--r-- | sys/kern/vfs_export.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 6cf879d..8bc6935 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -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); } |