Implement BIO_FLUSH handling by simply passing it down to the components.
Sponsored by: home.pl
This commit is contained in:
parent
51fb042070
commit
c33849dc41
@ -211,6 +211,42 @@ g_concat_access(struct g_provider *pp, int dr, int dw, int de)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
g_concat_flush(struct g_concat_softc *sc, struct bio *bp)
|
||||
{
|
||||
struct bio_queue_head queue;
|
||||
struct g_consumer *cp;
|
||||
struct bio *cbp;
|
||||
u_int no;
|
||||
|
||||
bioq_init(&queue);
|
||||
for (no = 0; no < sc->sc_ndisks; no++) {
|
||||
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 = sc->sc_disks[no].d_consumer;
|
||||
cbp->bio_to = sc->sc_disks[no].d_consumer->provider;
|
||||
}
|
||||
for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) {
|
||||
bioq_remove(&queue, cbp);
|
||||
G_CONCAT_LOGREQ(cbp, "Sending request.");
|
||||
cp = cbp->bio_caller1;
|
||||
cbp->bio_caller1 = NULL;
|
||||
g_io_request(cbp, cp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_concat_start(struct bio *bp)
|
||||
{
|
||||
@ -240,6 +276,9 @@ g_concat_start(struct bio *bp)
|
||||
case BIO_WRITE:
|
||||
case BIO_DELETE:
|
||||
break;
|
||||
case BIO_FLUSH:
|
||||
g_concat_flush(sc, bp);
|
||||
return;
|
||||
case BIO_GETATTR:
|
||||
/* To which provider it should be delivered? */
|
||||
default:
|
||||
|
@ -258,6 +258,7 @@ g_eli_start(struct bio *bp)
|
||||
case BIO_READ:
|
||||
case BIO_WRITE:
|
||||
case BIO_GETATTR:
|
||||
case BIO_FLUSH:
|
||||
break;
|
||||
case BIO_DELETE:
|
||||
/*
|
||||
@ -298,6 +299,7 @@ g_eli_start(struct bio *bp)
|
||||
wakeup(sc);
|
||||
break;
|
||||
case BIO_GETATTR:
|
||||
case BIO_FLUSH:
|
||||
cbp->bio_done = g_std_done;
|
||||
cp = LIST_FIRST(&sc->sc_geom->consumer);
|
||||
cbp->bio_to = cp->provider;
|
||||
|
@ -260,6 +260,8 @@ g_slice_start(struct bio *bp)
|
||||
gkd->length = gsp->slices[idx].length;
|
||||
/* now, pass it on downwards... */
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case BIO_FLUSH:
|
||||
bp2 = g_clone_bio(bp);
|
||||
if (bp2 == NULL) {
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
|
@ -1041,6 +1041,48 @@ g_mirror_kernel_dump(struct bio *bp)
|
||||
g_mirror_get_diskname(disk));
|
||||
}
|
||||
|
||||
static void
|
||||
g_mirror_flush(struct g_mirror_softc *sc, struct bio *bp)
|
||||
{
|
||||
struct bio_queue_head queue;
|
||||
struct g_mirror_disk *disk;
|
||||
struct g_consumer *cp;
|
||||
struct bio *cbp;
|
||||
|
||||
bioq_init(&queue);
|
||||
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
|
||||
if (disk->d_state != G_MIRROR_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_MIRROR_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_mirror_start(struct bio *bp)
|
||||
{
|
||||
@ -1061,6 +1103,9 @@ g_mirror_start(struct bio *bp)
|
||||
case BIO_WRITE:
|
||||
case BIO_DELETE:
|
||||
break;
|
||||
case BIO_FLUSH:
|
||||
g_mirror_flush(sc, bp);
|
||||
return;
|
||||
case BIO_GETATTR:
|
||||
if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
|
||||
g_mirror_kernel_dump(bp);
|
||||
|
@ -1369,6 +1369,50 @@ g_raid3_sync_done(struct bio *bp)
|
||||
mtx_unlock(&sc->sc_queue_mtx);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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);
|
||||
|
@ -519,6 +519,42 @@ g_stripe_start_economic(struct bio *bp, u_int no, off_t offset, off_t length)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
g_stripe_flush(struct g_stripe_softc *sc, struct bio *bp)
|
||||
{
|
||||
struct bio_queue_head queue;
|
||||
struct g_consumer *cp;
|
||||
struct bio *cbp;
|
||||
u_int no;
|
||||
|
||||
bioq_init(&queue);
|
||||
for (no = 0; no < sc->sc_ndisks; no++) {
|
||||
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 = sc->sc_disks[no];
|
||||
cbp->bio_to = sc->sc_disks[no]->provider;
|
||||
}
|
||||
for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) {
|
||||
bioq_remove(&queue, cbp);
|
||||
G_STRIPE_LOGREQ(cbp, "Sending request.");
|
||||
cp = cbp->bio_caller1;
|
||||
cbp->bio_caller1 = NULL;
|
||||
g_io_request(cbp, cp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_stripe_start(struct bio *bp)
|
||||
{
|
||||
@ -542,10 +578,10 @@ g_stripe_start(struct bio *bp)
|
||||
case BIO_READ:
|
||||
case BIO_WRITE:
|
||||
case BIO_DELETE:
|
||||
/*
|
||||
* Only those requests are supported.
|
||||
*/
|
||||
break;
|
||||
case BIO_FLUSH:
|
||||
g_stripe_flush(sc, bp);
|
||||
return;
|
||||
case BIO_GETATTR:
|
||||
/* To which provider it should be delivered? */
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user