summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-09-13 11:28:31 +0000
committerphk <phk@FreeBSD.org>2002-09-13 11:28:31 +0000
commit725daf0b2d98322fdc86d273333bdbc9b7d1a526 (patch)
tree9f94a84da337f90a627c0c82f184c5422f3616d9 /sys/kern
parent4e012cc1d4cadfedb14e953bbc71f695e9a03782 (diff)
downloadFreeBSD-src-725daf0b2d98322fdc86d273333bdbc9b7d1a526.zip
FreeBSD-src-725daf0b2d98322fdc86d273333bdbc9b7d1a526.tar.gz
Oops, broke the build there. Uninline biodone() now that it is non-trivial.
Introduce biowait() function. Currently there is a race condition and the mitigation is a timeout/retry. It is not obvious what kind of locking (if any) is suitable for BIO_DONE, since the majority of users take are of this themselves, and only a few places actually rely on the wakeup. Sponsored by: DARPA & NAI Labs.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_bio.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index d5e5898..8490644 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -2805,6 +2805,34 @@ allocbuf(struct buf *bp, int size)
return 1;
}
+void
+biodone(struct bio *bp)
+{
+ bp->bio_flags |= BIO_DONE;
+ if (bp->bio_done != NULL)
+ bp->bio_done(bp);
+ else
+ wakeup(bp);
+}
+
+/*
+ * Wait for a BIO to finish.
+ * XXX: For now resort to a timeout, the optimal locking (if any) for this
+ * case is not at this point obvious.
+ */
+int
+biowait(struct bio *bp, const char *wchan)
+{
+
+ while ((bp->bio_flags & BIO_DONE) == 0)
+ msleep(bp, NULL, 0, wchan, hz);
+ if (!(bp->bio_flags & BIO_ERROR))
+ return (0);
+ if (bp->bio_error)
+ return (bp->bio_error);
+ return (EIO);
+}
+
/*
* bufwait:
*
OpenPOWER on IntegriCloud