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);
|
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
|
static void
|
||||||
g_concat_start(struct bio *bp)
|
g_concat_start(struct bio *bp)
|
||||||
{
|
{
|
||||||
@ -240,6 +276,9 @@ g_concat_start(struct bio *bp)
|
|||||||
case BIO_WRITE:
|
case BIO_WRITE:
|
||||||
case BIO_DELETE:
|
case BIO_DELETE:
|
||||||
break;
|
break;
|
||||||
|
case BIO_FLUSH:
|
||||||
|
g_concat_flush(sc, bp);
|
||||||
|
return;
|
||||||
case BIO_GETATTR:
|
case BIO_GETATTR:
|
||||||
/* To which provider it should be delivered? */
|
/* To which provider it should be delivered? */
|
||||||
default:
|
default:
|
||||||
|
@ -258,6 +258,7 @@ g_eli_start(struct bio *bp)
|
|||||||
case BIO_READ:
|
case BIO_READ:
|
||||||
case BIO_WRITE:
|
case BIO_WRITE:
|
||||||
case BIO_GETATTR:
|
case BIO_GETATTR:
|
||||||
|
case BIO_FLUSH:
|
||||||
break;
|
break;
|
||||||
case BIO_DELETE:
|
case BIO_DELETE:
|
||||||
/*
|
/*
|
||||||
@ -298,6 +299,7 @@ g_eli_start(struct bio *bp)
|
|||||||
wakeup(sc);
|
wakeup(sc);
|
||||||
break;
|
break;
|
||||||
case BIO_GETATTR:
|
case BIO_GETATTR:
|
||||||
|
case BIO_FLUSH:
|
||||||
cbp->bio_done = g_std_done;
|
cbp->bio_done = g_std_done;
|
||||||
cp = LIST_FIRST(&sc->sc_geom->consumer);
|
cp = LIST_FIRST(&sc->sc_geom->consumer);
|
||||||
cbp->bio_to = cp->provider;
|
cbp->bio_to = cp->provider;
|
||||||
|
@ -260,6 +260,8 @@ g_slice_start(struct bio *bp)
|
|||||||
gkd->length = gsp->slices[idx].length;
|
gkd->length = gsp->slices[idx].length;
|
||||||
/* now, pass it on downwards... */
|
/* now, pass it on downwards... */
|
||||||
}
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case BIO_FLUSH:
|
||||||
bp2 = g_clone_bio(bp);
|
bp2 = g_clone_bio(bp);
|
||||||
if (bp2 == NULL) {
|
if (bp2 == NULL) {
|
||||||
g_io_deliver(bp, ENOMEM);
|
g_io_deliver(bp, ENOMEM);
|
||||||
|
@ -1041,6 +1041,48 @@ g_mirror_kernel_dump(struct bio *bp)
|
|||||||
g_mirror_get_diskname(disk));
|
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
|
static void
|
||||||
g_mirror_start(struct bio *bp)
|
g_mirror_start(struct bio *bp)
|
||||||
{
|
{
|
||||||
@ -1061,6 +1103,9 @@ g_mirror_start(struct bio *bp)
|
|||||||
case BIO_WRITE:
|
case BIO_WRITE:
|
||||||
case BIO_DELETE:
|
case BIO_DELETE:
|
||||||
break;
|
break;
|
||||||
|
case BIO_FLUSH:
|
||||||
|
g_mirror_flush(sc, bp);
|
||||||
|
return;
|
||||||
case BIO_GETATTR:
|
case BIO_GETATTR:
|
||||||
if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
|
if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
|
||||||
g_mirror_kernel_dump(bp);
|
g_mirror_kernel_dump(bp);
|
||||||
|
@ -1369,6 +1369,50 @@ g_raid3_sync_done(struct bio *bp)
|
|||||||
mtx_unlock(&sc->sc_queue_mtx);
|
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
|
static void
|
||||||
g_raid3_start(struct bio *bp)
|
g_raid3_start(struct bio *bp)
|
||||||
{
|
{
|
||||||
@ -1390,6 +1434,9 @@ g_raid3_start(struct bio *bp)
|
|||||||
case BIO_WRITE:
|
case BIO_WRITE:
|
||||||
case BIO_DELETE:
|
case BIO_DELETE:
|
||||||
break;
|
break;
|
||||||
|
case BIO_FLUSH:
|
||||||
|
g_raid3_flush(sc, bp);
|
||||||
|
return;
|
||||||
case BIO_GETATTR:
|
case BIO_GETATTR:
|
||||||
default:
|
default:
|
||||||
g_io_deliver(bp, EOPNOTSUPP);
|
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);
|
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
|
static void
|
||||||
g_stripe_start(struct bio *bp)
|
g_stripe_start(struct bio *bp)
|
||||||
{
|
{
|
||||||
@ -542,10 +578,10 @@ g_stripe_start(struct bio *bp)
|
|||||||
case BIO_READ:
|
case BIO_READ:
|
||||||
case BIO_WRITE:
|
case BIO_WRITE:
|
||||||
case BIO_DELETE:
|
case BIO_DELETE:
|
||||||
/*
|
|
||||||
* Only those requests are supported.
|
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
|
case BIO_FLUSH:
|
||||||
|
g_stripe_flush(sc, bp);
|
||||||
|
return;
|
||||||
case BIO_GETATTR:
|
case BIO_GETATTR:
|
||||||
/* To which provider it should be delivered? */
|
/* To which provider it should be delivered? */
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user