X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmd%2Fdm-crypt.c;h=bdc52d6922b7d998f27068cce53ededb302f0b09;hb=7616ee95f27a04fd5a6434e9ef4a82cec4b2807c;hp=1dc2c62200ee97b9b06cf406c7cbbd9f1eaa757d;hpb=98221eb757de03d9aa6262b1eded2be708640ccc;p=linux-2.6 diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 1dc2c62200..bdc52d6922 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -30,10 +30,9 @@ /* * per bio private data */ -struct crypt_io { +struct dm_crypt_io { struct dm_target *target; struct bio *base_bio; - struct bio *first_clone; struct work_struct work; atomic_t pending; int error; @@ -107,7 +106,7 @@ struct crypt_config { static struct kmem_cache *_crypt_io_pool; -static void clone_init(struct crypt_io *, struct bio *); +static void clone_init(struct dm_crypt_io *, struct bio *); /* * Different IV generation algorithms: @@ -122,6 +121,9 @@ static void clone_init(struct crypt_io *, struct bio *); * benbi: the 64-bit "big-endian 'narrow block'-count", starting at 1 * (needed for LRW-32-AES and possible other narrow block modes) * + * null: the initial vector is always zero. Provides compatibility with + * obsolete loop_fish2 devices. Do not use for new devices. + * * plumb: unimplemented, see: * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454 */ @@ -258,6 +260,13 @@ static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector) return 0; } +static int crypt_iv_null_gen(struct crypt_config *cc, u8 *iv, sector_t sector) +{ + memset(iv, 0, cc->iv_size); + + return 0; +} + static struct crypt_iv_operations crypt_iv_plain_ops = { .generator = crypt_iv_plain_gen }; @@ -274,6 +283,10 @@ static struct crypt_iv_operations crypt_iv_benbi_ops = { .generator = crypt_iv_benbi_gen }; +static struct crypt_iv_operations crypt_iv_null_ops = { + .generator = crypt_iv_null_gen +}; + static int crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out, struct scatterlist *in, unsigned int length, @@ -369,7 +382,7 @@ static int crypt_convert(struct crypt_config *cc, static void dm_crypt_bio_destructor(struct bio *bio) { - struct crypt_io *io = bio->bi_private; + struct dm_crypt_io *io = bio->bi_private; struct crypt_config *cc = io->target->private; bio_free(bio, cc->bs); @@ -380,9 +393,7 @@ static int crypt_convert(struct crypt_config *cc, * This should never violate the device limitations * May return a smaller bio when running out of pages */ -static struct bio * -crypt_alloc_buffer(struct crypt_io *io, unsigned int size, - struct bio *base_bio, unsigned int *bio_vec_idx) +static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size) { struct crypt_config *cc = io->target->private; struct bio *clone; @@ -390,27 +401,13 @@ crypt_alloc_buffer(struct crypt_io *io, unsigned int size, gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; unsigned int i; - if (base_bio) { - clone = bio_alloc_bioset(GFP_NOIO, base_bio->bi_max_vecs, cc->bs); - __bio_clone(clone, base_bio); - } else - clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); - + clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); if (!clone) return NULL; clone_init(io, clone); - /* if the last bio was not complete, continue where that one ended */ - clone->bi_idx = *bio_vec_idx; - clone->bi_vcnt = *bio_vec_idx; - clone->bi_size = 0; - clone->bi_flags &= ~(1 << BIO_SEG_VALID); - - /* clone->bi_idx pages have already been allocated */ - size -= clone->bi_idx * PAGE_SIZE; - - for (i = clone->bi_idx; i < nr_iovecs; i++) { + for (i = 0; i < nr_iovecs; i++) { struct bio_vec *bv = bio_iovec_idx(clone, i); bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask); @@ -422,7 +419,7 @@ crypt_alloc_buffer(struct crypt_io *io, unsigned int size, * return a partially allocated bio, the caller will then try * to allocate additional bios while submitting this partial bio */ - if ((i - clone->bi_idx) == (MIN_BIO_PAGES - 1)) + if (i == (MIN_BIO_PAGES - 1)) gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; bv->bv_offset = 0; @@ -441,12 +438,6 @@ crypt_alloc_buffer(struct crypt_io *io, unsigned int size, return NULL; } - /* - * Remember the last bio_vec allocated to be able - * to correctly continue after the splitting. - */ - *bio_vec_idx = clone->bi_vcnt; - return clone; } @@ -488,7 +479,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, * One of the bios was finished. Check for completion of * the whole request and correctly clean up the buffer. */ -static void dec_pending(struct crypt_io *io, int error) +static void dec_pending(struct dm_crypt_io *io, int error) { struct crypt_config *cc = (struct crypt_config *) io->target->private; @@ -498,9 +489,6 @@ static void dec_pending(struct crypt_io *io, int error) if (!atomic_dec_and_test(&io->pending)) return; - if (io->first_clone) - bio_put(io->first_clone); - bio_endio(io->base_bio, io->base_bio->bi_size, io->error); mempool_free(io, cc->io_pool); @@ -515,7 +503,7 @@ static void dec_pending(struct crypt_io *io, int error) static struct workqueue_struct *_kcryptd_workqueue; static void kcryptd_do_work(struct work_struct *work); -static void kcryptd_queue_io(struct crypt_io *io) +static void kcryptd_queue_io(struct dm_crypt_io *io) { INIT_WORK(&io->work, kcryptd_do_work); queue_work(_kcryptd_workqueue, &io->work); @@ -523,7 +511,7 @@ static void kcryptd_queue_io(struct crypt_io *io) static int crypt_endio(struct bio *clone, unsigned int done, int error) { - struct crypt_io *io = clone->bi_private; + struct dm_crypt_io *io = clone->bi_private; struct crypt_config *cc = io->target->private; unsigned read_io = bio_data_dir(clone) == READ; @@ -557,7 +545,7 @@ out: return error; } -static void clone_init(struct crypt_io *io, struct bio *clone) +static void clone_init(struct dm_crypt_io *io, struct bio *clone) { struct crypt_config *cc = io->target->private; @@ -568,7 +556,7 @@ static void clone_init(struct crypt_io *io, struct bio *clone) clone->bi_destructor = dm_crypt_bio_destructor; } -static void process_read(struct crypt_io *io) +static void process_read(struct dm_crypt_io *io) { struct crypt_config *cc = io->target->private; struct bio *base_bio = io->base_bio; @@ -599,7 +587,7 @@ static void process_read(struct crypt_io *io) generic_make_request(clone); } -static void process_write(struct crypt_io *io) +static void process_write(struct dm_crypt_io *io) { struct crypt_config *cc = io->target->private; struct bio *base_bio = io->base_bio; @@ -607,7 +595,6 @@ static void process_write(struct crypt_io *io) struct convert_context ctx; unsigned remaining = base_bio->bi_size; sector_t sector = base_bio->bi_sector - io->target->begin; - unsigned bvec_idx = 0; atomic_inc(&io->pending); @@ -618,14 +605,14 @@ static void process_write(struct crypt_io *io) * so repeat the whole process until all the data can be handled. */ while (remaining) { - clone = crypt_alloc_buffer(io, base_bio->bi_size, - io->first_clone, &bvec_idx); + clone = crypt_alloc_buffer(io, remaining); if (unlikely(!clone)) { dec_pending(io, -ENOMEM); return; } ctx.bio_out = clone; + ctx.idx_out = 0; if (unlikely(crypt_convert(cc, &ctx) < 0)) { crypt_free_buffer_pages(cc, clone, clone->bi_size); @@ -634,22 +621,15 @@ static void process_write(struct crypt_io *io) return; } - clone->bi_sector = cc->start + sector; - - if (!io->first_clone) { - /* - * hold a reference to the first clone, because it - * holds the bio_vec array and that can't be freed - * before all other clones are released - */ - bio_get(clone); - io->first_clone = clone; - } + /* crypt_convert should have filled the clone bio */ + BUG_ON(ctx.idx_out < clone->bi_vcnt); + clone->bi_sector = cc->start + sector; remaining -= clone->bi_size; sector += bio_sectors(clone); - /* prevent bio_put of first_clone */ + /* Grab another reference to the io struct + * before we kick off the request */ if (remaining) atomic_inc(&io->pending); @@ -664,7 +644,7 @@ static void process_write(struct crypt_io *io) } } -static void process_read_endio(struct crypt_io *io) +static void process_read_endio(struct dm_crypt_io *io) { struct crypt_config *cc = io->target->private; struct convert_context ctx; @@ -677,7 +657,7 @@ static void process_read_endio(struct crypt_io *io) static void kcryptd_do_work(struct work_struct *work) { - struct crypt_io *io = container_of(work, struct crypt_io, work); + struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); if (io->post_process) process_read_endio(io); @@ -837,6 +817,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->iv_gen_ops = &crypt_iv_essiv_ops; else if (strcmp(ivmode, "benbi") == 0) cc->iv_gen_ops = &crypt_iv_benbi_ops; + else if (strcmp(ivmode, "null") == 0) + cc->iv_gen_ops = &crypt_iv_null_ops; else { ti->error = "Invalid IV mode"; goto bad2; @@ -938,6 +920,8 @@ static void crypt_dtr(struct dm_target *ti) { struct crypt_config *cc = (struct crypt_config *) ti->private; + flush_workqueue(_kcryptd_workqueue); + bioset_free(cc->bs); mempool_destroy(cc->page_pool); mempool_destroy(cc->io_pool); @@ -957,15 +941,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) { struct crypt_config *cc = ti->private; - struct crypt_io *io; - - if (bio_barrier(bio)) - return -EOPNOTSUPP; + struct dm_crypt_io *io; io = mempool_alloc(cc->io_pool, GFP_NOIO); io->target = ti; io->base_bio = bio; - io->first_clone = NULL; io->error = io->post_process = 0; atomic_set(&io->pending, 0); kcryptd_queue_io(io); @@ -1065,7 +1045,7 @@ error: static struct target_type crypt_target = { .name = "crypt", - .version= {1, 3, 0}, + .version= {1, 5, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, @@ -1081,9 +1061,7 @@ static int __init dm_crypt_init(void) { int r; - _crypt_io_pool = kmem_cache_create("dm-crypt_io", - sizeof(struct crypt_io), - 0, 0, NULL, NULL); + _crypt_io_pool = KMEM_CACHE(dm_crypt_io, 0); if (!_crypt_io_pool) return -ENOMEM;