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:
parent
f56c15f914
commit
d901f6eae0
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue