summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-10-09 07:11:59 +0000
committerphk <phk@FreeBSD.org>2002-10-09 07:11:59 +0000
commit08c1778957b9ef53b1f7108cd793b43eb7c756b0 (patch)
treea44664bc7d5852c7393f6ea401ff5c37d19c26dc
parent32bc10e82a1e0e09a849279aa7935984a6de396e (diff)
downloadFreeBSD-src-08c1778957b9ef53b1f7108cd793b43eb7c756b0.zip
FreeBSD-src-08c1778957b9ef53b1f7108cd793b43eb7c756b0.tar.gz
Add support g_clone_bio() and g_std_done() to spawn multiple children
of a bio and correctly gather status when done. Sponsored by: DARPA & NAI Labs.
-rw-r--r--sys/geom/geom_io.c1
-rw-r--r--sys/geom/geom_subr.c10
2 files changed, 7 insertions, 4 deletions
diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c
index f1d21da..deb8978 100644
--- a/sys/geom/geom_io.c
+++ b/sys/geom/geom_io.c
@@ -151,6 +151,7 @@ g_clone_bio(struct bio *bp)
bp2->bio_offset = bp->bio_offset;
bp2->bio_data = bp->bio_data;
bp2->bio_attribute = bp->bio_attribute;
+ bp->bio_children++; /* XXX: atomic ? */
}
g_trace(G_T_BIO, "g_clone_bio(%p) = %p", bp, bp2);
return(bp2);
diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
index bfb0732..45130c6 100644
--- a/sys/geom/geom_subr.c
+++ b/sys/geom/geom_subr.c
@@ -495,13 +495,15 @@ void
g_std_done(struct bio *bp)
{
struct bio *bp2;
- int error;
bp2 = bp->bio_linkage;
- error = bp->bio_error;
- bp2->bio_completed = bp->bio_completed;
+ if (bp2->bio_error == 0)
+ bp2->bio_error = bp->bio_error;
+ bp2->bio_completed += bp->bio_completed;
g_destroy_bio(bp);
- g_io_deliver(bp2, error);
+ bp2->bio_children--; /* XXX: atomic ? */
+ if (bp2->bio_children == 0)
+ g_io_deliver(bp2, bp2->bio_error);
}
/* XXX: maybe this is only g_slice_spoiled */
OpenPOWER on IntegriCloud