Index: g_concat.c =================================================================== RCS file: /usr/repo/src/sys/geom/concat/g_concat.c,v retrieving revision 1.23 diff -u -p -r1.23 g_concat.c --- g_concat.c 27 Feb 2005 23:07:46 -0000 1.23 +++ g_concat.c 3 Apr 2005 14:22:21 -0000 @@ -213,6 +213,7 @@ g_concat_access(struct g_provider *pp, i static void g_concat_start(struct bio *bp) { + struct bio_queue_head queue; struct g_concat_softc *sc; struct g_concat_disk *disk; struct g_provider *pp; @@ -250,6 +251,7 @@ g_concat_start(struct bio *bp) addr = bp->bio_data; end = offset + length; + bioq_init(&queue); for (no = 0; no < sc->sc_ndisks; no++) { disk = &sc->sc_disks[no]; if (disk->d_end <= offset) @@ -264,10 +266,18 @@ g_concat_start(struct bio *bp) cbp = g_clone_bio(bp); if (cbp == NULL) { + G_CONCAT_DEBUG(0, "Cannot allocate bio!"); + for (cbp = bioq_first(&queue); cbp != NULL; + cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + g_destroy_bio(cbp); + } if (bp->bio_error == 0) bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); return; } + bioq_insert_tail(&queue, cbp); /* * Fill in the component buf structure. */ @@ -277,16 +287,21 @@ g_concat_start(struct bio *bp) addr += len; cbp->bio_length = len; cbp->bio_to = disk->d_consumer->provider; - G_CONCAT_LOGREQ(cbp, "Sending request."); - g_io_request(cbp, disk->d_consumer); + cbp->bio_caller1 = disk; if (length == 0) break; } - KASSERT(length == 0, ("Length is still greater than 0 (class=%s, name=%s).", bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + G_CONCAT_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } } static void