From 67812eacd74d5841e890b703d4ec2d5a76288830 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sat, 26 Jun 1999 02:47:16 +0000 Subject: [PATCH] Convert buffer locking from using the B_BUSY and B_WANTED flags to using lockmgr locks. This commit should be functionally equivalent to the old semantics. That is, all buffer locking is done with LK_EXCLUSIVE requests. Changes to take advantage of LK_SHARED and LK_RECURSIVE will be done in future commits. --- contrib/sys/softupdates/ffs_softdep.c | 22 +++--- sys/alpha/alpha/diskslice_machdep.c | 6 +- sys/cam/cam_periph.c | 6 +- sys/contrib/softupdates/ffs_softdep.c | 22 +++--- sys/dev/fdc/fdc.c | 8 +- sys/dev/vinum/vinumio.c | 6 +- sys/dev/vinum/vinumrequest.c | 7 +- sys/dev/vinum/vinumrevive.c | 6 +- sys/fs/msdosfs/msdosfs_vnops.c | 5 +- sys/fs/specfs/spec_vnops.c | 10 +-- sys/gnu/ext2fs/ext2_vnops.c | 3 +- sys/gnu/ext2fs/fs.h | 2 +- sys/gnu/fs/ext2fs/ext2_vnops.c | 3 +- sys/gnu/fs/ext2fs/fs.h | 2 +- sys/i386/isa/diskslice_machdep.c | 6 +- sys/isa/fd.c | 8 +- sys/kern/kern_lock.c | 20 ++++- sys/kern/kern_physio.c | 28 +++---- sys/kern/kern_shutdown.c | 19 ++--- sys/kern/subr_disklabel.c | 10 +-- sys/kern/subr_diskmbr.c | 6 +- sys/kern/subr_dkbad.c | 4 +- sys/kern/vfs_aio.c | 4 +- sys/kern/vfs_bio.c | 109 ++++++++++++++------------ sys/kern/vfs_cluster.c | 35 ++++----- sys/kern/vfs_export.c | 51 ++++++------ sys/kern/vfs_subr.c | 51 ++++++------ sys/miscfs/devfs/devfs_vnops.c | 8 +- sys/miscfs/specfs/spec_vnops.c | 10 +-- sys/msdosfs/msdosfs_vnops.c | 5 +- sys/nfs/nfs_bio.c | 3 +- sys/nfs/nfs_common.c | 5 +- sys/nfs/nfs_subs.c | 5 +- sys/nfs/nfs_vnops.c | 50 ++++++------ sys/nfsclient/nfs_bio.c | 3 +- sys/nfsclient/nfs_subs.c | 5 +- sys/nfsclient/nfs_vnops.c | 50 ++++++------ sys/nfsserver/nfs_srvsubs.c | 5 +- sys/pc98/cbus/fdc.c | 8 +- sys/pc98/pc98/atcompat_diskslice.c | 6 +- sys/pc98/pc98/diskslice_machdep.c | 6 +- sys/pc98/pc98/fd.c | 8 +- sys/sys/bio.h | 90 +++++++++++++++++++-- sys/sys/buf.h | 90 +++++++++++++++++++-- sys/sys/lock.h | 3 +- sys/sys/lockmgr.h | 3 +- sys/ufs/ffs/ffs_softdep.c | 22 +++--- sys/ufs/ffs/ffs_vnops.c | 13 +-- sys/ufs/mfs/mfs_vnops.c | 5 +- sys/ufs/ufs/ufs_disksubr.c | 10 +-- sys/vm/swap_pager.c | 9 ++- sys/vm/vm_pager.c | 21 ++--- sys/vm/vm_swap.c | 4 +- sys/vm/vnode_pager.c | 6 +- 54 files changed, 563 insertions(+), 349 deletions(-) diff --git a/contrib/sys/softupdates/ffs_softdep.c b/contrib/sys/softupdates/ffs_softdep.c index df2791f99d42..eaaa2eca159b 100644 --- a/contrib/sys/softupdates/ffs_softdep.c +++ b/contrib/sys/softupdates/ffs_softdep.c @@ -53,7 +53,7 @@ * SUCH DAMAGE. * * from: @(#)ffs_softdep.c 9.40 (McKusick) 6/15/99 - * $Id: ffs_softdep.c,v 1.30 1999/06/15 23:37:29 mckusick Exp $ + * $Id: ffs_softdep.c,v 1.31 1999/06/16 23:27:55 mckusick Exp $ */ /* @@ -1530,6 +1530,8 @@ setup_allocindir_phase2(bp, ip, aip) } newindirdep->ir_savebp = getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); + newindirdep->ir_savebp->b_flags |= B_ASYNC; + BUF_KERNPROC(newindirdep->ir_savebp); bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } } @@ -3698,7 +3700,7 @@ softdep_fsync_mountdev(vp) /* * If it is already scheduled, skip to the next buffer. */ - if (bp->b_flags & B_BUSY) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("softdep_fsync_mountdev: not dirty"); @@ -3707,10 +3709,11 @@ softdep_fsync_mountdev(vp) * dependencies. */ if ((wk = LIST_FIRST(&bp->b_dep)) == NULL || - wk->wk_type != D_BMSAFEMAP) + wk->wk_type != D_BMSAFEMAP) { + BUF_UNLOCK(bp); continue; + } bremfree(bp); - bp->b_flags |= B_BUSY; FREE_LOCK(&lk); (void) bawrite(bp); ACQUIRE_LOCK(&lk); @@ -4414,19 +4417,20 @@ getdirtybuf(bpp, waitfor) for (;;) { if ((bp = *bpp) == NULL) return (0); - if ((bp->b_flags & B_BUSY) == 0) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) break; if (waitfor != MNT_WAIT) return (0); - bp->b_flags |= B_WANTED; FREE_LOCK_INTERLOCKED(&lk); - tsleep((caddr_t)bp, PRIBIO + 1, "sdsdty", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL) != ENOLCK) + panic("getdirtybuf: inconsistent lock"); ACQUIRE_LOCK_INTERLOCKED(&lk); } - if ((bp->b_flags & B_DELWRI) == 0) + if ((bp->b_flags & B_DELWRI) == 0) { + BUF_UNLOCK(bp); return (0); + } bremfree(bp); - bp->b_flags |= B_BUSY; return (1); } diff --git a/sys/alpha/alpha/diskslice_machdep.c b/sys/alpha/alpha/diskslice_machdep.c index 43103673d760..e5a27ee6a390 100644 --- a/sys/alpha/alpha/diskslice_machdep.c +++ b/sys/alpha/alpha/diskslice_machdep.c @@ -36,7 +36,7 @@ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ * from: i386/isa Id: diskslice_machdep.c,v 1.31 1998/08/10 07:22:14 phk Exp - * $Id: diskslice_machdep.c,v 1.7 1999/05/10 16:00:01 peter Exp $ + * $Id: diskslice_machdep.c,v 1.8 1999/05/14 00:41:02 msmith Exp $ */ #include @@ -183,7 +183,7 @@ dsinit(dname, dev, strat, lp, sspp) bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); bp->b_blkno = mbr_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading primary partition table", @@ -381,7 +381,7 @@ extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset, bp->b_dev = dev; bp->b_blkno = ext_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading extended partition table", diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index b14bea78da02..6b6e0b4ded12 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_periph.c,v 1.16 1999/05/25 17:10:04 ken Exp $ + * $Id: cam_periph.c,v 1.17 1999/05/25 20:17:28 gibbs Exp $ */ #include @@ -612,7 +612,7 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) mapinfo->bp[i]->b_bufsize = lengths[i]; /* set the flags */ - mapinfo->bp[i]->b_flags = flags[i] | B_PHYS | B_BUSY; + mapinfo->bp[i]->b_flags = flags[i] | B_PHYS; /* map the buffer into kernel memory */ vmapbuf(mapinfo->bp[i]); @@ -673,7 +673,7 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) vunmapbuf(mapinfo->bp[i]); /* clear the flags we set above */ - mapinfo->bp[i]->b_flags &= ~(B_PHYS|B_BUSY); + mapinfo->bp[i]->b_flags &= ~B_PHYS; /* release the buffer */ relpbuf(mapinfo->bp[i], NULL); diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c index df2791f99d42..eaaa2eca159b 100644 --- a/sys/contrib/softupdates/ffs_softdep.c +++ b/sys/contrib/softupdates/ffs_softdep.c @@ -53,7 +53,7 @@ * SUCH DAMAGE. * * from: @(#)ffs_softdep.c 9.40 (McKusick) 6/15/99 - * $Id: ffs_softdep.c,v 1.30 1999/06/15 23:37:29 mckusick Exp $ + * $Id: ffs_softdep.c,v 1.31 1999/06/16 23:27:55 mckusick Exp $ */ /* @@ -1530,6 +1530,8 @@ setup_allocindir_phase2(bp, ip, aip) } newindirdep->ir_savebp = getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); + newindirdep->ir_savebp->b_flags |= B_ASYNC; + BUF_KERNPROC(newindirdep->ir_savebp); bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } } @@ -3698,7 +3700,7 @@ softdep_fsync_mountdev(vp) /* * If it is already scheduled, skip to the next buffer. */ - if (bp->b_flags & B_BUSY) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("softdep_fsync_mountdev: not dirty"); @@ -3707,10 +3709,11 @@ softdep_fsync_mountdev(vp) * dependencies. */ if ((wk = LIST_FIRST(&bp->b_dep)) == NULL || - wk->wk_type != D_BMSAFEMAP) + wk->wk_type != D_BMSAFEMAP) { + BUF_UNLOCK(bp); continue; + } bremfree(bp); - bp->b_flags |= B_BUSY; FREE_LOCK(&lk); (void) bawrite(bp); ACQUIRE_LOCK(&lk); @@ -4414,19 +4417,20 @@ getdirtybuf(bpp, waitfor) for (;;) { if ((bp = *bpp) == NULL) return (0); - if ((bp->b_flags & B_BUSY) == 0) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) break; if (waitfor != MNT_WAIT) return (0); - bp->b_flags |= B_WANTED; FREE_LOCK_INTERLOCKED(&lk); - tsleep((caddr_t)bp, PRIBIO + 1, "sdsdty", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL) != ENOLCK) + panic("getdirtybuf: inconsistent lock"); ACQUIRE_LOCK_INTERLOCKED(&lk); } - if ((bp->b_flags & B_DELWRI) == 0) + if ((bp->b_flags & B_DELWRI) == 0) { + BUF_UNLOCK(bp); return (0); + } bremfree(bp); - bp->b_flags |= B_BUSY; return (1); } diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 77ebb365aa4b..36e55244eb0b 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -47,7 +47,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.145 1999/05/30 16:52:12 phk Exp $ + * $Id: fd.c,v 1.146 1999/05/31 18:39:16 dfr Exp $ * */ @@ -2196,7 +2196,9 @@ fdformat(dev, finfo, p) */ PHOLD(p); bzero((void *)bp, sizeof(struct buf)); - bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; + BUF_LOCKINIT(bp); + BUF_LOCK(bp, LK_EXCLUSIVE); + bp->b_flags = B_PHYS | B_FORMAT; /* * calculate a fake blkno, so fdstrategy() would initiate a @@ -2232,6 +2234,8 @@ fdformat(dev, finfo, p) * allow the process to be swapped */ PRELE(p); + BUF_UNLOCK(bp); + BUF_LOCKFREE(bp); free(bp, M_TEMP); return rv; } diff --git a/sys/dev/vinum/vinumio.c b/sys/dev/vinum/vinumio.c index 720affb4fe95..ef2658de0554 100644 --- a/sys/dev/vinum/vinumio.c +++ b/sys/dev/vinum/vinumio.c @@ -33,7 +33,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: vinumio.c,v 1.24 1999/03/23 02:00:52 grog Exp grog $ + * $Id: vinumio.c,v 1.29 1999/06/24 08:55:02 grog Exp $ */ #include @@ -272,7 +272,7 @@ driveio(struct drive *drive, char *buf, size_t length, off_t offset, int flag) int len = min(length, MAXBSIZE); /* maximum block device transfer is MAXBSIZE */ bp = geteblk(len); /* get a buffer header */ - bp->b_flags = B_BUSY | flag; /* get busy */ + bp->b_flags = flag; /* get locked */ bp->b_dev = drive->vp->v_un.vu_specinfo->si_rdev; /* device */ bp->b_blkno = offset / drive->partinfo.disklab->d_secsize; /* block number */ bp->b_data = buf; @@ -907,7 +907,7 @@ write_volume_label(int volno) dlp = (struct disklabel *) bp->b_data; *dlp = *lp; bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_WRITE; + bp->b_flags |= B_WRITE; vinumstrategy(bp); /* write it out */ error = biowait(bp); bp->b_flags |= B_INVAL | B_AGE; diff --git a/sys/dev/vinum/vinumrequest.c b/sys/dev/vinum/vinumrequest.c index a6fd555f0303..c81a4ca090ad 100644 --- a/sys/dev/vinum/vinumrequest.c +++ b/sys/dev/vinum/vinumrequest.c @@ -33,7 +33,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: vinumrequest.c,v 1.23 1999/03/20 21:58:38 grog Exp grog $ + * $Id: vinumrequest.c,v 1.26 1999/06/24 08:56:03 grog Exp $ */ #include @@ -725,7 +725,7 @@ build_rq_buffer(struct rqelement *rqe, struct plex *plex) /* Initialize the buf struct */ bp->b_flags = ubp->b_flags & (B_NOCACHE | B_READ | B_ASYNC); /* copy these flags from user bp */ - bp->b_flags |= B_CALL | B_BUSY; /* inform us when it's done */ + bp->b_flags |= B_CALL; /* inform us when it's done */ /* * XXX Should we check for reviving plexes here, and * set B_ORDERED if so? @@ -811,8 +811,7 @@ sdio(struct buf *bp) if (sd->state < sd_empty) { /* nothing to talk to, */ bp->b_flags |= B_ERROR; bp->b_flags = EIO; - if (bp->b_flags & B_BUSY) /* XXX why isn't this always the case? */ - biodone(bp); + biodone(bp); return; } /* Get a buffer */ diff --git a/sys/dev/vinum/vinumrevive.c b/sys/dev/vinum/vinumrevive.c index a78baee0446d..25c0ff8b6bf9 100644 --- a/sys/dev/vinum/vinumrevive.c +++ b/sys/dev/vinum/vinumrevive.c @@ -33,7 +33,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: vinumrevive.c,v 1.7 1999/02/28 02:12:18 grog Exp grog $ + * $Id: vinumrevive.c,v 1.12 1999/05/15 05:49:21 grog Exp $ */ #include @@ -130,7 +130,7 @@ revive_block(int sdno) else /* it's an unattached plex */ bp->b_dev = VINUMRBDEV(sd->plexno, VINUM_RAWPLEX_TYPE); /* create the device number */ - bp->b_flags = B_BUSY | B_READ; /* either way, read it */ + bp->b_flags = B_READ; /* either way, read it */ vinumstart(bp, 1); biowait(bp); } @@ -145,7 +145,7 @@ revive_block(int sdno) splx(s); bp->b_dev = VINUMRBDEV(sdno, VINUM_RAWSD_TYPE); /* create the device number */ - bp->b_flags = B_BUSY | B_ORDERED; /* and make this an ordered write */ + bp->b_flags = B_ORDERED; /* and make this an ordered write */ bp->b_resid = 0x0; bp->b_blkno = sd->revived; /* write it to here */ sdio(bp); /* perform the I/O */ diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 036ad2f2572d..98e301ecd490 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_vnops.c,v 1.84 1999/05/06 18:12:51 peter Exp $ */ +/* $Id: msdosfs_vnops.c,v 1.85 1999/05/11 19:54:43 phk Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ /*- @@ -842,12 +842,11 @@ msdosfs_fsync(ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("msdosfs_fsync: not dirty"); bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); (void) bwrite(bp); goto loop; diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c index dd4a27902aa9..9a467fdc4338 100644 --- a/sys/fs/specfs/spec_vnops.c +++ b/sys/fs/specfs/spec_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95 - * $Id: spec_vnops.c,v 1.87 1999/05/31 11:27:56 phk Exp $ + * $Id: spec_vnops.c,v 1.88 1999/06/01 20:29:58 dt Exp $ */ #include @@ -492,16 +492,16 @@ spec_fsync(ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("spec_fsync: not dirty"); if ((vp->v_flag & VOBJBUF) && (bp->b_flags & B_CLUSTEROK)) { + BUF_UNLOCK(bp); vfs_bio_awrite(bp); splx(s); } else { bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); bawrite(bp); } @@ -570,7 +570,7 @@ spec_freeblks(ap) if ((bsw->d_flags & D_CANFREE) == 0) return (0); bp = geteblk(ap->a_length); - bp->b_flags |= B_FREEBUF | B_BUSY; + bp->b_flags |= B_FREEBUF; bp->b_dev = ap->a_vp->v_rdev; bp->b_blkno = ap->a_addr; bp->b_offset = dbtob(ap->a_addr); @@ -806,7 +806,7 @@ spec_getpages(ap) pmap_qenter(kva, ap->a_m, pcount); /* Build a minimal buffer header. */ - bp->b_flags = B_BUSY | B_READ | B_CALL; + bp->b_flags = B_READ | B_CALL; bp->b_iodone = spec_getpages_iodone; /* B_PHYS is not set, but it is nice to fill this in. */ diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c index c3b1263830f3..82eedd8996cf 100644 --- a/sys/gnu/ext2fs/ext2_vnops.c +++ b/sys/gnu/ext2fs/ext2_vnops.c @@ -198,12 +198,11 @@ ext2_fsync(ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("ext2_fsync: not dirty"); bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); /* * Wait for I/O associated with indirect blocks to complete, diff --git a/sys/gnu/ext2fs/fs.h b/sys/gnu/ext2fs/fs.h index 17b5beb7fa16..b8dab54606ae 100644 --- a/sys/gnu/ext2fs/fs.h +++ b/sys/gnu/ext2fs/fs.h @@ -173,8 +173,8 @@ extern u_char *fragtbl[]; s = splbio(); \ flags = (bp)->b_flags; \ (bp)->b_flags &= ~(B_DIRTY | B_LOCKED); \ + BUF_LOCK(bp, LK_EXCLUSIVE); \ bremfree(bp); \ - (bp)->b_flags |= B_BUSY; \ splx(s); \ if (flags & B_DIRTY) \ bdwrite(bp); \ diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c index c3b1263830f3..82eedd8996cf 100644 --- a/sys/gnu/fs/ext2fs/ext2_vnops.c +++ b/sys/gnu/fs/ext2fs/ext2_vnops.c @@ -198,12 +198,11 @@ ext2_fsync(ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("ext2_fsync: not dirty"); bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); /* * Wait for I/O associated with indirect blocks to complete, diff --git a/sys/gnu/fs/ext2fs/fs.h b/sys/gnu/fs/ext2fs/fs.h index 17b5beb7fa16..b8dab54606ae 100644 --- a/sys/gnu/fs/ext2fs/fs.h +++ b/sys/gnu/fs/ext2fs/fs.h @@ -173,8 +173,8 @@ extern u_char *fragtbl[]; s = splbio(); \ flags = (bp)->b_flags; \ (bp)->b_flags &= ~(B_DIRTY | B_LOCKED); \ + BUF_LOCK(bp, LK_EXCLUSIVE); \ bremfree(bp); \ - (bp)->b_flags |= B_BUSY; \ splx(s); \ if (flags & B_DIRTY) \ bdwrite(bp); \ diff --git a/sys/i386/isa/diskslice_machdep.c b/sys/i386/isa/diskslice_machdep.c index c05e66bd83c4..a7b6b244549b 100644 --- a/sys/i386/isa/diskslice_machdep.c +++ b/sys/i386/isa/diskslice_machdep.c @@ -35,7 +35,7 @@ * * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ - * $Id: diskslice_machdep.c,v 1.33 1999/01/28 01:59:53 dillon Exp $ + * $Id: diskslice_machdep.c,v 1.34 1999/05/11 19:54:10 phk Exp $ */ #include @@ -181,7 +181,7 @@ dsinit(dname, dev, strat, lp, sspp) bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); bp->b_blkno = mbr_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading primary partition table", @@ -371,7 +371,7 @@ extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset, bp->b_dev = dev; bp->b_blkno = ext_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading extended partition table", diff --git a/sys/isa/fd.c b/sys/isa/fd.c index 77ebb365aa4b..36e55244eb0b 100644 --- a/sys/isa/fd.c +++ b/sys/isa/fd.c @@ -47,7 +47,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.145 1999/05/30 16:52:12 phk Exp $ + * $Id: fd.c,v 1.146 1999/05/31 18:39:16 dfr Exp $ * */ @@ -2196,7 +2196,9 @@ fdformat(dev, finfo, p) */ PHOLD(p); bzero((void *)bp, sizeof(struct buf)); - bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; + BUF_LOCKINIT(bp); + BUF_LOCK(bp, LK_EXCLUSIVE); + bp->b_flags = B_PHYS | B_FORMAT; /* * calculate a fake blkno, so fdstrategy() would initiate a @@ -2232,6 +2234,8 @@ fdformat(dev, finfo, p) * allow the process to be swapped */ PRELE(p); + BUF_UNLOCK(bp); + BUF_LOCKFREE(bp); free(bp, M_TEMP); return rv; } diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 3dde4b8c03e0..c7e9c84350e4 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -38,7 +38,7 @@ * SUCH DAMAGE. * * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95 - * $Id: kern_lock.c,v 1.24 1999/03/12 03:09:29 julian Exp $ + * $Id: kern_lock.c,v 1.25 1999/03/15 05:11:27 julian Exp $ */ #include "opt_lint.h" @@ -384,7 +384,8 @@ debuglockmgr(lkp, flags, interlkp, p, name, file, line) case LK_RELEASE: if (lkp->lk_exclusivecount != 0) { #if !defined(MAX_PERF) - if (pid != lkp->lk_lockholder) + if (lkp->lk_lockholder != pid && + lkp->lk_lockholder != LK_KERNPROC) panic("lockmgr: pid %d, not %s %d unlocking", pid, "exclusive lock holder", lkp->lk_lockholder); @@ -517,6 +518,21 @@ lockstatus(lkp) return (lock_type); } +/* + * Determine the number of holders of a lock. + */ +int +lockcount(lkp) + struct lock *lkp; +{ + int count; + + simple_lock(&lkp->lk_interlock); + count = lkp->lk_exclusivecount + lkp->lk_sharecount; + simple_unlock(&lkp->lk_interlock); + return (count); +} + /* * Print out information about state of a lock. Used by VOP_PRINT * routines to display status about contained locks. diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c index 5f685b56ec58..2208319d3e30 100644 --- a/sys/kern/kern_physio.c +++ b/sys/kern/kern_physio.c @@ -16,7 +16,7 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: kern_physio.c,v 1.33 1999/05/07 07:03:39 phk Exp $ + * $Id: kern_physio.c,v 1.34 1999/05/08 06:39:37 phk Exp $ */ #include @@ -68,17 +68,10 @@ physio(strategy, bp, dev, rw, minp, uio) /* create and build a buffer header for a transfer */ bpa = (struct buf *)phygetvpbuf(dev, uio->uio_resid); - if (!bp_alloc) { - spl = splbio(); - while (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep((caddr_t)bp, PRIBIO, "physbw", 0); - } - bp->b_flags |= B_BUSY; - splx(spl); - } else { + if (!bp_alloc) + BUF_LOCK(bp, LK_EXCLUSIVE); + else bp = bpa; - } /* * get a copy of the kva from the physical buffer @@ -86,12 +79,12 @@ physio(strategy, bp, dev, rw, minp, uio) sa = bpa->b_data; error = bp->b_error = 0; - for(i=0;iuio_iovcnt;i++) { - while( uio->uio_iov[i].iov_len) { + for (i = 0; i < uio->uio_iovcnt; i++) { + while (uio->uio_iov[i].iov_len) { bp->b_dev = dev; bp->b_bcount = uio->uio_iov[i].iov_len; - bp->b_flags = B_BUSY | B_PHYS | B_CALL | bufflags; + bp->b_flags = B_PHYS | B_CALL | bufflags; bp->b_iodone = physwakeup; bp->b_data = uio->uio_iov[i].iov_base; bp->b_bcount = minp( bp); @@ -160,11 +153,8 @@ physio(strategy, bp, dev, rw, minp, uio) doerror: relpbuf(bpa, NULL); if (!bp_alloc) { - bp->b_flags &= ~(B_BUSY|B_PHYS); - if( bp->b_flags & B_WANTED) { - bp->b_flags &= ~B_WANTED; - wakeup((caddr_t)bp); - } + bp->b_flags &= ~B_PHYS; + BUF_UNLOCK(bp); } /* * Allow the process UPAGES to be swapped again. diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index e01b815c296f..52c3f291822e 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94 - * $Id: kern_shutdown.c,v 1.51 1999/05/08 06:39:38 phk Exp $ + * $Id: kern_shutdown.c,v 1.52 1999/05/12 22:30:46 peter Exp $ */ #include "opt_ddb.h" @@ -212,8 +212,8 @@ boot(howto) for (iter = 0; iter < 20; iter++) { nbusy = 0; for (bp = &buf[nbuf]; --bp >= buf; ) { - if ((bp->b_flags & (B_BUSY | B_INVAL)) - == B_BUSY) { + if ((bp->b_flags & B_INVAL) == 0 && + BUF_REFCNT(bp) > 0) { nbusy++; } else if ((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI) { @@ -233,10 +233,11 @@ boot(howto) */ nbusy = 0; for (bp = &buf[nbuf]; --bp >= buf; ) { - if (((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) || - ((bp->b_flags & (B_DELWRI | B_INVAL))== B_DELWRI)) { - if(bp->b_dev == NODEV) - CIRCLEQ_REMOVE(&mountlist, bp->b_vp->v_mount, mnt_list); + if (((bp->b_flags&B_INVAL) == 0 && BUF_REFCNT(bp)) || + ((bp->b_flags & (B_DELWRI|B_INVAL)) == B_DELWRI)) { + if (bp->b_dev == NODEV) + CIRCLEQ_REMOVE(&mountlist, + bp->b_vp->v_mount, mnt_list); else nbusy++; } @@ -252,8 +253,8 @@ boot(howto) #ifdef SHOW_BUSYBUFS nbusy = 0; for (bp = &buf[nbuf]; --bp >= buf; ) { - if ((bp->b_flags & (B_BUSY | B_INVAL)) - == B_BUSY) { + if ((bp->b_flags & B_INVAL) == 0 && + BUF_REFCNT(bp) > 0) { nbusy++; printf( "%d: dev:%08lx, flags:%08lx, blkno:%ld, lblkno:%ld\n", diff --git a/sys/kern/subr_disklabel.c b/sys/kern/subr_disklabel.c index 33f1d2ac1b68..21088cb7f67d 100644 --- a/sys/kern/subr_disklabel.c +++ b/sys/kern/subr_disklabel.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94 - * $Id: ufs_disksubr.c,v 1.38 1998/10/17 07:49:04 bde Exp $ + * $Id: ufs_disksubr.c,v 1.39 1998/12/14 05:37:37 dillon Exp $ */ #include @@ -182,7 +182,7 @@ readdisklabel(dev, strat, lp) bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE); bp->b_bcount = lp->d_secsize; bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp)) msg = "I/O error"; @@ -286,7 +286,7 @@ writedisklabel(dev, strat, lp) * (also stupid.. how do you write the first one? by raw writes?) */ bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); error = biowait(bp); if (error) @@ -299,7 +299,7 @@ writedisklabel(dev, strat, lp) dkcksum(dlp) == 0) { *dlp = *lp; bp->b_flags &= ~(B_DONE | B_READ); - bp->b_flags |= B_BUSY | B_WRITE; + bp->b_flags |= B_WRITE; #ifdef __alpha__ alpha_fix_srm_checksum(bp); #endif @@ -315,7 +315,7 @@ writedisklabel(dev, strat, lp) dlp = (struct disklabel *)bp->b_data; *dlp = *lp; bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_WRITE; + bp->b_flags |= B_WRITE; (*strat)(bp); error = biowait(bp); #endif diff --git a/sys/kern/subr_diskmbr.c b/sys/kern/subr_diskmbr.c index c05e66bd83c4..a7b6b244549b 100644 --- a/sys/kern/subr_diskmbr.c +++ b/sys/kern/subr_diskmbr.c @@ -35,7 +35,7 @@ * * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ - * $Id: diskslice_machdep.c,v 1.33 1999/01/28 01:59:53 dillon Exp $ + * $Id: diskslice_machdep.c,v 1.34 1999/05/11 19:54:10 phk Exp $ */ #include @@ -181,7 +181,7 @@ dsinit(dname, dev, strat, lp, sspp) bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); bp->b_blkno = mbr_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading primary partition table", @@ -371,7 +371,7 @@ extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset, bp->b_dev = dev; bp->b_blkno = ext_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading extended partition table", diff --git a/sys/kern/subr_dkbad.c b/sys/kern/subr_dkbad.c index c020254c8420..bbb18ddb2441 100644 --- a/sys/kern/subr_dkbad.c +++ b/sys/kern/subr_dkbad.c @@ -43,7 +43,7 @@ * from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ - * $Id: subr_dkbad.c,v 1.8 1997/12/02 21:06:43 phk Exp $ + * $Id: subr_dkbad.c,v 1.9 1999/05/11 19:54:31 phk Exp $ */ #include @@ -118,7 +118,7 @@ readbad144(dev, strat, lp, bdp) else bp->b_blkno /= DEV_BSIZE / lp->d_secsize; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; bp->b_flags &= ~B_ERROR; (*strat)(bp); diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 04d9de4cac22..f5f9a20bc734 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -13,7 +13,7 @@ * bad that happens because of using this software isn't the responsibility * of the author. This software is distributed AS-IS. * - * $Id: vfs_aio.c,v 1.50 1999/05/09 13:13:52 phk Exp $ + * $Id: vfs_aio.c,v 1.51 1999/06/01 18:56:24 phk Exp $ */ /* @@ -1017,7 +1017,7 @@ aio_qphysio(p, aiocbe) bp->b_bcount = cb->aio_nbytes; bp->b_bufsize = cb->aio_nbytes; - bp->b_flags = B_BUSY | B_PHYS | B_CALL | bflags; + bp->b_flags = B_PHYS | B_CALL | bflags; bp->b_iodone = aio_physwakeup; bp->b_saveaddr = bp->b_data; bp->b_data = (void *) cb->aio_buf; diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 4a7c2e420dd1..48f2c38a0e16 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -11,7 +11,7 @@ * 2. Absolutely no warranty of function or purpose is made by the author * John S. Dyson. * - * $Id: vfs_bio.c,v 1.214 1999/06/16 23:27:31 mckusick Exp $ + * $Id: vfs_bio.c,v 1.215 1999/06/22 01:39:53 mckusick Exp $ */ /* @@ -139,6 +139,7 @@ SYSCTL_INT(_vfs, OID_AUTO, kvafreespace, CTLFLAG_RD, static LIST_HEAD(bufhashhdr, buf) bufhashtbl[BUFHSZ], invalhash; struct bqueues bufqueues[BUFFER_QUEUES] = { { 0 } }; +char *buf_wmesg = BUF_WMESG; extern int vm_swap_size; @@ -250,6 +251,7 @@ bufinit() TAILQ_INIT(&bswlist); LIST_INIT(&invalhash); + simple_lock_init(&buftimelock); /* first, make a null hash table */ for (i = 0; i < BUFHSZ; i++) @@ -270,6 +272,7 @@ bufinit() bp->b_qindex = QUEUE_EMPTY; bp->b_xflags = 0; LIST_INIT(&bp->b_dep); + BUF_LOCKINIT(bp); TAILQ_INSERT_TAIL(&bufqueues[QUEUE_EMPTY], bp, b_freelist); LIST_INSERT_HEAD(&invalhash, bp, b_hash); } @@ -359,7 +362,14 @@ bremfree(struct buf * bp) if (bp->b_qindex == QUEUE_EMPTY) { kvafreespace -= bp->b_kvasize; } - TAILQ_REMOVE(&bufqueues[bp->b_qindex], bp, b_freelist); + if (BUF_REFCNT(bp) == 1) + TAILQ_REMOVE(&bufqueues[bp->b_qindex], bp, b_freelist); + else if (BUF_REFCNT(bp) == 0) + panic("bremfree: not locked"); + else + /* Temporary panic to verify exclusive locking */ + /* This panic goes away when we allow shared refs */ + panic("bremfree: multiple refs"); bp->b_qindex = QUEUE_NONE; runningbufspace += bp->b_bufsize; } else { @@ -471,6 +481,7 @@ breadn(struct vnode * vp, daddr_t blkno, int size, rabp->b_rcred = cred; } vfs_busy_pages(rabp, 0); + BUF_KERNPROC(bp); VOP_STRATEGY(vp, rabp); } else { brelse(rabp); @@ -509,7 +520,7 @@ bwrite(struct buf * bp) oldflags = bp->b_flags; #if !defined(MAX_PERF) - if ((bp->b_flags & B_BUSY) == 0) + if (BUF_REFCNT(bp) == 0) panic("bwrite: buffer is not busy???"); #endif s = splbio(); @@ -523,6 +534,7 @@ bwrite(struct buf * bp) if (curproc != NULL) curproc->p_stats->p_ru.ru_oublock++; splx(s); + BUF_KERNPROC(bp); VOP_STRATEGY(bp->b_vp, bp); /* @@ -567,9 +579,8 @@ bdwrite(struct buf * bp) struct vnode *vp; #if !defined(MAX_PERF) - if ((bp->b_flags & B_BUSY) == 0) { + if (BUF_REFCNT(bp) == 0) panic("bdwrite: buffer is not busy"); - } #endif if (bp->b_flags & B_INVAL) { @@ -883,6 +894,16 @@ brelse(struct buf * bp) if (bp->b_qindex != QUEUE_NONE) panic("brelse: free buffer onto another queue???"); #endif + if (BUF_REFCNT(bp) > 1) { + /* Temporary panic to verify exclusive locking */ + /* This panic goes away when we allow shared refs */ + panic("brelse: multiple refs"); + /* do not release to free list */ + BUF_UNLOCK(bp); + splx(s); + return; + } + /* enqueue */ /* buffers with no memory */ @@ -948,14 +969,9 @@ brelse(struct buf * bp) if (bp->b_bufsize) bufspacewakeup(); - if (bp->b_flags & B_WANTED) { - bp->b_flags &= ~(B_WANTED | B_AGE); - wakeup(bp); - } - /* unlock */ - bp->b_flags &= ~(B_ORDERED | B_WANTED | B_BUSY | - B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); + BUF_UNLOCK(bp); + bp->b_flags &= ~(B_ORDERED | B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); splx(s); } @@ -981,6 +997,13 @@ bqrelse(struct buf * bp) if (bp->b_qindex != QUEUE_NONE) panic("bqrelse: free buffer onto another queue???"); #endif + if (BUF_REFCNT(bp) > 1) { + /* do not release to free list */ + panic("bqrelse: multiple refs"); + BUF_UNLOCK(bp); + splx(s); + return; + } if (bp->b_flags & B_LOCKED) { bp->b_flags &= ~B_ERROR; bp->b_qindex = QUEUE_LOCKED; @@ -1005,15 +1028,9 @@ bqrelse(struct buf * bp) if (bp->b_bufsize) bufspacewakeup(); - /* anyone need this block? */ - if (bp->b_flags & B_WANTED) { - bp->b_flags &= ~(B_WANTED | B_AGE); - wakeup(bp); - } - /* unlock */ - bp->b_flags &= ~(B_ORDERED | B_WANTED | B_BUSY | - B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); + BUF_UNLOCK(bp); + bp->b_flags &= ~(B_ORDERED | B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); splx(s); } @@ -1124,7 +1141,8 @@ vfs_bio_awrite(struct buf * bp) for (i = 1; i < maxcl; i++) { if ((bpa = gbincore(vp, lblkno + i)) && - ((bpa->b_flags & (B_BUSY | B_DELWRI | B_CLUSTEROK | B_INVAL)) == + BUF_REFCNT(bpa) == 0 && + ((bpa->b_flags & (B_DELWRI | B_CLUSTEROK | B_INVAL)) == (B_DELWRI | B_CLUSTEROK)) && (bpa->b_bufsize == size)) { if ((bpa->b_blkno == bpa->b_lblkno) || @@ -1145,8 +1163,9 @@ vfs_bio_awrite(struct buf * bp) } } + BUF_LOCK(bp, LK_EXCLUSIVE); bremfree(bp); - bp->b_flags |= B_BUSY | B_ASYNC; + bp->b_flags |= B_ASYNC; splx(s); /* @@ -1281,7 +1300,7 @@ getnewbuf(struct vnode *vp, daddr_t blkno, /* * Sanity Checks */ - KASSERT(!(bp->b_flags & B_BUSY), ("getnewbuf: busy buffer %p on free list", bp)); + KASSERT(BUF_REFCNT(bp) == 0, ("getnewbuf: busy buffer %p on free list", bp)); KASSERT(bp->b_qindex == qindex, ("getnewbuf: inconsistant queue %d bp %p", qindex, bp)); /* @@ -1374,8 +1393,9 @@ getnewbuf(struct vnode *vp, daddr_t blkno, * remains valid only for QUEUE_EMPTY bp's. */ + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) != 0) + panic("getnewbuf: locked buf"); bremfree(bp); - bp->b_flags |= B_BUSY; if (qindex == QUEUE_LRU || qindex == QUEUE_AGE) { if (bp->b_flags & B_VMIO) { @@ -1386,11 +1406,6 @@ getnewbuf(struct vnode *vp, daddr_t blkno, brelvp(bp); } - if (bp->b_flags & B_WANTED) { - bp->b_flags &= ~B_WANTED; - wakeup(bp); - } - /* * NOTE: nbp is now entirely invalid. We can only restart * the scan from this point on. @@ -1416,7 +1431,7 @@ getnewbuf(struct vnode *vp, daddr_t blkno, if (bp->b_bufsize) allocbuf(bp, 0); - bp->b_flags = B_BUSY; + bp->b_flags = 0; bp->b_dev = NODEV; bp->b_vp = NULL; bp->b_blkno = bp->b_lblkno = 0; @@ -1644,8 +1659,9 @@ flushbufqueues(void) */ if ((bp->b_flags & B_DELWRI) != 0) { if (bp->b_flags & B_INVAL) { + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) != 0) + panic("flushbufqueues: locked buf"); bremfree(bp); - bp->b_flags |= B_BUSY; brelse(bp); } else { vfs_bio_awrite(bp); @@ -1872,30 +1888,25 @@ getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo) * Buffer is in-core */ - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { if (bp->b_usecount < BUF_MAXUSE) ++bp->b_usecount; - - if (!tsleep(bp, - (PRIBIO + 4) | slpflag, "getblk", slptimeo)) { + if (BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL, + "getblk", slpflag, slptimeo) == ENOLCK) goto loop; - } - splx(s); return (struct buf *) NULL; } /* - * Busy the buffer. B_CACHE is cleared if the buffer is + * The buffer is locked. B_CACHE is cleared if the buffer is * invalid. Ohterwise, for a non-VMIO buffer, B_CACHE is set * and for a VMIO buffer B_CACHE is adjusted according to the * backing VM cache. */ - bp->b_flags |= B_BUSY; if (bp->b_flags & B_INVAL) bp->b_flags &= ~B_CACHE; - else if ((bp->b_flags & (B_VMIO|B_INVAL)) == 0) + else if ((bp->b_flags & (B_VMIO | B_INVAL)) == 0) bp->b_flags |= B_CACHE; bremfree(bp); @@ -1965,9 +1976,8 @@ getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo) } else { /* * Buffer is not in-core, create new buffer. The buffer - * returned by getnewbuf() is marked B_BUSY. Note that the - * returned buffer is also considered valid ( not marked - * B_INVAL ). + * returned by getnewbuf() is locked. Note that the returned + * buffer is also considered valid (not marked B_INVAL). */ int bsize, maxsize, vmio; off_t offset; @@ -2088,7 +2098,7 @@ allocbuf(struct buf *bp, int size) int i; #if !defined(MAX_PERF) - if (!(bp->b_flags & B_BUSY)) + if (BUF_REFCNT(bp) == 0) panic("allocbuf: buffer not busy"); if (bp->b_kvasize < size) @@ -2376,7 +2386,7 @@ allocbuf(struct buf *bp, int size) * biowait: * * Wait for buffer I/O completion, returning error status. The buffer - * is left B_BUSY|B_DONE on return. B_EINTR is converted into a EINTR + * is left locked and B_DONE on return. B_EINTR is converted into a EINTR * error and cleared. */ int @@ -2432,7 +2442,7 @@ biodone(register struct buf * bp) s = splbio(); - KASSERT((bp->b_flags & B_BUSY), ("biodone: bp %p not busy", bp)); + KASSERT(BUF_REFCNT(bp) > 0, ("biodone: bp %p not busy", bp)); KASSERT(!(bp->b_flags & B_DONE), ("biodone: bp %p already done", bp)); bp->b_flags |= B_DONE; @@ -2583,8 +2593,8 @@ biodone(register struct buf * bp) } /* * For asynchronous completions, release the buffer now. The brelse - * checks for B_WANTED and will do the wakeup there if necessary - so - * no need to do a wakeup here in the async case. + * will do a wakeup there if necessary - so no need to do a wakeup + * here in the async case. The sync case always needs to do a wakeup. */ if (bp->b_flags & B_ASYNC) { @@ -2593,7 +2603,6 @@ biodone(register struct buf * bp) else bqrelse(bp); } else { - bp->b_flags &= ~B_WANTED; wakeup(bp); } splx(s); diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index 3674516ceb5a..edbe37dc7339 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -33,7 +33,7 @@ * SUCH DAMAGE. * * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 - * $Id: vfs_cluster.c,v 1.82 1999/06/16 15:54:30 dg Exp $ + * $Id: vfs_cluster.c,v 1.83 1999/06/17 01:25:25 julian Exp $ */ #include "opt_debug_cluster.h" @@ -139,7 +139,7 @@ cluster_read(vp, filesize, lblkno, size, cred, totread, seqcount, bpp) * for efficiency. */ s = splbio(); - for(i=1;ib_flags |= B_RAM; if ((tbp->b_usecount < 1) && - ((tbp->b_flags & B_BUSY) == 0) && + BUF_REFCNT(tbp) == 0 && (tbp->b_qindex == QUEUE_LRU)) { TAILQ_REMOVE(&bufqueues[QUEUE_LRU], tbp, b_freelist); TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], tbp, b_freelist); @@ -252,6 +252,7 @@ cluster_read(vp, filesize, lblkno, size, cred, totread, seqcount, bpp) if ((bp->b_flags & B_CLUSTER) == 0) vfs_busy_pages(bp, 0); bp->b_flags &= ~(B_ERROR|B_INVAL); + BUF_KERNPROC(bp); error = VOP_STRATEGY(vp, bp); curproc->p_stats->p_ru.ru_inblock++; } @@ -285,6 +286,7 @@ cluster_read(vp, filesize, lblkno, size, cred, totread, seqcount, bpp) if ((rbp->b_flags & B_CLUSTER) == 0) vfs_busy_pages(rbp, 0); rbp->b_flags &= ~(B_ERROR|B_INVAL); + BUF_KERNPROC(rbp); (void) VOP_STRATEGY(vp, rbp); curproc->p_stats->p_ru.ru_inblock++; } @@ -346,7 +348,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) bp->b_data = (char *)((vm_offset_t)bp->b_data | ((vm_offset_t)tbp->b_data & PAGE_MASK)); - bp->b_flags = B_ASYNC | B_READ | B_CALL | B_BUSY | B_CLUSTER | B_VMIO; + bp->b_flags = B_ASYNC | B_READ | B_CALL | B_CLUSTER | B_VMIO; bp->b_iodone = cluster_callback; bp->b_blkno = blkno; bp->b_lblkno = lbn; @@ -370,8 +372,9 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) break; if ((tbp = incore(vp, lbn + i)) != NULL) { - if (tbp->b_flags & B_BUSY) + if (BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) break; + BUF_UNLOCK(tbp); for (j = 0; j < tbp->b_npages; j++) if (tbp->b_pages[j]->valid) @@ -638,14 +641,14 @@ cluster_wbuild(vp, size, start_lbn, len) while (len > 0) { s = splbio(); if (((tbp = gbincore(vp, start_lbn)) == NULL) || - ((tbp->b_flags & (B_INVAL|B_BUSY|B_DELWRI)) != B_DELWRI)) { + ((tbp->b_flags & (B_INVAL | B_DELWRI)) != B_DELWRI) || + BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) { ++start_lbn; --len; splx(s); continue; } bremfree(tbp); - tbp->b_flags |= B_BUSY; tbp->b_flags &= ~B_DONE; splx(s); @@ -687,7 +690,7 @@ cluster_wbuild(vp, size, start_lbn, len) bp->b_offset = tbp->b_offset; bp->b_data = (char *)((vm_offset_t)bp->b_data | ((vm_offset_t)tbp->b_data & PAGE_MASK)); - bp->b_flags |= B_CALL | B_BUSY | B_CLUSTER | + bp->b_flags |= B_CALL | B_CLUSTER | (tbp->b_flags & (B_VMIO | B_NEEDCOMMIT)); bp->b_iodone = cluster_callback; pbgetvp(vp, bp); @@ -712,16 +715,12 @@ cluster_wbuild(vp, size, start_lbn, len) * If it IS in core, but has different * characteristics, don't cluster with it. */ - if ((tbp->b_flags & - (B_VMIO | B_CLUSTEROK | B_INVAL | B_BUSY | - B_DELWRI | B_NEEDCOMMIT)) + if ((tbp->b_flags & (B_VMIO | B_CLUSTEROK | + B_INVAL | B_DELWRI | B_NEEDCOMMIT)) != (B_DELWRI | B_CLUSTEROK | - (bp->b_flags & (B_VMIO | B_NEEDCOMMIT)))) { - splx(s); - break; - } - - if (tbp->b_wcred != bp->b_wcred) { + (bp->b_flags & (B_VMIO | B_NEEDCOMMIT))) || + tbp->b_wcred != bp->b_wcred || + BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) { splx(s); break; } @@ -736,6 +735,7 @@ cluster_wbuild(vp, size, start_lbn, len) tbp->b_blkno) || ((tbp->b_npages + bp->b_npages) > (vp->v_maxio / PAGE_SIZE))) { + BUF_UNLOCK(tbp); splx(s); break; } @@ -745,7 +745,6 @@ cluster_wbuild(vp, size, start_lbn, len) * and mark it busy. We will use it. */ bremfree(tbp); - tbp->b_flags |= B_BUSY; tbp->b_flags &= ~B_DONE; splx(s); } /* end of code for non-first buffers only */ diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index bb8fa536c377..2a94962fd262 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.201 1999/06/15 23:37:25 mckusick Exp $ + * $Id: vfs_subr.c,v 1.202 1999/06/16 23:27:32 mckusick Exp $ */ /* @@ -128,9 +128,9 @@ static int syncer_maxdelay = SYNCER_MAXDELAY; /* maximum delay time */ time_t syncdelay = 30; /* max time to delay syncing data */ time_t filedelay = 30; /* time to delay syncing files */ SYSCTL_INT(_kern, OID_AUTO, filedelay, CTLFLAG_RW, &filedelay, 0, ""); -time_t dirdelay = 15; /* time to delay syncing directories */ +time_t dirdelay = 29; /* time to delay syncing directories */ SYSCTL_INT(_kern, OID_AUTO, dirdelay, CTLFLAG_RW, &dirdelay, 0, ""); -time_t metadelay = 10; /* time to delay syncing metadata */ +time_t metadelay = 28; /* time to delay syncing metadata */ SYSCTL_INT(_kern, OID_AUTO, metadelay, CTLFLAG_RW, &metadelay, 0, ""); static int rushjob; /* number of slots to run ASAP */ static int stat_rush_requests; /* number of times I/O speeded up */ @@ -622,16 +622,14 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) for (bp = blist; bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - error = tsleep((caddr_t) bp, - slpflag | (PRIBIO + 4), "vinvalbuf", - slptimeo); - if (error) { - splx(s); - return (error); - } - break; + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + error = BUF_TIMELOCK(bp, + LK_EXCLUSIVE | LK_SLEEPFAIL, + "vinvalbuf", slpflag, slptimeo); + if (error == ENOLCK) + break; + splx(s); + return (error); } /* * XXX Since there are no node locks for NFS, I @@ -646,21 +644,21 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) if (bp->b_vp == vp) { if (bp->b_flags & B_CLUSTEROK) { + BUF_UNLOCK(bp); vfs_bio_awrite(bp); } else { bremfree(bp); - bp->b_flags |= (B_BUSY | B_ASYNC); + bp->b_flags |= B_ASYNC; VOP_BWRITE(bp->b_vp, bp); } } else { bremfree(bp); - bp->b_flags |= B_BUSY; (void) VOP_BWRITE(bp->b_vp, bp); } break; } bremfree(bp); - bp->b_flags |= (B_INVAL | B_NOCACHE | B_RELBUF | B_BUSY); + bp->b_flags |= (B_INVAL | B_NOCACHE | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); } @@ -720,13 +718,12 @@ vtruncbuf(vp, cred, p, length, blksize) for (bp = TAILQ_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); if (bp->b_lblkno >= trunclbn) { - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep(bp, PRIBIO + 4, "vtrb1", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + BUF_LOCK(bp, LK_EXCLUSIVE|LK_SLEEPFAIL); goto restart; } else { bremfree(bp); - bp->b_flags |= (B_BUSY | B_INVAL | B_RELBUF); + bp->b_flags |= (B_INVAL | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); anyfreed = 1; @@ -742,13 +739,12 @@ vtruncbuf(vp, cred, p, length, blksize) for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); if (bp->b_lblkno >= trunclbn) { - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep(bp, PRIBIO + 4, "vtrb2", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + BUF_LOCK(bp, LK_EXCLUSIVE|LK_SLEEPFAIL); goto restart; } else { bremfree(bp); - bp->b_flags |= (B_BUSY | B_INVAL | B_RELBUF); + bp->b_flags |= (B_INVAL | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); anyfreed = 1; @@ -767,12 +763,11 @@ vtruncbuf(vp, cred, p, length, blksize) for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); if ((bp->b_flags & B_DELWRI) && (bp->b_lblkno < 0)) { - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep(bp, PRIBIO, "vtrb3", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + BUF_LOCK(bp, LK_EXCLUSIVE|LK_SLEEPFAIL); + goto restart; } else { bremfree(bp); - bp->b_flags |= B_BUSY; if (bp->b_vp == vp) { bp->b_flags |= B_ASYNC; } else { diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index bb8fa536c377..2a94962fd262 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.201 1999/06/15 23:37:25 mckusick Exp $ + * $Id: vfs_subr.c,v 1.202 1999/06/16 23:27:32 mckusick Exp $ */ /* @@ -128,9 +128,9 @@ static int syncer_maxdelay = SYNCER_MAXDELAY; /* maximum delay time */ time_t syncdelay = 30; /* max time to delay syncing data */ time_t filedelay = 30; /* time to delay syncing files */ SYSCTL_INT(_kern, OID_AUTO, filedelay, CTLFLAG_RW, &filedelay, 0, ""); -time_t dirdelay = 15; /* time to delay syncing directories */ +time_t dirdelay = 29; /* time to delay syncing directories */ SYSCTL_INT(_kern, OID_AUTO, dirdelay, CTLFLAG_RW, &dirdelay, 0, ""); -time_t metadelay = 10; /* time to delay syncing metadata */ +time_t metadelay = 28; /* time to delay syncing metadata */ SYSCTL_INT(_kern, OID_AUTO, metadelay, CTLFLAG_RW, &metadelay, 0, ""); static int rushjob; /* number of slots to run ASAP */ static int stat_rush_requests; /* number of times I/O speeded up */ @@ -622,16 +622,14 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) for (bp = blist; bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - error = tsleep((caddr_t) bp, - slpflag | (PRIBIO + 4), "vinvalbuf", - slptimeo); - if (error) { - splx(s); - return (error); - } - break; + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + error = BUF_TIMELOCK(bp, + LK_EXCLUSIVE | LK_SLEEPFAIL, + "vinvalbuf", slpflag, slptimeo); + if (error == ENOLCK) + break; + splx(s); + return (error); } /* * XXX Since there are no node locks for NFS, I @@ -646,21 +644,21 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) if (bp->b_vp == vp) { if (bp->b_flags & B_CLUSTEROK) { + BUF_UNLOCK(bp); vfs_bio_awrite(bp); } else { bremfree(bp); - bp->b_flags |= (B_BUSY | B_ASYNC); + bp->b_flags |= B_ASYNC; VOP_BWRITE(bp->b_vp, bp); } } else { bremfree(bp); - bp->b_flags |= B_BUSY; (void) VOP_BWRITE(bp->b_vp, bp); } break; } bremfree(bp); - bp->b_flags |= (B_INVAL | B_NOCACHE | B_RELBUF | B_BUSY); + bp->b_flags |= (B_INVAL | B_NOCACHE | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); } @@ -720,13 +718,12 @@ vtruncbuf(vp, cred, p, length, blksize) for (bp = TAILQ_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); if (bp->b_lblkno >= trunclbn) { - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep(bp, PRIBIO + 4, "vtrb1", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + BUF_LOCK(bp, LK_EXCLUSIVE|LK_SLEEPFAIL); goto restart; } else { bremfree(bp); - bp->b_flags |= (B_BUSY | B_INVAL | B_RELBUF); + bp->b_flags |= (B_INVAL | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); anyfreed = 1; @@ -742,13 +739,12 @@ vtruncbuf(vp, cred, p, length, blksize) for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); if (bp->b_lblkno >= trunclbn) { - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep(bp, PRIBIO + 4, "vtrb2", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + BUF_LOCK(bp, LK_EXCLUSIVE|LK_SLEEPFAIL); goto restart; } else { bremfree(bp); - bp->b_flags |= (B_BUSY | B_INVAL | B_RELBUF); + bp->b_flags |= (B_INVAL | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); anyfreed = 1; @@ -767,12 +763,11 @@ vtruncbuf(vp, cred, p, length, blksize) for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); if ((bp->b_flags & B_DELWRI) && (bp->b_lblkno < 0)) { - if (bp->b_flags & B_BUSY) { - bp->b_flags |= B_WANTED; - tsleep(bp, PRIBIO, "vtrb3", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { + BUF_LOCK(bp, LK_EXCLUSIVE|LK_SLEEPFAIL); + goto restart; } else { bremfree(bp); - bp->b_flags |= B_BUSY; if (bp->b_vp == vp) { bp->b_flags |= B_ASYNC; } else { diff --git a/sys/miscfs/devfs/devfs_vnops.c b/sys/miscfs/devfs/devfs_vnops.c index 7dc94769ee4b..683d2c7e4872 100644 --- a/sys/miscfs/devfs/devfs_vnops.c +++ b/sys/miscfs/devfs/devfs_vnops.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: devfs_vnops.c,v 1.73 1999/05/06 20:00:27 phk Exp $ + * $Id: devfs_vnops.c,v 1.74 1999/05/11 19:54:35 phk Exp $ */ @@ -1647,16 +1647,16 @@ devfs_fsync(struct vop_fsync_args *ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("devfs_fsync: not dirty"); if ((vp->v_flag & VOBJBUF) && (bp->b_flags & B_CLUSTEROK)) { + BUF_UNLOCK(bp); vfs_bio_awrite(bp); splx(s); } else { bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); bawrite(bp); } @@ -1950,7 +1950,7 @@ devfs_getpages(struct vop_getpages_args *ap) pmap_qenter(kva, ap->a_m, pcount); /* Build a minimal buffer header. */ - bp->b_flags = B_BUSY | B_READ | B_CALL; + bp->b_flags = B_READ | B_CALL; bp->b_iodone = devfs_getpages_iodone; /* B_PHYS is not set, but it is nice to fill this in. */ diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c index dd4a27902aa9..9a467fdc4338 100644 --- a/sys/miscfs/specfs/spec_vnops.c +++ b/sys/miscfs/specfs/spec_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95 - * $Id: spec_vnops.c,v 1.87 1999/05/31 11:27:56 phk Exp $ + * $Id: spec_vnops.c,v 1.88 1999/06/01 20:29:58 dt Exp $ */ #include @@ -492,16 +492,16 @@ spec_fsync(ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("spec_fsync: not dirty"); if ((vp->v_flag & VOBJBUF) && (bp->b_flags & B_CLUSTEROK)) { + BUF_UNLOCK(bp); vfs_bio_awrite(bp); splx(s); } else { bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); bawrite(bp); } @@ -570,7 +570,7 @@ spec_freeblks(ap) if ((bsw->d_flags & D_CANFREE) == 0) return (0); bp = geteblk(ap->a_length); - bp->b_flags |= B_FREEBUF | B_BUSY; + bp->b_flags |= B_FREEBUF; bp->b_dev = ap->a_vp->v_rdev; bp->b_blkno = ap->a_addr; bp->b_offset = dbtob(ap->a_addr); @@ -806,7 +806,7 @@ spec_getpages(ap) pmap_qenter(kva, ap->a_m, pcount); /* Build a minimal buffer header. */ - bp->b_flags = B_BUSY | B_READ | B_CALL; + bp->b_flags = B_READ | B_CALL; bp->b_iodone = spec_getpages_iodone; /* B_PHYS is not set, but it is nice to fill this in. */ diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 036ad2f2572d..98e301ecd490 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_vnops.c,v 1.84 1999/05/06 18:12:51 peter Exp $ */ +/* $Id: msdosfs_vnops.c,v 1.85 1999/05/11 19:54:43 phk Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ /*- @@ -842,12 +842,11 @@ msdosfs_fsync(ap) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_BUSY)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("msdosfs_fsync: not dirty"); bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); (void) bwrite(bp); goto loop; diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c index fe055c078cc6..ec593d8106ff 100644 --- a/sys/nfs/nfs_bio.c +++ b/sys/nfs/nfs_bio.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - * $Id: nfs_bio.c,v 1.72 1999/06/05 05:25:37 peter Exp $ + * $Id: nfs_bio.c,v 1.73 1999/06/16 23:27:46 mckusick Exp $ */ @@ -1194,6 +1194,7 @@ nfs_asyncio(bp, cred, procp) } } + BUF_KERNPROC(bp); TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist); nmp->nm_bufqlen++; return (0); diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c index cd771555ae85..554e182c1239 100644 --- a/sys/nfs/nfs_common.c +++ b/sys/nfs/nfs_common.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - * $Id: nfs_subs.c,v 1.75 1999/06/05 05:35:00 peter Exp $ + * $Id: nfs_subs.c,v 1.76 1999/06/23 04:44:12 julian Exp $ */ /* @@ -2188,7 +2188,8 @@ nfs_clearcommit(mp) nvp = vp->v_mntvnodes.le_next; for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) + if (BUF_REFCNT(bp) == 0 && + (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == (B_DELWRI | B_NEEDCOMMIT)) bp->b_flags &= ~B_NEEDCOMMIT; } diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index cd771555ae85..554e182c1239 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - * $Id: nfs_subs.c,v 1.75 1999/06/05 05:35:00 peter Exp $ + * $Id: nfs_subs.c,v 1.76 1999/06/23 04:44:12 julian Exp $ */ /* @@ -2188,7 +2188,8 @@ nfs_clearcommit(mp) nvp = vp->v_mntvnodes.le_next; for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) + if (BUF_REFCNT(bp) == 0 && + (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == (B_DELWRI | B_NEEDCOMMIT)) bp->b_flags &= ~B_NEEDCOMMIT; } diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index c4b20b802a51..9e5ceb8f2811 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $Id: nfs_vnops.c,v 1.130 1999/06/05 05:35:02 peter Exp $ + * $Id: nfs_vnops.c,v 1.131 1999/06/16 23:27:48 mckusick Exp $ */ @@ -2647,7 +2647,7 @@ nfs_strategy(ap) int error = 0; KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); - KASSERT((bp->b_flags & B_BUSY), ("nfs_strategy: buffer %p not B_BUSY", bp)); + KASSERT(BUF_REFCNT(bp) == 0, ("nfs_strategy: buffer %p not locked", bp)); if (bp->b_flags & B_PHYS) panic("nfs physio"); @@ -2762,8 +2762,9 @@ nfs_flush(vp, cred, waitfor, p, commit) bveccount = 0; for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) - == (B_DELWRI | B_NEEDCOMMIT)) + if (BUF_REFCNT(bp) == 0 && + (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) + == (B_DELWRI | B_NEEDCOMMIT)) bveccount++; } /* @@ -2791,8 +2792,9 @@ nfs_flush(vp, cred, waitfor, p, commit) nbp = TAILQ_NEXT(bp, b_vnbufs); if (bvecpos >= bvecsize) break; - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) - != (B_DELWRI | B_NEEDCOMMIT)) + if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != + (B_DELWRI | B_NEEDCOMMIT) || + BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; bremfree(bp); /* @@ -2807,11 +2809,11 @@ nfs_flush(vp, cred, waitfor, p, commit) wcred = bp->b_wcred; else if (wcred != bp->b_wcred) wcred = NOCRED; - bp->b_flags |= (B_BUSY | B_WRITEINPROG); + bp->b_flags |= B_WRITEINPROG; vfs_busy_pages(bp, 1); /* - * bp is protected by being B_BUSY, but nbp is not + * bp is protected by being locked, but nbp is not * and vfs_busy_pages() may sleep. We have to * recalculate nbp. */ @@ -2904,34 +2906,37 @@ nfs_flush(vp, cred, waitfor, p, commit) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if (bp->b_flags & B_BUSY) { + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { if (waitfor != MNT_WAIT || passone) continue; - bp->b_flags |= B_WANTED; - error = tsleep((caddr_t)bp, slpflag | (PRIBIO + 1), - "nfsfsync", slptimeo); + error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL, + "nfsfsync", slpflag, slptimeo); splx(s); - if (error) { - if (nfs_sigintr(nmp, (struct nfsreq *)0, p)) { + if (error == 0) + panic("nfs_fsync: inconsistent lock"); + if (error == ENOLCK) + goto loop; + if (nfs_sigintr(nmp, (struct nfsreq *)0, p)) { error = EINTR; goto done; - } - if (slpflag == PCATCH) { + } + if (slpflag == PCATCH) { slpflag = 0; slptimeo = 2 * hz; - } } goto loop; } if ((bp->b_flags & B_DELWRI) == 0) panic("nfs_fsync: not dirty"); - if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) + if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) { + BUF_UNLOCK(bp); continue; + } bremfree(bp); if (passone || !commit) - bp->b_flags |= (B_BUSY|B_ASYNC); + bp->b_flags |= B_ASYNC; else - bp->b_flags |= (B_BUSY|B_ASYNC|B_WRITEINPROG|B_NEEDCOMMIT); + bp->b_flags |= (B_ASYNC | B_WRITEINPROG | B_NEEDCOMMIT); splx(s); VOP_BWRITE(bp->b_vp, bp); goto loop; @@ -3045,8 +3050,8 @@ nfs_writebp(bp, force, procp) int retv = 1; off_t off; - if(!(bp->b_flags & B_BUSY)) - panic("bwrite: buffer is not busy???"); + if (BUF_REFCNT(bp) == 0) + panic("bwrite: buffer is not locked???"); if (bp->b_flags & B_INVAL) { brelse(bp); @@ -3090,6 +3095,7 @@ nfs_writebp(bp, force, procp) if (retv) { if (force) bp->b_flags |= B_WRITEINPROG; + BUF_KERNPROC(bp); VOP_STRATEGY(bp->b_vp, bp); } diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index fe055c078cc6..ec593d8106ff 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - * $Id: nfs_bio.c,v 1.72 1999/06/05 05:25:37 peter Exp $ + * $Id: nfs_bio.c,v 1.73 1999/06/16 23:27:46 mckusick Exp $ */ @@ -1194,6 +1194,7 @@ nfs_asyncio(bp, cred, procp) } } + BUF_KERNPROC(bp); TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist); nmp->nm_bufqlen++; return (0); diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index cd771555ae85..554e182c1239 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - * $Id: nfs_subs.c,v 1.75 1999/06/05 05:35:00 peter Exp $ + * $Id: nfs_subs.c,v 1.76 1999/06/23 04:44:12 julian Exp $ */ /* @@ -2188,7 +2188,8 @@ nfs_clearcommit(mp) nvp = vp->v_mntvnodes.le_next; for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) + if (BUF_REFCNT(bp) == 0 && + (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == (B_DELWRI | B_NEEDCOMMIT)) bp->b_flags &= ~B_NEEDCOMMIT; } diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index c4b20b802a51..9e5ceb8f2811 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $Id: nfs_vnops.c,v 1.130 1999/06/05 05:35:02 peter Exp $ + * $Id: nfs_vnops.c,v 1.131 1999/06/16 23:27:48 mckusick Exp $ */ @@ -2647,7 +2647,7 @@ nfs_strategy(ap) int error = 0; KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); - KASSERT((bp->b_flags & B_BUSY), ("nfs_strategy: buffer %p not B_BUSY", bp)); + KASSERT(BUF_REFCNT(bp) == 0, ("nfs_strategy: buffer %p not locked", bp)); if (bp->b_flags & B_PHYS) panic("nfs physio"); @@ -2762,8 +2762,9 @@ nfs_flush(vp, cred, waitfor, p, commit) bveccount = 0; for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) - == (B_DELWRI | B_NEEDCOMMIT)) + if (BUF_REFCNT(bp) == 0 && + (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) + == (B_DELWRI | B_NEEDCOMMIT)) bveccount++; } /* @@ -2791,8 +2792,9 @@ nfs_flush(vp, cred, waitfor, p, commit) nbp = TAILQ_NEXT(bp, b_vnbufs); if (bvecpos >= bvecsize) break; - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) - != (B_DELWRI | B_NEEDCOMMIT)) + if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != + (B_DELWRI | B_NEEDCOMMIT) || + BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; bremfree(bp); /* @@ -2807,11 +2809,11 @@ nfs_flush(vp, cred, waitfor, p, commit) wcred = bp->b_wcred; else if (wcred != bp->b_wcred) wcred = NOCRED; - bp->b_flags |= (B_BUSY | B_WRITEINPROG); + bp->b_flags |= B_WRITEINPROG; vfs_busy_pages(bp, 1); /* - * bp is protected by being B_BUSY, but nbp is not + * bp is protected by being locked, but nbp is not * and vfs_busy_pages() may sleep. We have to * recalculate nbp. */ @@ -2904,34 +2906,37 @@ nfs_flush(vp, cred, waitfor, p, commit) s = splbio(); for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if (bp->b_flags & B_BUSY) { + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { if (waitfor != MNT_WAIT || passone) continue; - bp->b_flags |= B_WANTED; - error = tsleep((caddr_t)bp, slpflag | (PRIBIO + 1), - "nfsfsync", slptimeo); + error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL, + "nfsfsync", slpflag, slptimeo); splx(s); - if (error) { - if (nfs_sigintr(nmp, (struct nfsreq *)0, p)) { + if (error == 0) + panic("nfs_fsync: inconsistent lock"); + if (error == ENOLCK) + goto loop; + if (nfs_sigintr(nmp, (struct nfsreq *)0, p)) { error = EINTR; goto done; - } - if (slpflag == PCATCH) { + } + if (slpflag == PCATCH) { slpflag = 0; slptimeo = 2 * hz; - } } goto loop; } if ((bp->b_flags & B_DELWRI) == 0) panic("nfs_fsync: not dirty"); - if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) + if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) { + BUF_UNLOCK(bp); continue; + } bremfree(bp); if (passone || !commit) - bp->b_flags |= (B_BUSY|B_ASYNC); + bp->b_flags |= B_ASYNC; else - bp->b_flags |= (B_BUSY|B_ASYNC|B_WRITEINPROG|B_NEEDCOMMIT); + bp->b_flags |= (B_ASYNC | B_WRITEINPROG | B_NEEDCOMMIT); splx(s); VOP_BWRITE(bp->b_vp, bp); goto loop; @@ -3045,8 +3050,8 @@ nfs_writebp(bp, force, procp) int retv = 1; off_t off; - if(!(bp->b_flags & B_BUSY)) - panic("bwrite: buffer is not busy???"); + if (BUF_REFCNT(bp) == 0) + panic("bwrite: buffer is not locked???"); if (bp->b_flags & B_INVAL) { brelse(bp); @@ -3090,6 +3095,7 @@ nfs_writebp(bp, force, procp) if (retv) { if (force) bp->b_flags |= B_WRITEINPROG; + BUF_KERNPROC(bp); VOP_STRATEGY(bp->b_vp, bp); } diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index cd771555ae85..554e182c1239 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - * $Id: nfs_subs.c,v 1.75 1999/06/05 05:35:00 peter Exp $ + * $Id: nfs_subs.c,v 1.76 1999/06/23 04:44:12 julian Exp $ */ /* @@ -2188,7 +2188,8 @@ nfs_clearcommit(mp) nvp = vp->v_mntvnodes.le_next; for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & (B_BUSY | B_DELWRI | B_NEEDCOMMIT)) + if (BUF_REFCNT(bp) == 0 && + (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == (B_DELWRI | B_NEEDCOMMIT)) bp->b_flags &= ~B_NEEDCOMMIT; } diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c index 245e344ef283..6e854448e972 100644 --- a/sys/pc98/cbus/fdc.c +++ b/sys/pc98/cbus/fdc.c @@ -47,7 +47,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.62 1999/05/30 16:53:16 phk Exp $ + * $Id: fd.c,v 1.63 1999/06/01 13:14:34 kato Exp $ * */ @@ -2603,7 +2603,9 @@ fdformat(dev, finfo, p) */ PHOLD(p); bzero((void *)bp, sizeof(struct buf)); - bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; + BUF_INITLOCK(bp); + BUF_LOCK(bp, LK_EXCLUSIVE); + bp->b_flags = B_PHYS | B_FORMAT; /* * calculate a fake blkno, so fdstrategy() would initiate a @@ -2639,6 +2641,8 @@ fdformat(dev, finfo, p) * allow the process to be swapped */ PRELE(p); + BUF_UNLOCK(bp); + BUF_FREELOCK(bp); free(bp, M_TEMP); return rv; } diff --git a/sys/pc98/pc98/atcompat_diskslice.c b/sys/pc98/pc98/atcompat_diskslice.c index 984763168420..9bc0f1faec13 100644 --- a/sys/pc98/pc98/atcompat_diskslice.c +++ b/sys/pc98/pc98/atcompat_diskslice.c @@ -35,7 +35,7 @@ * * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ - * $Id: atcompat_diskslice.c,v 1.14 1999/01/28 09:18:21 kato Exp $ + * $Id: atcompat_diskslice.c,v 1.15 1999/05/12 08:33:18 kato Exp $ */ /* @@ -194,7 +194,7 @@ atcompat_dsinit(dname, dev, strat, lp, sspp) bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); bp->b_blkno = mbr_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading primary partition table", @@ -389,7 +389,7 @@ atcompat_extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, bp->b_dev = dev; bp->b_blkno = ext_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading extended partition table", diff --git a/sys/pc98/pc98/diskslice_machdep.c b/sys/pc98/pc98/diskslice_machdep.c index b1c881cc0c8b..7d59b9922df4 100644 --- a/sys/pc98/pc98/diskslice_machdep.c +++ b/sys/pc98/pc98/diskslice_machdep.c @@ -35,7 +35,7 @@ * * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ - * $Id: diskslice_machdep.c,v 1.18 1999/01/28 09:18:21 kato Exp $ + * $Id: diskslice_machdep.c,v 1.19 1999/05/12 08:33:22 kato Exp $ */ /* @@ -243,7 +243,7 @@ dsinit(dname, dev, strat, lp, sspp) bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); bp->b_blkno = mbr_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; #ifdef PC98 if (bp->b_bcount < 1024) bp->b_bcount = 1024; @@ -538,7 +538,7 @@ extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset, bp->b_dev = dev; bp->b_blkno = ext_offset; bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp) != 0) { diskerr(bp, dname, "error reading extended partition table", diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c index 245e344ef283..6e854448e972 100644 --- a/sys/pc98/pc98/fd.c +++ b/sys/pc98/pc98/fd.c @@ -47,7 +47,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.62 1999/05/30 16:53:16 phk Exp $ + * $Id: fd.c,v 1.63 1999/06/01 13:14:34 kato Exp $ * */ @@ -2603,7 +2603,9 @@ fdformat(dev, finfo, p) */ PHOLD(p); bzero((void *)bp, sizeof(struct buf)); - bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; + BUF_INITLOCK(bp); + BUF_LOCK(bp, LK_EXCLUSIVE); + bp->b_flags = B_PHYS | B_FORMAT; /* * calculate a fake blkno, so fdstrategy() would initiate a @@ -2639,6 +2641,8 @@ fdformat(dev, finfo, p) * allow the process to be swapped */ PRELE(p); + BUF_UNLOCK(bp); + BUF_FREELOCK(bp); free(bp, M_TEMP); return rv; } diff --git a/sys/sys/bio.h b/sys/sys/bio.h index f05d3d74c63f..193c5b5202bd 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -36,13 +36,14 @@ * SUCH DAMAGE. * * @(#)buf.h 8.9 (Berkeley) 3/30/95 - * $Id: buf.h,v 1.68 1999/05/06 20:00:32 phk Exp $ + * $Id: buf.h,v 1.69 1999/05/07 07:03:45 phk Exp $ */ #ifndef _SYS_BUF_H_ #define _SYS_BUF_H_ #include +#include struct buf; struct mount; @@ -101,6 +102,7 @@ struct buf { unsigned short b_qindex; /* buffer queue index */ unsigned char b_usecount; /* buffer use count */ unsigned char b_xflags; /* extra flags */ + struct lock b_lock; /* Buffer lock */ int b_error; /* Errno value. */ long b_bufsize; /* Allocated buffer size. */ long b_bcount; /* Valid bytes in buffer. */ @@ -186,7 +188,7 @@ struct buf { #define B_NEEDCOMMIT 0x00000002 /* Append-write in progress. */ #define B_ASYNC 0x00000004 /* Start I/O, do not wait. */ #define B_BAD 0x00000008 /* Bad block revectoring in progress. */ -#define B_BUSY 0x00000010 /* I/O in progress. */ +#define B_UNUSED1 0x00000010 /* Old B_BUSY */ #define B_CACHE 0x00000020 /* Bread found us in the cache. */ #define B_CALL 0x00000040 /* Call b_iodone from biodone. */ #define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */ @@ -205,7 +207,7 @@ struct buf { #define B_READ 0x00100000 /* Read buffer. */ #define B_DIRTY 0x00200000 /* Needs writing later. */ #define B_RELBUF 0x00400000 /* Release VMIO buffer. */ -#define B_WANTED 0x00800000 /* Process wants this buffer. */ +#define B_WANT 0x00800000 /* Used by vm_pager.c */ #define B_WRITE 0x00000000 /* Write buffer (pseudo flag). */ #define B_WRITEINPROG 0x01000000 /* Write in progress. */ #define B_XXX 0x02000000 /* Debugging flag. */ @@ -217,10 +219,10 @@ struct buf { #define B_AUTOCHAINDONE 0x80000000 /* Available flag */ #define PRINT_BUF_FLAGS "\20\40autochain\37cluster\36vmio\35ram\34ordered" \ - "\33paging\32xxx\31writeinprog\30wanted\27relbuf\26dirty" \ + "\33paging\32xxx\31writeinprog\30want\27relbuf\26dirty" \ "\25read\24raw\23phys\22clusterok\21malloc\20nocache" \ "\17locked\16inval\15scanned\14error\13eintr\12done\11freebuf" \ - "\10delwri\7call\6cache\5busy\4bad\3async\2needcommit\1age" + "\10delwri\7call\6cache\4bad\3async\2needcommit\1age" /* * These flags are kept in b_xflags. @@ -230,6 +232,84 @@ struct buf { #define NOOFFSET (-1LL) /* No buffer offset calculated yet */ +/* + * Buffer locking + */ +struct simplelock buftimelock; /* Interlock on setting prio and timo */ +extern char *buf_wmesg; /* Default buffer lock message */ +#define BUF_WMESG "bufwait" +#include /* XXX for curproc */ +/* + * Initialize a lock. + */ +#define BUF_LOCKINIT(bp) \ + lockinit(&(bp)->b_lock, PRIBIO + 4, buf_wmesg, 0, 0) +/* + * + * Get a lock sleeping non-interruptably until it becomes available. + */ +static __inline int BUF_LOCK __P((struct buf *, int)); +static __inline int +BUF_LOCK (struct buf *bp, int locktype) +{ + + simple_lock(&buftimelock); + bp->b_lock.lk_wmesg = buf_wmesg; + bp->b_lock.lk_prio = PRIBIO + 4; + bp->b_lock.lk_timo = 0; + return (lockmgr(&(bp)->b_lock, locktype, &buftimelock, curproc)); +} +/* + * Get a lock sleeping with specified interruptably and timeout. + */ +static __inline int BUF_TIMELOCK __P((struct buf *, int, char *, int, int)); +static __inline int +BUF_TIMELOCK(struct buf *bp, int locktype, char *wmesg, int catch, int timo) +{ + + simple_lock(&buftimelock); + bp->b_lock.lk_wmesg = wmesg; + bp->b_lock.lk_prio = (PRIBIO + 4) | catch; + bp->b_lock.lk_timo = timo; + return (lockmgr(&(bp)->b_lock, (locktype), &buftimelock, curproc)); +} +/* + * Release a lock. Only the acquiring process may free the lock unless + * it has been handed off to biodone. + */ +#define BUF_UNLOCK(bp) \ + lockmgr(&(bp)->b_lock, LK_RELEASE, NULL, curproc) +/* + * Free a buffer lock. + */ +#define BUF_LOCKFREE(bp) \ + if (BUF_REFCNT(bp) > 0) \ + panic("free locked buf") +/* + * When initiating asynchronous I/O, change ownership of the lock to the + * kernel. Once done, the lock may legally released by biodone. The + * original owning process can no longer acquire it recursively, but must + * wait until the I/O is completed and the lock has been freed by biodone. + */ +static __inline void BUF_KERNPROC __P((struct buf *)); +static __inline void +BUF_KERNPROC(struct buf *bp) +{ + struct buf *nbp; + + if (bp->b_flags & B_ASYNC) + bp->b_lock.lk_lockholder = LK_KERNPROC; + for (nbp = TAILQ_FIRST(&bp->b_cluster.cluster_head); + nbp; nbp = TAILQ_NEXT(&nbp->b_cluster, cluster_entry)) + if (nbp->b_flags & B_ASYNC) + nbp->b_lock.lk_lockholder = LK_KERNPROC; +} +/* + * Find out the number of references to a lock. + */ +#define BUF_REFCNT(bp) \ + lockcount(&(bp)->b_lock) + struct buf_queue_head { TAILQ_HEAD(buf_queue, buf) queue; daddr_t last_pblkno; diff --git a/sys/sys/buf.h b/sys/sys/buf.h index f05d3d74c63f..193c5b5202bd 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -36,13 +36,14 @@ * SUCH DAMAGE. * * @(#)buf.h 8.9 (Berkeley) 3/30/95 - * $Id: buf.h,v 1.68 1999/05/06 20:00:32 phk Exp $ + * $Id: buf.h,v 1.69 1999/05/07 07:03:45 phk Exp $ */ #ifndef _SYS_BUF_H_ #define _SYS_BUF_H_ #include +#include struct buf; struct mount; @@ -101,6 +102,7 @@ struct buf { unsigned short b_qindex; /* buffer queue index */ unsigned char b_usecount; /* buffer use count */ unsigned char b_xflags; /* extra flags */ + struct lock b_lock; /* Buffer lock */ int b_error; /* Errno value. */ long b_bufsize; /* Allocated buffer size. */ long b_bcount; /* Valid bytes in buffer. */ @@ -186,7 +188,7 @@ struct buf { #define B_NEEDCOMMIT 0x00000002 /* Append-write in progress. */ #define B_ASYNC 0x00000004 /* Start I/O, do not wait. */ #define B_BAD 0x00000008 /* Bad block revectoring in progress. */ -#define B_BUSY 0x00000010 /* I/O in progress. */ +#define B_UNUSED1 0x00000010 /* Old B_BUSY */ #define B_CACHE 0x00000020 /* Bread found us in the cache. */ #define B_CALL 0x00000040 /* Call b_iodone from biodone. */ #define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */ @@ -205,7 +207,7 @@ struct buf { #define B_READ 0x00100000 /* Read buffer. */ #define B_DIRTY 0x00200000 /* Needs writing later. */ #define B_RELBUF 0x00400000 /* Release VMIO buffer. */ -#define B_WANTED 0x00800000 /* Process wants this buffer. */ +#define B_WANT 0x00800000 /* Used by vm_pager.c */ #define B_WRITE 0x00000000 /* Write buffer (pseudo flag). */ #define B_WRITEINPROG 0x01000000 /* Write in progress. */ #define B_XXX 0x02000000 /* Debugging flag. */ @@ -217,10 +219,10 @@ struct buf { #define B_AUTOCHAINDONE 0x80000000 /* Available flag */ #define PRINT_BUF_FLAGS "\20\40autochain\37cluster\36vmio\35ram\34ordered" \ - "\33paging\32xxx\31writeinprog\30wanted\27relbuf\26dirty" \ + "\33paging\32xxx\31writeinprog\30want\27relbuf\26dirty" \ "\25read\24raw\23phys\22clusterok\21malloc\20nocache" \ "\17locked\16inval\15scanned\14error\13eintr\12done\11freebuf" \ - "\10delwri\7call\6cache\5busy\4bad\3async\2needcommit\1age" + "\10delwri\7call\6cache\4bad\3async\2needcommit\1age" /* * These flags are kept in b_xflags. @@ -230,6 +232,84 @@ struct buf { #define NOOFFSET (-1LL) /* No buffer offset calculated yet */ +/* + * Buffer locking + */ +struct simplelock buftimelock; /* Interlock on setting prio and timo */ +extern char *buf_wmesg; /* Default buffer lock message */ +#define BUF_WMESG "bufwait" +#include /* XXX for curproc */ +/* + * Initialize a lock. + */ +#define BUF_LOCKINIT(bp) \ + lockinit(&(bp)->b_lock, PRIBIO + 4, buf_wmesg, 0, 0) +/* + * + * Get a lock sleeping non-interruptably until it becomes available. + */ +static __inline int BUF_LOCK __P((struct buf *, int)); +static __inline int +BUF_LOCK (struct buf *bp, int locktype) +{ + + simple_lock(&buftimelock); + bp->b_lock.lk_wmesg = buf_wmesg; + bp->b_lock.lk_prio = PRIBIO + 4; + bp->b_lock.lk_timo = 0; + return (lockmgr(&(bp)->b_lock, locktype, &buftimelock, curproc)); +} +/* + * Get a lock sleeping with specified interruptably and timeout. + */ +static __inline int BUF_TIMELOCK __P((struct buf *, int, char *, int, int)); +static __inline int +BUF_TIMELOCK(struct buf *bp, int locktype, char *wmesg, int catch, int timo) +{ + + simple_lock(&buftimelock); + bp->b_lock.lk_wmesg = wmesg; + bp->b_lock.lk_prio = (PRIBIO + 4) | catch; + bp->b_lock.lk_timo = timo; + return (lockmgr(&(bp)->b_lock, (locktype), &buftimelock, curproc)); +} +/* + * Release a lock. Only the acquiring process may free the lock unless + * it has been handed off to biodone. + */ +#define BUF_UNLOCK(bp) \ + lockmgr(&(bp)->b_lock, LK_RELEASE, NULL, curproc) +/* + * Free a buffer lock. + */ +#define BUF_LOCKFREE(bp) \ + if (BUF_REFCNT(bp) > 0) \ + panic("free locked buf") +/* + * When initiating asynchronous I/O, change ownership of the lock to the + * kernel. Once done, the lock may legally released by biodone. The + * original owning process can no longer acquire it recursively, but must + * wait until the I/O is completed and the lock has been freed by biodone. + */ +static __inline void BUF_KERNPROC __P((struct buf *)); +static __inline void +BUF_KERNPROC(struct buf *bp) +{ + struct buf *nbp; + + if (bp->b_flags & B_ASYNC) + bp->b_lock.lk_lockholder = LK_KERNPROC; + for (nbp = TAILQ_FIRST(&bp->b_cluster.cluster_head); + nbp; nbp = TAILQ_NEXT(&nbp->b_cluster, cluster_entry)) + if (nbp->b_flags & B_ASYNC) + nbp->b_lock.lk_lockholder = LK_KERNPROC; +} +/* + * Find out the number of references to a lock. + */ +#define BUF_REFCNT(bp) \ + lockcount(&(bp)->b_lock) + struct buf_queue_head { TAILQ_HEAD(buf_queue, buf) queue; daddr_t last_pblkno; diff --git a/sys/sys/lock.h b/sys/sys/lock.h index c9c287d120c6..038774f7edd8 100644 --- a/sys/sys/lock.h +++ b/sys/sys/lock.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)lock.h 8.12 (Berkeley) 5/19/95 - * $Id: lock.h,v 1.12 1999/01/02 11:34:56 bde Exp $ + * $Id: lock.h,v 1.13 1999/01/20 14:49:12 eivind Exp $ */ #ifndef _LOCK_H_ @@ -189,6 +189,7 @@ int lockmgr __P((struct lock *, u_int flags, #endif void lockmgr_printinfo __P((struct lock *)); int lockstatus __P((struct lock *)); +int lockcount __P((struct lock *)); #ifdef SIMPLELOCK_DEBUG void _simple_unlock __P((struct simplelock *alp, const char *, int)); diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h index c9c287d120c6..038774f7edd8 100644 --- a/sys/sys/lockmgr.h +++ b/sys/sys/lockmgr.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)lock.h 8.12 (Berkeley) 5/19/95 - * $Id: lock.h,v 1.12 1999/01/02 11:34:56 bde Exp $ + * $Id: lock.h,v 1.13 1999/01/20 14:49:12 eivind Exp $ */ #ifndef _LOCK_H_ @@ -189,6 +189,7 @@ int lockmgr __P((struct lock *, u_int flags, #endif void lockmgr_printinfo __P((struct lock *)); int lockstatus __P((struct lock *)); +int lockcount __P((struct lock *)); #ifdef SIMPLELOCK_DEBUG void _simple_unlock __P((struct simplelock *alp, const char *, int)); diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index df2791f99d42..eaaa2eca159b 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -53,7 +53,7 @@ * SUCH DAMAGE. * * from: @(#)ffs_softdep.c 9.40 (McKusick) 6/15/99 - * $Id: ffs_softdep.c,v 1.30 1999/06/15 23:37:29 mckusick Exp $ + * $Id: ffs_softdep.c,v 1.31 1999/06/16 23:27:55 mckusick Exp $ */ /* @@ -1530,6 +1530,8 @@ setup_allocindir_phase2(bp, ip, aip) } newindirdep->ir_savebp = getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); + newindirdep->ir_savebp->b_flags |= B_ASYNC; + BUF_KERNPROC(newindirdep->ir_savebp); bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } } @@ -3698,7 +3700,7 @@ softdep_fsync_mountdev(vp) /* * If it is already scheduled, skip to the next buffer. */ - if (bp->b_flags & B_BUSY) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("softdep_fsync_mountdev: not dirty"); @@ -3707,10 +3709,11 @@ softdep_fsync_mountdev(vp) * dependencies. */ if ((wk = LIST_FIRST(&bp->b_dep)) == NULL || - wk->wk_type != D_BMSAFEMAP) + wk->wk_type != D_BMSAFEMAP) { + BUF_UNLOCK(bp); continue; + } bremfree(bp); - bp->b_flags |= B_BUSY; FREE_LOCK(&lk); (void) bawrite(bp); ACQUIRE_LOCK(&lk); @@ -4414,19 +4417,20 @@ getdirtybuf(bpp, waitfor) for (;;) { if ((bp = *bpp) == NULL) return (0); - if ((bp->b_flags & B_BUSY) == 0) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) break; if (waitfor != MNT_WAIT) return (0); - bp->b_flags |= B_WANTED; FREE_LOCK_INTERLOCKED(&lk); - tsleep((caddr_t)bp, PRIBIO + 1, "sdsdty", 0); + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL) != ENOLCK) + panic("getdirtybuf: inconsistent lock"); ACQUIRE_LOCK_INTERLOCKED(&lk); } - if ((bp->b_flags & B_DELWRI) == 0) + if ((bp->b_flags & B_DELWRI) == 0) { + BUF_UNLOCK(bp); return (0); + } bremfree(bp); - bp->b_flags |= B_BUSY; return (1); } diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 97c96fcc5432..29f403a20aae 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95 - * $Id: ffs_vnops.c,v 1.56 1999/05/14 01:26:05 mckusick Exp $ + * $Id: ffs_vnops.c,v 1.57 1999/06/18 05:49:46 mckusick Exp $ */ #include @@ -159,8 +159,9 @@ ffs_fsync(ap) * or if it's already scheduled, skip to the next * buffer */ - if ((bp->b_flags & (B_BUSY | B_SCANNED)) || - ((skipmeta == 1) && (bp->b_lblkno < 0))) + if ((bp->b_flags & B_SCANNED) || + ((skipmeta == 1) && (bp->b_lblkno < 0)) || + BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("ffs_fsync: not dirty"); @@ -181,17 +182,16 @@ ffs_fsync(ap) if (passes > 0 || (ap->a_waitfor != MNT_WAIT)) { if ((bp->b_flags & B_CLUSTEROK) && ap->a_waitfor != MNT_WAIT) { + BUF_UNLOCK(bp); (void) vfs_bio_awrite(bp); } else { bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); (void) bawrite(bp); s = splbio(); } } else { bremfree(bp); - bp->b_flags |= B_BUSY; splx(s); if ((error = bwrite(bp)) != 0) return (error); @@ -203,11 +203,12 @@ ffs_fsync(ap) * off the file, then throw it away. */ bremfree(bp); - bp->b_flags |= B_BUSY | B_INVAL | B_NOCACHE; + bp->b_flags |= B_INVAL | B_NOCACHE; splx(s); brelse(bp); s = splbio(); } else { + BUF_UNLOCK(bp); vfs_bio_awrite(bp); } /* diff --git a/sys/ufs/mfs/mfs_vnops.c b/sys/ufs/mfs/mfs_vnops.c index c9ae4dd8483d..09b65e4c8192 100644 --- a/sys/ufs/mfs/mfs_vnops.c +++ b/sys/ufs/mfs/mfs_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95 - * $Id: mfs_vnops.c,v 1.43 1999/04/11 02:28:32 eivind Exp $ + * $Id: mfs_vnops.c,v 1.44 1999/05/02 23:56:57 alc Exp $ */ #include @@ -147,11 +147,12 @@ mfs_freeblks(ap) panic("mfs_freeblks: bad dev"); bp = geteblk(ap->a_length); - bp->b_flags |= B_FREEBUF | B_BUSY; + bp->b_flags |= B_FREEBUF | B_ASYNC; bp->b_dev = ap->a_vp->v_rdev; bp->b_blkno = ap->a_addr; bp->b_offset = dbtob(ap->a_addr); bp->b_bcount = ap->a_length; + BUF_KERNPROC(bp); VOP_STRATEGY(vp, bp); return(0); } diff --git a/sys/ufs/ufs/ufs_disksubr.c b/sys/ufs/ufs/ufs_disksubr.c index 33f1d2ac1b68..21088cb7f67d 100644 --- a/sys/ufs/ufs/ufs_disksubr.c +++ b/sys/ufs/ufs/ufs_disksubr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94 - * $Id: ufs_disksubr.c,v 1.38 1998/10/17 07:49:04 bde Exp $ + * $Id: ufs_disksubr.c,v 1.39 1998/12/14 05:37:37 dillon Exp $ */ #include @@ -182,7 +182,7 @@ readdisklabel(dev, strat, lp) bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE); bp->b_bcount = lp->d_secsize; bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); if (biowait(bp)) msg = "I/O error"; @@ -286,7 +286,7 @@ writedisklabel(dev, strat, lp) * (also stupid.. how do you write the first one? by raw writes?) */ bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_READ; + bp->b_flags |= B_READ; (*strat)(bp); error = biowait(bp); if (error) @@ -299,7 +299,7 @@ writedisklabel(dev, strat, lp) dkcksum(dlp) == 0) { *dlp = *lp; bp->b_flags &= ~(B_DONE | B_READ); - bp->b_flags |= B_BUSY | B_WRITE; + bp->b_flags |= B_WRITE; #ifdef __alpha__ alpha_fix_srm_checksum(bp); #endif @@ -315,7 +315,7 @@ writedisklabel(dev, strat, lp) dlp = (struct disklabel *)bp->b_data; *dlp = *lp; bp->b_flags &= ~B_INVAL; - bp->b_flags |= B_BUSY | B_WRITE; + bp->b_flags |= B_WRITE; (*strat)(bp); error = biowait(bp); #endif diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 2651be4a0fe7..74ca75ec5c83 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -64,7 +64,7 @@ * * @(#)swap_pager.c 8.9 (Berkeley) 3/21/94 * - * $Id: swap_pager.c,v 1.117 1999/03/14 09:20:00 julian Exp $ + * $Id: swap_pager.c,v 1.118 1999/05/06 20:00:33 phk Exp $ */ #include @@ -1108,7 +1108,7 @@ swap_pager_getpages(object, m, count, reqpage) pmap_qenter(kva, m + i, j - i); - bp->b_flags = B_BUSY | B_READ | B_CALL; + bp->b_flags = B_READ | B_CALL; bp->b_iodone = swp_pager_async_iodone; bp->b_rcred = bp->b_wcred = proc0.p_ucred; bp->b_data = (caddr_t) kva; @@ -1358,10 +1358,10 @@ swap_pager_putpages(object, m, count, sync, rtvals) if (sync == TRUE) { bp = getpbuf(&nsw_wcount_sync); - bp->b_flags = B_BUSY | B_CALL; + bp->b_flags = B_CALL; } else { bp = getpbuf(&nsw_wcount_async); - bp->b_flags = B_BUSY | B_CALL | B_ASYNC; + bp->b_flags = B_CALL | B_ASYNC; } bp->b_spc = NULL; /* not used, but NULL-out anyway */ @@ -1413,6 +1413,7 @@ swap_pager_putpages(object, m, count, sync, rtvals) if (sync == FALSE) { bp->b_iodone = swp_pager_async_iodone; + BUF_KERNPROC(bp); VOP_STRATEGY(bp->b_vp, bp); for (j = 0; j < n; ++j) diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c index 90550036b841..829258b97a74 100644 --- a/sys/vm/vm_pager.c +++ b/sys/vm/vm_pager.c @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_pager.c,v 1.46 1999/05/02 23:57:14 alc Exp $ + * $Id: vm_pager.c,v 1.47 1999/05/06 20:00:34 phk Exp $ */ /* @@ -218,6 +218,8 @@ vm_pager_bufferinit() */ for (i = 0; i < nswbuf; i++, bp++) { TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist); + BUF_LOCKINIT(bp); + LIST_INIT(&bp->b_dep); bp->b_rcred = bp->b_wcred = NOCRED; bp->b_xflags = 0; } @@ -338,7 +340,6 @@ vm_pager_object_lookup(pg_list, handle) static void initpbuf(struct buf *bp) { - bzero(bp, sizeof *bp); bp->b_rcred = NOCRED; bp->b_wcred = NOCRED; bp->b_qindex = QUEUE_NONE; @@ -346,6 +347,9 @@ initpbuf(struct buf *bp) { bp->b_kvabase = bp->b_data; bp->b_kvasize = MAXPHYS; bp->b_xflags = 0; + bp->b_flags = 0; + bp->b_error = 0; + BUF_LOCK(bp, LK_EXCLUSIVE); } /* @@ -448,8 +452,7 @@ relpbuf(bp, pfreecnt) if (bp->b_vp) pbrelvp(bp); - if (bp->b_flags & B_WANTED) - wakeup(bp); + BUF_UNLOCK(bp); TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist); @@ -499,8 +502,8 @@ vm_pager_chain_iodone(struct buf *nbp) } nbp->b_chain.parent = NULL; --bp->b_chain.count; - if (bp->b_flags & B_WANTED) { - bp->b_flags &= ~B_WANTED; + if (bp->b_flags & B_WANT) { + bp->b_flags &= ~B_WANT; wakeup(bp); } if (!bp->b_chain.count && (bp->b_flags & B_AUTOCHAINDONE)) { @@ -513,7 +516,7 @@ vm_pager_chain_iodone(struct buf *nbp) } } nbp->b_flags |= B_DONE; - nbp->b_flags &= ~(B_ASYNC|B_WANTED); + nbp->b_flags &= ~B_ASYNC; relpbuf(nbp, NULL); } @@ -539,7 +542,7 @@ getchainbuf(struct buf *bp, struct vnode *vp, int flags) if (bp->b_chain.count > 4) waitchainbuf(bp, 4, 0); - nbp->b_flags = B_BUSY | B_CALL | (bp->b_flags & B_ORDERED) | flags; + nbp->b_flags = B_CALL | (bp->b_flags & B_ORDERED) | flags; nbp->b_rcred = nbp->b_wcred = proc0.p_ucred; nbp->b_iodone = vm_pager_chain_iodone; @@ -571,7 +574,7 @@ waitchainbuf(struct buf *bp, int count, int done) s = splbio(); while (bp->b_chain.count > count) { - bp->b_flags |= B_WANTED; + bp->b_flags |= B_WANT; tsleep(bp, PRIBIO + 4, "bpchain", 0); } if (done) { diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index aefeb776135d..5af762df4767 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vm_swap.c 8.5 (Berkeley) 2/17/94 - * $Id: vm_swap.c,v 1.70 1999/05/31 11:29:30 phk Exp $ + * $Id: vm_swap.c,v 1.71 1999/06/01 17:11:27 phk Exp $ */ #include "opt_devfs.h" @@ -116,7 +116,7 @@ int vm_swap_size; * * Perform swap strategy interleave device selection * - * The bp is expected to be B_BUSY and *not* B_DONE on call. + * The bp is expected to be locked and *not* B_DONE on call. */ static void diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 4488697dacdf..1115ba93fcd0 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -38,7 +38,7 @@ * SUCH DAMAGE. * * from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91 - * $Id: vnode_pager.c,v 1.109 1999/05/06 20:00:34 phk Exp $ + * $Id: vnode_pager.c,v 1.110 1999/05/15 23:42:39 dt Exp $ */ /* @@ -407,7 +407,7 @@ vnode_pager_input_smlfs(object, m) bp = getpbuf(&vnode_pbuf_freecnt); /* build a minimal buffer header */ - bp->b_flags = B_BUSY | B_READ | B_CALL; + bp->b_flags = B_READ | B_CALL; bp->b_iodone = vnode_pager_iodone; bp->b_rcred = bp->b_wcred = curproc->p_ucred; if (bp->b_rcred != NOCRED) @@ -722,7 +722,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage) pmap_qenter(kva, m, count); /* build a minimal buffer header */ - bp->b_flags = B_BUSY | B_READ | B_CALL; + bp->b_flags = B_READ | B_CALL; bp->b_iodone = vnode_pager_iodone; /* B_PHYS is not set, but it is nice to fill this in */ bp->b_rcred = bp->b_wcred = curproc->p_ucred;