aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 f1d21da524be..deb8978bf769 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 bfb07323a545..45130c6f8d94 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 */