Changeset View
Changeset View
Standalone View
Standalone View
head/sys/geom/mirror/g_mirror.c
Show First 20 Lines • Show All 919 Lines • ▼ Show 20 Lines | g_mirror_done(struct bio *bp) | ||||
wakeup(sc); | wakeup(sc); | ||||
} | } | ||||
static void | static void | ||||
g_mirror_regular_request_error(struct g_mirror_softc *sc, | g_mirror_regular_request_error(struct g_mirror_softc *sc, | ||||
struct g_mirror_disk *disk, struct bio *bp) | struct g_mirror_disk *disk, struct bio *bp) | ||||
{ | { | ||||
if (bp->bio_cmd == BIO_FLUSH && bp->bio_error == EOPNOTSUPP) | if ((bp->bio_cmd == BIO_FLUSH || bp->bio_cmd == BIO_SPEEDUP) && | ||||
bp->bio_error == EOPNOTSUPP) | |||||
return; | return; | ||||
if ((disk->d_flags & G_MIRROR_DISK_FLAG_BROKEN) == 0) { | if ((disk->d_flags & G_MIRROR_DISK_FLAG_BROKEN) == 0) { | ||||
disk->d_flags |= G_MIRROR_DISK_FLAG_BROKEN; | disk->d_flags |= G_MIRROR_DISK_FLAG_BROKEN; | ||||
G_MIRROR_LOGREQ(0, bp, "Request failed (error=%d).", | G_MIRROR_LOGREQ(0, bp, "Request failed (error=%d).", | ||||
bp->bio_error); | bp->bio_error); | ||||
} else { | } else { | ||||
G_MIRROR_LOGREQ(1, bp, "Request failed (error=%d).", | G_MIRROR_LOGREQ(1, bp, "Request failed (error=%d).", | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | g_mirror_regular_request(struct g_mirror_softc *sc, struct bio *bp) | ||||
case BIO_DELETE: | case BIO_DELETE: | ||||
KFAIL_POINT_ERROR(DEBUG_FP, g_mirror_regular_request_delete, | KFAIL_POINT_ERROR(DEBUG_FP, g_mirror_regular_request_delete, | ||||
bp->bio_error); | bp->bio_error); | ||||
break; | break; | ||||
case BIO_FLUSH: | case BIO_FLUSH: | ||||
KFAIL_POINT_ERROR(DEBUG_FP, g_mirror_regular_request_flush, | KFAIL_POINT_ERROR(DEBUG_FP, g_mirror_regular_request_flush, | ||||
bp->bio_error); | bp->bio_error); | ||||
break; | break; | ||||
case BIO_SPEEDUP: | |||||
KFAIL_POINT_ERROR(DEBUG_FP, g_mirror_regular_request_speedup, | |||||
bp->bio_error); | |||||
break; | |||||
} | } | ||||
pbp->bio_inbed++; | pbp->bio_inbed++; | ||||
KASSERT(pbp->bio_inbed <= pbp->bio_children, | KASSERT(pbp->bio_inbed <= pbp->bio_children, | ||||
("bio_inbed (%u) is bigger than bio_children (%u).", pbp->bio_inbed, | ("bio_inbed (%u) is bigger than bio_children (%u).", pbp->bio_inbed, | ||||
pbp->bio_children)); | pbp->bio_children)); | ||||
if (bp->bio_error == 0 && pbp->bio_error == 0) { | if (bp->bio_error == 0 && pbp->bio_error == 0) { | ||||
G_MIRROR_LOGREQ(3, bp, "Request delivered."); | G_MIRROR_LOGREQ(3, bp, "Request delivered."); | ||||
Show All 14 Lines | if (bp->bio_error == 0 && pbp->bio_error == 0) { | ||||
if (pbp->bio_error == 0) | if (pbp->bio_error == 0) | ||||
pbp->bio_error = bp->bio_error; | pbp->bio_error = bp->bio_error; | ||||
if (disk != NULL) | if (disk != NULL) | ||||
g_mirror_regular_request_error(sc, disk, bp); | g_mirror_regular_request_error(sc, disk, bp); | ||||
switch (pbp->bio_cmd) { | switch (pbp->bio_cmd) { | ||||
case BIO_DELETE: | case BIO_DELETE: | ||||
case BIO_WRITE: | case BIO_WRITE: | ||||
case BIO_FLUSH: | case BIO_FLUSH: | ||||
case BIO_SPEEDUP: | |||||
pbp->bio_inbed--; | pbp->bio_inbed--; | ||||
pbp->bio_children--; | pbp->bio_children--; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
g_destroy_bio(bp); | g_destroy_bio(bp); | ||||
switch (pbp->bio_cmd) { | switch (pbp->bio_cmd) { | ||||
Show All 9 Lines | else { | ||||
mtx_unlock(&sc->sc_queue_mtx); | mtx_unlock(&sc->sc_queue_mtx); | ||||
G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc); | G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc); | ||||
wakeup(sc); | wakeup(sc); | ||||
} | } | ||||
break; | break; | ||||
case BIO_DELETE: | case BIO_DELETE: | ||||
case BIO_WRITE: | case BIO_WRITE: | ||||
case BIO_FLUSH: | case BIO_FLUSH: | ||||
case BIO_SPEEDUP: | |||||
if (pbp->bio_children == 0) { | if (pbp->bio_children == 0) { | ||||
/* | /* | ||||
* All requests failed. | * All requests failed. | ||||
*/ | */ | ||||
} else if (pbp->bio_inbed < pbp->bio_children) { | } else if (pbp->bio_inbed < pbp->bio_children) { | ||||
/* Do nothing. */ | /* Do nothing. */ | ||||
break; | break; | ||||
} else if (pbp->bio_children == pbp->bio_inbed) { | } else if (pbp->bio_children == pbp->bio_inbed) { | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | KASSERT(sc != NULL && sc->sc_state == G_MIRROR_DEVICE_STATE_RUNNING, | ||||
("Provider's error should be set (error=%d)(mirror=%s).", | ("Provider's error should be set (error=%d)(mirror=%s).", | ||||
bp->bio_to->error, bp->bio_to->name)); | bp->bio_to->error, bp->bio_to->name)); | ||||
G_MIRROR_LOGREQ(3, bp, "Request received."); | G_MIRROR_LOGREQ(3, bp, "Request received."); | ||||
switch (bp->bio_cmd) { | switch (bp->bio_cmd) { | ||||
case BIO_READ: | case BIO_READ: | ||||
case BIO_WRITE: | case BIO_WRITE: | ||||
case BIO_DELETE: | case BIO_DELETE: | ||||
case BIO_SPEEDUP: | |||||
case BIO_FLUSH: | case BIO_FLUSH: | ||||
break; | break; | ||||
case BIO_GETATTR: | case BIO_GETATTR: | ||||
if (!strcmp(bp->bio_attribute, "GEOM::candelete")) { | if (!strcmp(bp->bio_attribute, "GEOM::candelete")) { | ||||
g_mirror_candelete(bp); | g_mirror_candelete(bp); | ||||
return; | return; | ||||
} else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { | } else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { | ||||
g_mirror_kernel_dump(bp); | g_mirror_kernel_dump(bp); | ||||
▲ Show 20 Lines • Show All 618 Lines • ▼ Show 20 Lines | while ((cbp = TAILQ_FIRST(&queue)) != NULL) { | ||||
g_io_request(cbp, cp); | g_io_request(cbp, cp); | ||||
} | } | ||||
/* | /* | ||||
* Put request onto inflight queue, so we can check if new | * Put request onto inflight queue, so we can check if new | ||||
* synchronization requests don't collide with it. | * synchronization requests don't collide with it. | ||||
*/ | */ | ||||
TAILQ_INSERT_TAIL(&sc->sc_inflight, bp, bio_queue); | TAILQ_INSERT_TAIL(&sc->sc_inflight, bp, bio_queue); | ||||
return; | return; | ||||
case BIO_SPEEDUP: | |||||
case BIO_FLUSH: | case BIO_FLUSH: | ||||
TAILQ_INIT(&queue); | TAILQ_INIT(&queue); | ||||
LIST_FOREACH(disk, &sc->sc_disks, d_next) { | LIST_FOREACH(disk, &sc->sc_disks, d_next) { | ||||
if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE) | if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE) | ||||
continue; | continue; | ||||
cbp = g_clone_bio(bp); | cbp = g_clone_bio(bp); | ||||
if (cbp == NULL) { | if (cbp == NULL) { | ||||
while ((cbp = TAILQ_FIRST(&queue)) != NULL) { | while ((cbp = TAILQ_FIRST(&queue)) != NULL) { | ||||
▲ Show 20 Lines • Show All 1,780 Lines • Show Last 20 Lines |