diff options
author | pjd <pjd@FreeBSD.org> | 2006-10-31 21:23:51 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-10-31 21:23:51 +0000 |
commit | c33849dc41d24ae1362682bce0b8ebce43af556a (patch) | |
tree | e1cf58f0328589a697dacbff3b7e0c1982735a33 /sys/geom/raid3 | |
parent | 51fb042070317c283395fd7170157adbbc879898 (diff) | |
download | FreeBSD-src-c33849dc41d24ae1362682bce0b8ebce43af556a.zip FreeBSD-src-c33849dc41d24ae1362682bce0b8ebce43af556a.tar.gz |
Implement BIO_FLUSH handling by simply passing it down to the components.
Sponsored by: home.pl
Diffstat (limited to 'sys/geom/raid3')
-rw-r--r-- | sys/geom/raid3/g_raid3.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index 66383bc..3cb1c6c 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -1370,6 +1370,50 @@ g_raid3_sync_done(struct bio *bp) } static void +g_raid3_flush(struct g_raid3_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_raid3_disk *disk; + struct g_consumer *cp; + struct bio *cbp; + u_int i; + + bioq_init(&queue); + for (i = 0; i < sc->sc_ndisks; i++) { + disk = &sc->sc_disks[i]; + if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) + continue; + 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); + cbp->bio_done = g_std_done; + cbp->bio_caller1 = disk; + cbp->bio_to = disk->d_consumer->provider; + } + for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + G_RAID3_LOGREQ(3, cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + cp = disk->d_consumer; + KASSERT(cp->acr >= 1 && cp->acw >= 1 && cp->ace >= 1, + ("Consumer %s not opened (r%dw%de%d).", cp->provider->name, + cp->acr, cp->acw, cp->ace)); + g_io_request(cbp, disk->d_consumer); + } +} + +static void g_raid3_start(struct bio *bp) { struct g_raid3_softc *sc; @@ -1390,6 +1434,9 @@ g_raid3_start(struct bio *bp) case BIO_WRITE: case BIO_DELETE: break; + case BIO_FLUSH: + g_raid3_flush(sc, bp); + return; case BIO_GETATTR: default: g_io_deliver(bp, EOPNOTSUPP); |