Be more careful to block bio interrupts for some data structures. There

were at least a few missed cases where vp->v_{clean,dirty}blkhd were
unprotected since the softdep/trickle sync merge.
This commit is contained in:
fvdl 1999-11-23 23:52:40 +00:00
parent f56c15f914
commit d901f6eae0
8 changed files with 71 additions and 32 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_softdep.c,v 1.2 1999/11/18 12:20:45 fvdl Exp $ */
/* $NetBSD: ffs_softdep.c,v 1.3 1999/11/23 23:52:57 fvdl Exp $ */
/*
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@ -3709,10 +3709,12 @@ softdep_fsync_mountdev(vp)
{
struct buf *bp, *nbp;
struct worklist *wk;
int s;
if (vp->v_type != VBLK)
panic("softdep_fsync_mountdev: vnode not VBLK");
ACQUIRE_LOCK(&lk);
s = splbio();
for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
nbp = bp->b_vnbufs.le_next;
/*
@ -3731,15 +3733,18 @@ softdep_fsync_mountdev(vp)
continue;
bremfree(bp);
bp->b_flags |= B_BUSY;
splx(s);
FREE_LOCK(&lk);
(void) bawrite(bp);
ACQUIRE_LOCK(&lk);
s = splbio();
/*
* Since we may have slept during the I/O, we need
* to start from a known point.
*/
nbp = vp->v_dirtyblkhd.lh_first;
}
splx(s);
drain_output(vp, 1);
FREE_LOCK(&lk);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_bio.c,v 1.59 1999/11/15 18:49:09 fvdl Exp $ */
/* $NetBSD: vfs_bio.c,v 1.60 1999/11/23 23:52:40 fvdl Exp $ */
/*-
* Copyright (c) 1994 Christopher G. Demetriou
@ -110,6 +110,8 @@ void
bremfree(bp)
struct buf *bp;
{
int s = splbio();
struct bqueues *dp = NULL;
/*
@ -127,6 +129,8 @@ bremfree(bp)
panic("bremfree: lost tail");
}
TAILQ_REMOVE(dp, bp, b_freelist);
splx(s);
}
/*
@ -340,10 +344,11 @@ bwrite(bp)
}
wasdelayed = ISSET(bp->b_flags, B_DELWRI);
CLR(bp->b_flags, (B_READ | B_DONE | B_ERROR | B_DELWRI));
s = splbio();
CLR(bp->b_flags, (B_READ | B_DONE | B_ERROR | B_DELWRI));
/*
* Pay for the I/O operation and make sure the buf is on the correct
* vnode queue.
@ -399,8 +404,8 @@ void
bdwrite(bp)
struct buf *bp;
{
int s;
struct proc *p = (curproc != NULL ? curproc : &proc0); /* XXX */
int s;
/* If this is a tape block, write the block now. */
/* XXX NOTE: the memory filesystem usurpes major device */
@ -418,16 +423,18 @@ bdwrite(bp)
* (2) Charge for the write,
* (3) Make sure it's on its vnode's correct block list.
*/
s = splbio();
if (!ISSET(bp->b_flags, B_DELWRI)) {
SET(bp->b_flags, B_DELWRI);
p->p_stats->p_ru.ru_oublock++;
s = splbio();
reassignbuf(bp, bp->b_vp);
splx(s);
}
/* Otherwise, the "write" is done, so mark and release the buffer. */
CLR(bp->b_flags, B_NEEDCOMMIT|B_DONE);
splx(s);
brelse(bp);
}
@ -453,13 +460,15 @@ bdirty(bp)
struct proc *p = (curproc != NULL ? curproc : &proc0); /* XXX */
int s;
s = splbio();
if (!ISSET(bp->b_flags, B_DELWRI)) {
SET(bp->b_flags, B_DELWRI);
p->p_stats->p_ru.ru_oublock++;
s = splbio();
reassignbuf(bp, bp->b_vp);
splx(s);
}
splx(s);
}
/*
@ -479,15 +488,15 @@ brelse(bp)
wakeup(&needbuffer);
}
/* Block disk interrupts. */
s = splbio();
/* Wake up any proceeses waiting for _this_ buffer to become free. */
if (ISSET(bp->b_flags, B_WANTED)) {
CLR(bp->b_flags, B_WANTED|B_AGE);
wakeup(bp);
}
/* Block disk interrupts. */
s = splbio();
/*
* Determine which queue the buffer should be on, then put it there.
*/
@ -895,6 +904,8 @@ void
biodone(bp)
struct buf *bp;
{
int s = splbio();
if (ISSET(bp->b_flags, B_DONE))
panic("biodone already");
SET(bp->b_flags, B_DONE); /* note that it's done */
@ -916,6 +927,8 @@ biodone(bp)
wakeup(bp);
}
}
splx(s);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_subr.c,v 1.114 1999/11/18 05:50:25 enami Exp $ */
/* $NetBSD: vfs_subr.c,v 1.115 1999/11/23 23:52:40 fvdl Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -624,6 +624,8 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
splx(s);
}
s = splbio();
for (;;) {
if ((blist = vp->v_cleanblkhd.lh_first) && (flags & V_SAVEMETA))
while (blist && blist->b_lblkno < 0)
@ -640,19 +642,18 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
nbp = bp->b_vnbufs.le_next;
if (flags & V_SAVEMETA && bp->b_lblkno < 0)
continue;
s = splbio();
if (bp->b_flags & B_BUSY) {
bp->b_flags |= B_WANTED;
error = tsleep((caddr_t)bp,
slpflag | (PRIBIO + 1), "vinvalbuf",
slptimeo);
splx(s);
if (error)
if (error) {
splx(s);
return (error);
}
break;
}
bp->b_flags |= B_BUSY | B_VFLUSH;
splx(s);
/*
* XXX Since there are no node locks for NFS, I believe
* there is a slight chance that a delayed write will
@ -670,9 +671,13 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
brelse(bp);
}
}
if (!(flags & V_SAVEMETA) &&
(vp->v_dirtyblkhd.lh_first || vp->v_cleanblkhd.lh_first))
panic("vinvalbuf: flush failed");
splx(s);
return (0);
}
@ -727,10 +732,12 @@ bgetvp(vp, bp)
register struct vnode *vp;
register struct buf *bp;
{
int s;
if (bp->b_vp)
panic("bgetvp: not free");
VHOLD(vp);
s = splbio();
bp->b_vp = vp;
if (vp->v_type == VBLK || vp->v_type == VCHR)
bp->b_dev = vp->v_rdev;
@ -740,6 +747,7 @@ bgetvp(vp, bp)
* Insert onto list for new vnode.
*/
bufinsvn(bp, &vp->v_cleanblkhd);
splx(s);
}
/*
@ -750,9 +758,12 @@ brelvp(bp)
register struct buf *bp;
{
struct vnode *vp;
int s;
if (bp->b_vp == (struct vnode *) 0)
panic("brelvp: NULL");
s = splbio();
vp = bp->b_vp;
/*
* Delete from old vnode list, if on one.
@ -765,12 +776,15 @@ brelvp(bp)
}
bp->b_vp = (struct vnode *) 0;
HOLDRELE(vp);
splx(s);
}
/*
* Reassign a buffer from one vnode to another.
* Used to assign file specific control information
* (indirect blocks) to the vnode to which they belong.
*
* This function must be called at splbio().
*/
void
reassignbuf(bp, newvp)
@ -784,6 +798,7 @@ reassignbuf(bp, newvp)
printf("reassignbuf: NULL");
return;
}
/*
* Delete from old vnode list, if on one.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: sync_subr.c,v 1.2 1999/11/15 18:49:10 fvdl Exp $ */
/* $NetBSD: sync_subr.c,v 1.3 1999/11/23 23:52:41 fvdl Exp $ */
/*
* Copyright 1997 Marshall Kirk McKusick. All Rights Reserved.
@ -62,7 +62,7 @@ static int stat_rush_requests; /* number of times I/O speeded up */
static int syncer_delayno = 0;
static long syncer_last;
static struct synclist *syncer_workitem_pending;
static struct proc *updateproc = NULL;
struct proc *updateproc = NULL;
void
vn_initialize_syncerd()

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_bio.c,v 1.46 1999/11/15 18:49:11 fvdl Exp $ */
/* $NetBSD: nfs_bio.c,v 1.47 1999/11/23 23:52:41 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -931,7 +931,7 @@ again:
bp->b_wcred = cred;
}
}
TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen++;
return (0);
@ -1084,6 +1084,7 @@ nfs_doio(bp, cr, p)
vp, bp, bp->b_dirtyoff, bp->b_dirtyend);
#endif
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
s = splbio();
if (!error && iomode == NFSV3WRITE_UNSTABLE)
bp->b_flags |= B_NEEDCOMMIT;
else
@ -1111,9 +1112,7 @@ nfs_doio(bp, cr, p)
* dirty one. Ugh.
*/
if (bp->b_flags & B_ASYNC) {
s = splbio();
reassignbuf(bp, vp);
splx(s);
} else if (error)
bp->b_flags |= B_EINTR;
} else {
@ -1124,6 +1123,7 @@ nfs_doio(bp, cr, p)
}
bp->b_dirtyoff = bp->b_dirtyend = 0;
}
splx(s);
}
bp->b_resid = uiop->uio_resid;
if (must_commit)

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_bio.c,v 1.13 1999/11/06 20:33:05 perseant Exp $ */
/* $NetBSD: lfs_bio.c,v 1.14 1999/11/23 23:52:42 fvdl Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -241,6 +241,7 @@ lfs_bwrite_ext(bp, flags)
fs->lfs_avail -= db;
++locked_queue_count;
locked_queue_bytes += bp->b_bufsize;
s = splbio();
#ifdef LFS_HONOR_RDONLY
/*
* XXX KS - Don't write blocks if we're mounted ro.
@ -253,7 +254,6 @@ lfs_bwrite_ext(bp, flags)
#endif
bp->b_flags |= B_DELWRI | B_LOCKED;
bp->b_flags &= ~(B_READ | B_ERROR);
s = splbio();
reassignbuf(bp, bp->b_vp);
splx(s);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_inode.c,v 1.27 1999/09/03 22:48:51 perseant Exp $ */
/* $NetBSD: lfs_inode.c,v 1.28 1999/11/23 23:52:42 fvdl Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -236,7 +236,7 @@ lfs_truncate(v)
ufs_daddr_t daddr, lastblock, lbn, olastblock;
ufs_daddr_t oldsize_lastblock, oldsize_newlast, newsize;
long off, a_released, fragsreleased, i_released;
int e1, e2, depth, lastseg, num, offset, seg, freesize;
int e1, e2, depth, lastseg, num, offset, seg, freesize, s;
ip = VTOI(vp);
@ -426,6 +426,8 @@ lfs_truncate(v)
*/
a_released = 0;
i_released = 0;
s = splbio();
for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = bp->b_vnbufs.le_next) {
/* XXX KS - Don't miscount if we're not truncating to zero. */
@ -451,6 +453,7 @@ lfs_truncate(v)
}
}
}
splx(s);
fragsreleased = i_released;
#ifdef DIAGNOSTIC
if (fragsreleased > dbtofrags(fs, ip->i_ffs_blocks)) {
@ -506,10 +509,10 @@ lfs_vinvalbuf(vp, cred, p, maxblk)
else /* i == 1 */
blist = vp->v_dirtyblkhd.lh_first;
s = splbio();
for (bp = blist; bp; bp = nbp) {
nbp = bp->b_vnbufs.le_next;
s = splbio();
if (bp->b_flags & B_GATHERED) {
error = tsleep(vp, PRIBIO+1, "lfs_vin2", 0);
splx(s);
@ -521,14 +524,14 @@ lfs_vinvalbuf(vp, cred, p, maxblk)
bp->b_flags |= B_WANTED;
error = tsleep((caddr_t)bp,
(PRIBIO + 1), "lfs_vinval", 0);
splx(s);
if (error)
if (error) {
splx(s);
return (error);
}
goto top;
}
bp->b_flags |= B_BUSY;
splx(s);
if((bp->b_lblkno >= 0 && bp->b_lblkno > maxblk)
|| (bp->b_lblkno < 0 && bp->b_lblkno < -maxblk-(NIADDR-1)))
{
@ -551,6 +554,7 @@ lfs_vinvalbuf(vp, cred, p, maxblk)
}
}
}
splx(s);
}
if(dirty)
goto top;

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_syscalls.c,v 1.36 1999/11/21 19:25:31 perseant Exp $ */
/* $NetBSD: lfs_syscalls.c,v 1.37 1999/11/23 23:52:42 fvdl Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -475,10 +475,10 @@ sys_lfs_markv(p, v, retval)
lfs_vunref(vp);
/* Free up fakebuffers -- have to take these from the LOCKED list */
again:
s = splbio();
for(bp = bufqueues[BQ_LOCKED].tqh_first; bp; bp=nbp) {
nbp = bp->b_freelist.tqe_next;
if(bp->b_flags & B_CALL) {
s = splbio();
if(bp->b_flags & B_BUSY) { /* not bloody likely */
bp->b_flags |= B_WANTED;
tsleep(bp, PRIBIO+1, "markv", 0);
@ -488,8 +488,10 @@ sys_lfs_markv(p, v, retval)
bremfree(bp);
splx(s);
brelse(bp);
s = splbio();
}
}
splx(s);
free(start, M_SEGMENT);
lfs_segunlock(fs);
vfs_unbusy(mntp);