Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/eli/g_eli_privacy.c
Show All 32 Lines | |||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/linker.h> | #include <sys/linker.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/bio.h> | #include <sys/bio.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/malloc.h> | |||||
#include <sys/kthread.h> | #include <sys/kthread.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/sched.h> | #include <sys/sched.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <vm/uma.h> | #include <vm/uma.h> | ||||
#include <geom/geom.h> | #include <geom/geom.h> | ||||
#include <geom/geom_dbg.h> | #include <geom/geom_dbg.h> | ||||
#include <geom/eli/g_eli.h> | #include <geom/eli/g_eli.h> | ||||
#include <geom/eli/pkcs5v2.h> | #include <geom/eli/pkcs5v2.h> | ||||
/* | /* | ||||
* Code paths: | * Code paths: | ||||
* BIO_READ: | * BIO_READ: | ||||
* g_eli_start -> g_eli_crypto_read -> g_io_request -> g_eli_read_done -> g_eli_crypto_run -> g_eli_crypto_read_done -> g_io_deliver | * g_eli_start -> g_eli_crypto_read -> g_io_request -> g_eli_read_done -> g_eli_crypto_run -> g_eli_crypto_read_done -> g_io_deliver | ||||
* BIO_WRITE: | * BIO_WRITE: | ||||
* g_eli_start -> g_eli_crypto_run -> g_eli_crypto_write_done -> g_io_request -> g_eli_write_done -> g_io_deliver | * g_eli_start -> g_eli_crypto_run -> g_eli_crypto_write_done -> g_io_request -> g_eli_write_done -> g_io_deliver | ||||
*/ | */ | ||||
MALLOC_DECLARE(M_ELI); | |||||
/* | /* | ||||
* The function is called after we read and decrypt data. | * The function is called after we read and decrypt data. | ||||
* | * | ||||
* g_eli_start -> g_eli_crypto_read -> g_io_request -> g_eli_read_done -> g_eli_crypto_run -> G_ELI_CRYPTO_READ_DONE -> g_io_deliver | * g_eli_start -> g_eli_crypto_read -> g_io_request -> g_eli_read_done -> g_eli_crypto_run -> G_ELI_CRYPTO_READ_DONE -> g_io_deliver | ||||
*/ | */ | ||||
static int | static int | ||||
g_eli_crypto_read_done(struct cryptop *crp) | g_eli_crypto_read_done(struct cryptop *crp) | ||||
{ | { | ||||
Show All 20 Lines | g_eli_crypto_read_done(struct cryptop *crp) | ||||
if (sc != NULL && crp->crp_cipher_key != NULL) | if (sc != NULL && crp->crp_cipher_key != NULL) | ||||
g_eli_key_drop(sc, __DECONST(void *, crp->crp_cipher_key)); | g_eli_key_drop(sc, __DECONST(void *, crp->crp_cipher_key)); | ||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||
/* | /* | ||||
* Do we have all sectors already? | * Do we have all sectors already? | ||||
*/ | */ | ||||
if (bp->bio_inbed < bp->bio_children) | if (bp->bio_inbed < bp->bio_children) | ||||
return (0); | return (0); | ||||
free(bp->bio_driver2, M_ELI); | g_eli_free_data(bp); | ||||
bp->bio_driver2 = NULL; | |||||
if (bp->bio_error != 0) { | if (bp->bio_error != 0) { | ||||
G_ELI_LOGREQ(0, bp, "Crypto READ request failed (error=%d).", | G_ELI_LOGREQ(0, bp, "Crypto READ request failed (error=%d).", | ||||
bp->bio_error); | bp->bio_error); | ||||
bp->bio_completed = 0; | bp->bio_completed = 0; | ||||
} | } | ||||
/* | /* | ||||
* Read is finished, send it up. | * Read is finished, send it up. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (bp->bio_inbed < bp->bio_children) | ||||
return (0); | return (0); | ||||
bp->bio_inbed = 0; | bp->bio_inbed = 0; | ||||
bp->bio_children = 1; | bp->bio_children = 1; | ||||
cbp = bp->bio_driver1; | cbp = bp->bio_driver1; | ||||
bp->bio_driver1 = NULL; | bp->bio_driver1 = NULL; | ||||
if (bp->bio_error != 0) { | if (bp->bio_error != 0) { | ||||
G_ELI_LOGREQ(0, bp, "Crypto WRITE request failed (error=%d).", | G_ELI_LOGREQ(0, bp, "Crypto WRITE request failed (error=%d).", | ||||
bp->bio_error); | bp->bio_error); | ||||
free(bp->bio_driver2, M_ELI); | g_eli_free_data(bp); | ||||
bp->bio_driver2 = NULL; | |||||
g_destroy_bio(cbp); | g_destroy_bio(cbp); | ||||
g_io_deliver(bp, bp->bio_error); | g_io_deliver(bp, bp->bio_error); | ||||
atomic_subtract_int(&sc->sc_inflight, 1); | atomic_subtract_int(&sc->sc_inflight, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
cbp->bio_data = bp->bio_driver2; | cbp->bio_data = bp->bio_driver2; | ||||
cbp->bio_done = g_eli_write_done; | cbp->bio_done = g_eli_write_done; | ||||
cp = LIST_FIRST(&gp->consumer); | cp = LIST_FIRST(&gp->consumer); | ||||
Show All 32 Lines | if (sc->sc_flags & G_ELI_FLAG_SUSPEND) { | ||||
bioq_insert_tail(&sc->sc_queue, bp); | bioq_insert_tail(&sc->sc_queue, bp); | ||||
mtx_unlock(&sc->sc_queue_mtx); | mtx_unlock(&sc->sc_queue_mtx); | ||||
wakeup(sc); | wakeup(sc); | ||||
return; | return; | ||||
} | } | ||||
atomic_add_int(&sc->sc_inflight, 1); | atomic_add_int(&sc->sc_inflight, 1); | ||||
mtx_unlock(&sc->sc_queue_mtx); | mtx_unlock(&sc->sc_queue_mtx); | ||||
} | } | ||||
bp->bio_pflags = 0; | G_ELI_SETWORKER(bp->bio_pflags, 0); | ||||
bp->bio_driver2 = NULL; | bp->bio_driver2 = NULL; | ||||
cbp = bp->bio_driver1; | cbp = bp->bio_driver1; | ||||
cbp->bio_done = g_eli_read_done; | cbp->bio_done = g_eli_read_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; | ||||
G_ELI_LOGREQ(2, cbp, "Sending request."); | G_ELI_LOGREQ(2, cbp, "Sending request."); | ||||
/* | /* | ||||
* Read encrypted data from provider. | * Read encrypted data from provider. | ||||
Show All 17 Lines | g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) | ||||
struct cryptop *crp; | struct cryptop *crp; | ||||
u_int i, nsec, secsize; | u_int i, nsec, secsize; | ||||
off_t dstoff; | off_t dstoff; | ||||
u_char *data; | u_char *data; | ||||
int error; | int error; | ||||
G_ELI_LOGREQ(3, bp, "%s", __func__); | G_ELI_LOGREQ(3, bp, "%s", __func__); | ||||
bp->bio_pflags = wr->w_number; | G_ELI_SETWORKER(bp->bio_pflags, wr->w_number); | ||||
sc = wr->w_softc; | sc = wr->w_softc; | ||||
secsize = LIST_FIRST(&sc->sc_geom->provider)->sectorsize; | secsize = LIST_FIRST(&sc->sc_geom->provider)->sectorsize; | ||||
nsec = bp->bio_length / secsize; | nsec = bp->bio_length / secsize; | ||||
bp->bio_inbed = 0; | bp->bio_inbed = 0; | ||||
bp->bio_children = nsec; | bp->bio_children = nsec; | ||||
/* | /* | ||||
* If we write the data we cannot destroy current bio_data content, | * If we write the data we cannot destroy current bio_data content, | ||||
* so we need to allocate more memory for encrypted data. | * so we need to allocate more memory for encrypted data. | ||||
*/ | */ | ||||
if (bp->bio_cmd == BIO_WRITE && !g_eli_alloc_data(bp, bp->bio_length)) { | |||||
G_ELI_LOGREQ(0, bp, "Crypto request failed (ENOMEM)."); | |||||
if (bp->bio_driver1 != NULL) { | |||||
g_destroy_bio(bp->bio_driver1); | |||||
bp->bio_driver1 = NULL; | |||||
} | |||||
bp->bio_error = ENOMEM; | |||||
g_io_deliver(bp, bp->bio_error); | |||||
if (sc != NULL) | |||||
atomic_subtract_int(&sc->sc_inflight, 1); | |||||
return; | |||||
} | |||||
if (bp->bio_cmd == BIO_WRITE) { | if (bp->bio_cmd == BIO_WRITE) { | ||||
data = malloc(bp->bio_length, M_ELI, M_WAITOK); | data = bp->bio_driver2; | ||||
bp->bio_driver2 = data; | |||||
bcopy(bp->bio_data, data, bp->bio_length); | bcopy(bp->bio_data, data, bp->bio_length); | ||||
} else | } else | ||||
data = bp->bio_data; | data = bp->bio_data; | ||||
for (i = 0, dstoff = bp->bio_offset; i < nsec; i++, dstoff += secsize) { | for (i = 0, dstoff = bp->bio_offset; i < nsec; i++, dstoff += secsize) { | ||||
crp = crypto_getreq(wr->w_sid, M_WAITOK); | crp = crypto_getreq(wr->w_sid, M_WAITOK); | ||||
crp->crp_ilen = secsize; | crp->crp_ilen = secsize; | ||||
Show All 30 Lines |