diff options
Diffstat (limited to 'drivers/md/dm-verity-target.c')
-rw-r--r-- | drivers/md/dm-verity-target.c | 83 |
1 files changed, 41 insertions, 42 deletions
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index ccf5b852fbf7..ade83ef3b439 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -41,9 +41,9 @@ #define DM_VERITY_OPTS_MAX (4 + DM_VERITY_OPTS_FEC + \ DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) -static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; +static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; -module_param_named(prefetch_cluster, dm_verity_prefetch_cluster, uint, S_IRUGO | S_IWUSR); +module_param_named(prefetch_cluster, dm_verity_prefetch_cluster, uint, 0644); static DEFINE_STATIC_KEY_FALSE(use_tasklet_enabled); @@ -51,7 +51,7 @@ struct dm_verity_prefetch_work { struct work_struct work; struct dm_verity *v; sector_t block; - unsigned n_blocks; + unsigned int n_blocks; }; /* @@ -110,22 +110,24 @@ static int verity_hash_update(struct dm_verity *v, struct ahash_request *req, sg_init_one(&sg, data, len); ahash_request_set_crypt(req, &sg, NULL, len); return crypto_wait_req(crypto_ahash_update(req), wait); - } else { - do { - int r; - size_t this_step = min_t(size_t, len, PAGE_SIZE - offset_in_page(data)); - flush_kernel_vmap_range((void *)data, this_step); - sg_init_table(&sg, 1); - sg_set_page(&sg, vmalloc_to_page(data), this_step, offset_in_page(data)); - ahash_request_set_crypt(req, &sg, NULL, this_step); - r = crypto_wait_req(crypto_ahash_update(req), wait); - if (unlikely(r)) - return r; - data += this_step; - len -= this_step; - } while (len); - return 0; } + + do { + int r; + size_t this_step = min_t(size_t, len, PAGE_SIZE - offset_in_page(data)); + + flush_kernel_vmap_range((void *)data, this_step); + sg_init_table(&sg, 1); + sg_set_page(&sg, vmalloc_to_page(data), this_step, offset_in_page(data)); + ahash_request_set_crypt(req, &sg, NULL, this_step); + r = crypto_wait_req(crypto_ahash_update(req), wait); + if (unlikely(r)) + return r; + data += this_step; + len -= this_step; + } while (len); + + return 0; } /* @@ -164,7 +166,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req, r = verity_hash_update(v, req, v->salt, v->salt_size, wait); if (r < 0) { - DMERR("verity_hash_final failed updating salt: %d", r); + DMERR("%s failed updating salt: %d", __func__, r); goto out; } } @@ -196,10 +198,10 @@ out: } static void verity_hash_at_level(struct dm_verity *v, sector_t block, int level, - sector_t *hash_block, unsigned *offset) + sector_t *hash_block, unsigned int *offset) { sector_t position = verity_position_at_level(v, block, level); - unsigned idx; + unsigned int idx; *hash_block = v->hash_level_block[level] + (position >> v->hash_per_block_bits); @@ -287,7 +289,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io, u8 *data; int r; sector_t hash_block; - unsigned offset; + unsigned int offset; verity_hash_at_level(v, block, level, &hash_block, &offset); @@ -332,10 +334,8 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io, */ r = -EAGAIN; goto release_ret_r; - } - else if (verity_fec_decode(v, io, - DM_VERITY_BLOCK_TYPE_METADATA, - hash_block, data, NULL) == 0) + } else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_METADATA, + hash_block, data, NULL) == 0) aux->hash_verified = 1; else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_METADATA, @@ -424,7 +424,7 @@ static int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io, r = crypto_wait_req(crypto_ahash_update(req), wait); if (unlikely(r < 0)) { - DMERR("verity_for_io_block crypto op failed: %d", r); + DMERR("%s crypto op failed: %d", __func__, r); return r; } @@ -445,13 +445,13 @@ int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, struct dm_verity_io *io, u8 *data, size_t len)) { - unsigned todo = 1 << v->data_dev_block_bits; + unsigned int todo = 1 << v->data_dev_block_bits; struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); do { int r; u8 *page; - unsigned len; + unsigned int len; struct bio_vec bv = bio_iter_iovec(bio, *iter); page = bvec_kmap_local(&bv); @@ -685,10 +685,12 @@ static void verity_prefetch_io(struct work_struct *work) for (i = v->levels - 2; i >= 0; i--) { sector_t hash_block_start; sector_t hash_block_end; + verity_hash_at_level(v, pw->block, i, &hash_block_start, NULL); verity_hash_at_level(v, pw->block + pw->n_blocks - 1, i, &hash_block_end, NULL); + if (!i) { - unsigned cluster = READ_ONCE(dm_verity_prefetch_cluster); + unsigned int cluster = READ_ONCE(dm_verity_prefetch_cluster); cluster >>= v->data_dev_block_bits; if (unlikely(!cluster)) @@ -753,7 +755,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio) bio_set_dev(bio, v->data_dev->bdev); bio->bi_iter.bi_sector = verity_map_sector(v, bio->bi_iter.bi_sector); - if (((unsigned)bio->bi_iter.bi_sector | bio_sectors(bio)) & + if (((unsigned int)bio->bi_iter.bi_sector | bio_sectors(bio)) & ((1 << (v->data_dev_block_bits - SECTOR_SHIFT)) - 1)) { DMERR_LIMIT("unaligned io"); return DM_MAPIO_KILL; @@ -789,12 +791,12 @@ static int verity_map(struct dm_target *ti, struct bio *bio) * Status: V (valid) or C (corruption found) */ static void verity_status(struct dm_target *ti, status_type_t type, - unsigned status_flags, char *result, unsigned maxlen) + unsigned int status_flags, char *result, unsigned int maxlen) { struct dm_verity *v = ti->private; - unsigned args = 0; - unsigned sz = 0; - unsigned x; + unsigned int args = 0; + unsigned int sz = 0; + unsigned int x; switch (type) { case STATUSTYPE_INFO: @@ -1054,7 +1056,7 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, bool only_modifier_opts) { int r = 0; - unsigned argc; + unsigned int argc; struct dm_target *ti = v->ti; const char *arg_name; @@ -1156,13 +1158,12 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, * <digest> * <salt> Hex string or "-" if no salt. */ -static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) +static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv) { struct dm_verity *v; struct dm_verity_sig_opts verify_args = {0}; struct dm_arg_set as; unsigned int num; - unsigned int wq_flags; unsigned long long num_ll; int r; int i; @@ -1370,6 +1371,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) hash_position = v->hash_start; for (i = v->levels - 1; i >= 0; i--) { sector_t s; + v->hash_level_block[i] = hash_position; s = (v->data_blocks + ((sector_t)1 << ((i + 1) * v->hash_per_block_bits)) - 1) >> ((i + 1) * v->hash_per_block_bits); @@ -1399,8 +1401,6 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) goto bad; } - /* WQ_UNBOUND greatly improves performance when running on ramdisk */ - wq_flags = WQ_MEM_RECLAIM | WQ_UNBOUND; /* * Using WQ_HIGHPRI improves throughput and completion latency by * reducing wait times when reading from a dm-verity device. @@ -1410,8 +1410,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) * will fall-back to using it for error handling (or if the bufio cache * doesn't have required hashes). */ - wq_flags |= WQ_HIGHPRI; - v->verify_wq = alloc_workqueue("kverityd", wq_flags, num_online_cpus()); + v->verify_wq = alloc_workqueue("kverityd", WQ_MEM_RECLAIM | WQ_HIGHPRI, 0); if (!v->verify_wq) { ti->error = "Cannot allocate workqueue"; r = -ENOMEM; |