summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>1999-06-26 02:47:16 +0000
committermckusick <mckusick@FreeBSD.org>1999-06-26 02:47:16 +0000
commit5b58f2f951911f1075788268f99efccf1dba60eb (patch)
tree3f01ed42f71231eaa6a8cfa08b267634f1923fb1 /sys/kern
parent3213b13650cb2206bbd62b5b1764d148750f63a0 (diff)
downloadFreeBSD-src-5b58f2f951911f1075788268f99efccf1dba60eb.zip
FreeBSD-src-5b58f2f951911f1075788268f99efccf1dba60eb.tar.gz
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.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_lock.c20
-rw-r--r--sys/kern/kern_physio.c28
-rw-r--r--sys/kern/kern_shutdown.c19
-rw-r--r--sys/kern/subr_disklabel.c10
-rw-r--r--sys/kern/subr_diskmbr.c6
-rw-r--r--sys/kern/subr_dkbad.c4
-rw-r--r--sys/kern/vfs_aio.c4
-rw-r--r--sys/kern/vfs_bio.c109
-rw-r--r--sys/kern/vfs_cluster.c35
-rw-r--r--sys/kern/vfs_export.c51
-rw-r--r--sys/kern/vfs_subr.c51
11 files changed, 171 insertions, 166 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 3dde4b8..c7e9c84 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);
@@ -518,6 +519,21 @@ lockstatus(lkp)
}
/*
+ * 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 5f685b5..2208319 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 <sys/param.h>
@@ -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;i<uio->uio_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 e01b815..52c3f29 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 33f1d2a..21088cb 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 <sys/param.h>
@@ -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 @@ done:
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 c05e66b..a7b6b24 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 <sys/param.h>
@@ -181,7 +181,7 @@ reread_mbr:
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 c020254..bbb18dd 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 <sys/param.h>
@@ -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 04d9de4..f5f9a20 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 4a7c2e4..48f2c38 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 @@ restart:
/*
* 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 @@ restart:
* 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 @@ restart:
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 @@ restart:
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 @@ loop:
* 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 @@ loop:
} 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 3674516..edbe37d 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;i<maxra;i++) {
+ for (i = 1; i < maxra; i++) {
if (!(tbp = incore(vp, lblkno+i))) {
break;
@@ -154,7 +154,7 @@ cluster_read(vp, filesize, lblkno, size, cred, totread, seqcount, bpp)
tbp->b_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 @@ single_block_read:
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 @@ single_block_read:
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 bb8fa53..2a94962 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 @@ restart:
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 @@ restart:
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 @@ restartsync:
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 bb8fa53..2a94962 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 @@ restart:
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 @@ restart:
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 @@ restartsync:
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 {
OpenPOWER on IntegriCloud