diff options
| author | Poul-Henning Kamp <phk@FreeBSD.org> | 2003-01-02 19:29:49 +0000 |
|---|---|---|
| committer | Poul-Henning Kamp <phk@FreeBSD.org> | 2003-01-02 19:29:49 +0000 |
| commit | acb161b16f126edbe5b62cbb7889f45a792fcd2a (patch) | |
| tree | 8f0633d36fb6b5dbfd94669025f89326b083770c | |
| parent | 777cc88b9d37909035f43622f29b15849009f1d4 (diff) | |
Notes
| -rw-r--r-- | sys/geom/bde/g_bde.h | 2 | ||||
| -rw-r--r-- | sys/geom/bde/g_bde_crypt.c | 93 | ||||
| -rw-r--r-- | sys/geom/bde/g_bde_work.c | 19 |
3 files changed, 66 insertions, 48 deletions
diff --git a/sys/geom/bde/g_bde.h b/sys/geom/bde/g_bde.h index c5f9bf5abb39..b162e9621803 100644 --- a/sys/geom/bde/g_bde.h +++ b/sys/geom/bde/g_bde.h @@ -161,7 +161,7 @@ void g_bde_hash_pass(struct g_bde_softc *sc, const void *input, u_int len); /* g_bde_math .c */ uint64_t g_bde_max_sector(struct g_bde_key *lp); -void g_bde_map_sector(struct g_bde_key *lp, uint64_t isector, uint64_t *osector, uint64_t *ksector, u_int *koffset); +void g_bde_map_sector(struct g_bde_work *wp); /* g_bde_work.c */ void g_bde_start1(struct bio *bp); diff --git a/sys/geom/bde/g_bde_crypt.c b/sys/geom/bde/g_bde_crypt.c index bd368d8162f3..ec58dbffdf07 100644 --- a/sys/geom/bde/g_bde_crypt.c +++ b/sys/geom/bde/g_bde_crypt.c @@ -245,8 +245,13 @@ g_bde_max_sector(struct g_bde_key *kp) * on a "cold" disk image. * * We do this by adding the "keyoffset" from the lock to the physical sector - * number modulus the available number of sectors, since all physical sectors - * presumably look the same cold, this should be enough. + * number modulus the available number of sectors. Since all physical sectors + * presumably look the same cold, this will do. + * + * As part of the mapping we have to skip the lock sectors which we know + * the physical address off. We also truncate the work packet, respecting + * zone boundaries and lock sectors, so that we end up with a sequence of + * sectors which are physically contiguous. * * Shuffling things further is an option, but the incremental frustration is * not currently deemed worth the run-time performance hit resulting from the @@ -257,52 +262,64 @@ g_bde_max_sector(struct g_bde_key *kp) */ void -g_bde_map_sector(struct g_bde_key *kp, - uint64_t isector, - uint64_t *osector, - uint64_t *ksector, - u_int *koffset) +g_bde_map_sector(struct g_bde_work *wp) { - u_int zone, zoff, zidx, u; - uint64_t os; + u_int zone, zoff, u, len; + uint64_t ko; + struct g_bde_softc *sc; + struct g_bde_key *kp; - /* find which zone and the offset and index in it */ - zone = isector / kp->zone_cont; - zoff = isector % kp->zone_cont; - zidx = zoff / kp->sectorsize; + sc = wp->softc; + kp = &sc->key; - /* Find physical sector address */ - os = zone * kp->zone_width + zoff; - os += kp->keyoffset; - os %= kp->media_width; - os += kp->sector0; + /* find which zone and the offset in it */ + zone = wp->offset / kp->zone_cont; + zoff = wp->offset % kp->zone_cont; - /* Compensate for lock sectors */ - for (u = 0; u < G_BDE_MAXKEYS; u++) - if (os >= (kp->lsector[u] & ~(kp->sectorsize - 1))) - os += kp->sectorsize; + /* Calculate the offset of the key in the key sector */ + wp->ko = (zoff / kp->sectorsize) * G_BDE_SKEYLEN; - *osector = os; + /* restrict length to that zone */ + len = kp->zone_cont - zoff; + if (len < wp->length) + wp->length = len; - /* The key sector is the last in this zone. */ - os = (1 + zone) * kp->zone_width - kp->sectorsize; - os += kp->keyoffset; - os %= kp->media_width; - os += kp->sector0; + /* Find physical sector address */ + wp->so = zone * kp->zone_width + zoff; + wp->so += kp->keyoffset; + wp->so %= kp->media_width; + wp->so += kp->sector0; - for (u = 0; u < G_BDE_MAXKEYS; u++) - if (os >= (kp->lsector[u] & ~(kp->sectorsize - 1))) - os += kp->sectorsize; - *ksector = os; + /* The key sector is the last in this zone. */ + wp->kso = zone * kp->zone_width + kp->zone_cont; + wp->kso += kp->keyoffset; + wp->kso %= kp->media_width; + wp->kso += kp->sector0; - *koffset = zidx * G_BDE_SKEYLEN; + /* Compensate for lock sectors */ + for (u = 0; u < G_BDE_MAXKEYS; u++) { + /* Find the start of this lock sector */ + ko = kp->lsector[u] & ~(kp->sectorsize - 1); + + if (wp->kso >= ko) + wp->kso += kp->sectorsize; + + if (wp->so >= ko) { + /* lock sector before work packet */ + wp->so += kp->sectorsize; + } else if ((wp->so + wp->length) > ko) { + /* lock sector in work packet, truncate */ + wp->length = ko - wp->so; + } + } #if 0 - printf("off %jd %jd %jd %u\n", - (intmax_t)isector, - (intmax_t)*osector, - (intmax_t)*ksector, - *koffset); + printf("off %jd len %jd so %jd ko %jd kso %u\n", + (intmax_t)wp->offset, + (intmax_t)wp->length, + (intmax_t)wp->so, + (intmax_t)wp->kso, + wp->ko); #endif } diff --git a/sys/geom/bde/g_bde_work.c b/sys/geom/bde/g_bde_work.c index e173d804aa07..3635869ae868 100644 --- a/sys/geom/bde/g_bde_work.c +++ b/sys/geom/bde/g_bde_work.c @@ -651,10 +651,9 @@ g_bde_start2(struct g_bde_work *wp) struct g_bde_softc *sc; KASSERT(wp != NULL, ("NULL wp in g_bde_start2")); + KASSERT(wp->softc != NULL, ("NULL wp->softc")); g_trace(G_T_TOPOLOGY, "g_bde_start2(%p)", wp); sc = wp->softc; - KASSERT(wp->softc != NULL, ("NULL wp->softc")); - g_bde_map_sector(&sc->key, wp->offset, &wp->so, &wp->kso, &wp->ko); if (wp->bp->bio_cmd == BIO_READ) { wp->sp = g_bde_new_sector(wp, 0); if (wp->sp == NULL) { @@ -704,8 +703,8 @@ g_bde_start2(struct g_bde_work *wp) } /* - * Split the incoming bio on zone boundaries and submit the resulting - * work structures to g_bde_start2(). + * Create a sequence of work structures, and have g_bde_map_sector() determine + * how long they each can be. Feed them to g_bde_start2(). */ void @@ -713,13 +712,13 @@ g_bde_start1(struct bio *bp) { struct g_bde_softc *sc; struct g_bde_work *wp; - off_t left; + off_t done; sc = bp->bio_to->geom->softc; bp->bio_driver1 = sc; mtx_lock(&sc->worklist_mutex); - for(left = 0;left < bp->bio_length; left += sc->sectorsize) { + for(done = 0; done < bp->bio_length; ) { wp = g_bde_new_work(sc); if (wp == NULL) { g_io_deliver(bp, ENOMEM); @@ -727,9 +726,11 @@ g_bde_start1(struct bio *bp) return; } wp->bp = bp; - wp->offset = bp->bio_offset + left; - wp->data = bp->bio_data + left; - wp->length = sc->sectorsize; + wp->offset = bp->bio_offset + done; + wp->data = bp->bio_data + done; + wp->length = bp->bio_length - done; + g_bde_map_sector(wp); + done += wp->length; g_bde_start2(wp); } mtx_unlock(&sc->worklist_mutex); |
