- Add a missing g_io_deliver() in case of allocation failure - we didn't
completed I/O requests here. - First allocate all needed bios, so if any of allocations fail, we can free memory before sending any I/O requests down. Reported by: Pawel Malachowski MFC after: 3 days
This commit is contained in:
parent
fa13a39e3c
commit
7e0b3120e7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=144592
@ -213,6 +213,7 @@ g_concat_access(struct g_provider *pp, int dr, int dw, int de)
|
||||
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,17 @@ g_concat_start(struct bio *bp)
|
||||
|
||||
cbp = g_clone_bio(bp);
|
||||
if (cbp == NULL) {
|
||||
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 +286,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
|
||||
|
Loading…
Reference in New Issue
Block a user