summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPedro Martelletto <pedro@cvs.openbsd.org>2006-08-09 12:00:04 +0000
committerPedro Martelletto <pedro@cvs.openbsd.org>2006-08-09 12:00:04 +0000
commitd7c6f6ee0f54bad44c5bd3404c235712a18369de (patch)
treec63437e5770d3cb351469e8357694b50e63b345a /sys
parent4c9478e8d0700e3f336fb7039ec8121ad84c8947 (diff)
Propagate error on getnewbuf(), effectively allowing callers to be
notified of posted signals for the current process, okay tedu@. Based on initial diagnosis by R. Tyler Ballance <tyler@bleepsoft.com>
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_bio.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 6fdd92d97c8..466a7439583 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_bio.c,v 1.80 2006/04/24 15:08:48 pedro Exp $ */
+/* $OpenBSD: vfs_bio.c,v 1.81 2006/08/09 12:00:03 pedro Exp $ */
/* $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $ */
/*-
@@ -102,7 +102,7 @@ struct pool bufpool;
#define binstailfree(bp, dp) TAILQ_INSERT_TAIL(dp, bp, b_freelist)
static __inline struct buf *bio_doread(struct vnode *, daddr_t, int, int);
-struct buf *getnewbuf(int slpflag, int slptimeo);
+struct buf *getnewbuf(int, int, int *);
/*
* We keep a few counters to monitor the utilization of the buffer cache
@@ -599,7 +599,7 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo)
{
struct bufhashhdr *bh;
struct buf *bp;
- int s, err;
+ int s, error;
/*
* XXX
@@ -620,10 +620,10 @@ start:
s = splbio();
if (ISSET(bp->b_flags, B_BUSY)) {
SET(bp->b_flags, B_WANTED);
- err = tsleep(bp, slpflag | (PRIBIO + 1), "getblk",
+ error = tsleep(bp, slpflag | (PRIBIO + 1), "getblk",
slptimeo);
splx(s);
- if (err)
+ if (error)
return (NULL);
goto start;
}
@@ -638,8 +638,13 @@ start:
}
if (bp == NULL) {
- if ((bp = getnewbuf(slpflag, slptimeo)) == NULL)
+ bp = getnewbuf(slpflag, slptimeo, &error);
+ if (bp == NULL) {
+ if (error == ERESTART || error == EINTR)
+ return (NULL);
goto start;
+ }
+
binshash(bp, bh);
bp->b_blkno = bp->b_lblkno = blkno;
s = splbio();
@@ -659,7 +664,7 @@ geteblk(int size)
{
struct buf *bp;
- while ((bp = getnewbuf(0, 0)) == NULL)
+ while ((bp = getnewbuf(0, 0, NULL)) == NULL)
;
SET(bp->b_flags, B_INVAL);
binshash(bp, &invalhash);
@@ -699,7 +704,7 @@ allocbuf(struct buf *bp, int size)
int amt;
/* find a buffer */
- while ((nbp = getnewbuf(0, 0)) == NULL)
+ while ((nbp = getnewbuf(0, 0, NULL)) == NULL)
;
SET(nbp->b_flags, B_INVAL);
binshash(nbp, &invalhash);
@@ -760,10 +765,10 @@ out:
* Find a buffer which is available for use.
*/
struct buf *
-getnewbuf(int slpflag, int slptimeo)
+getnewbuf(int slpflag, int slptimeo, int *ep)
{
struct buf *bp;
- int s;
+ int s, error;
s = splbio();
/*
@@ -775,15 +780,23 @@ getnewbuf(int slpflag, int slptimeo)
if ((numcleanpages <= locleanpages) &&
curproc != syncerproc && curproc != cleanerproc) {
needbuffer++;
- tsleep(&needbuffer, slpflag|(PRIBIO+1), "getnewbuf", slptimeo);
+ error = tsleep(&needbuffer, slpflag | (PRIBIO + 1),
+ "getnewbuf", slptimeo);
splx(s);
+ if (ep != NULL)
+ *ep = error;
return (NULL);
}
- if ((bp = TAILQ_FIRST(&bufqueues[BQ_CLEAN])) == NULL) {
+
+ bp = TAILQ_FIRST(&bufqueues[BQ_CLEAN]);
+ if (bp == NULL) {
/* wait for a free buffer of any kind */
nobuffers = 1;
- tsleep(&nobuffers, slpflag|(PRIBIO-3), "getnewbuf", slptimeo);
+ error = tsleep(&nobuffers, slpflag | (PRIBIO - 3),
+ "getnewbuf", slptimeo);
splx(s);
+ if (ep != NULL)
+ *ep = error;
return (NULL);
}