aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2015-12-07 10:37:21 +0000
committerMister Oyster <oysterized@gmail.com>2017-12-27 18:49:06 +0100
commit2a1ae53d30b485019854d6908ece456b52c7ba9f (patch)
tree18f571404f877e43139369c43d98465fc95e12ce
parent3859d5e00c44b7c974e87a57e1fe49ef85578c48 (diff)
dm verity: factor out verity_for_bv_block()
verity_for_bv_block() will be re-used by optional dm-verity object. Bug: 21893453 Change-Id: I82a3e6efdd95a488770a2fea6794befa8f5a35ce Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> (cherry picked from commit cce43a8a989fb5e245f5ca457e39edc22941c42e)
-rw-r--r--drivers/md/dm-verity-target.c85
-rw-r--r--drivers/md/dm-verity.h6
2 files changed, 64 insertions, 27 deletions
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 53740f22d..c4a06f75e 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -335,6 +335,57 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
}
/*
+ * Calls function process for 1 << v->data_dev_block_bits bytes in io->io_vec
+ * starting from (vector, offset).
+ */
+int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io,
+ unsigned *vector, unsigned *offset,
+ int (*process)(struct dm_verity *v,
+ struct dm_verity_io *io,
+ u8 *data, size_t len))
+{
+ unsigned todo = 1 << v->data_dev_block_bits;
+
+ do {
+ int r;
+ struct bio_vec *bv;
+ u8 *page;
+ unsigned len;
+
+ BUG_ON(*vector >= io->io_vec_size);
+ bv = &io->io_vec[*vector];
+ page = kmap_atomic(bv->bv_page);
+ len = bv->bv_len - *offset;
+
+ if (likely(len >= todo))
+ len = todo;
+
+ r = process(v, io, page + bv->bv_offset + *offset, len);
+ kunmap_atomic(page);
+
+ if (r < 0)
+ return r;
+
+ *offset += len;
+
+ if (likely(*offset == bv->bv_len)) {
+ *offset = 0;
+ (*vector)++;
+ }
+
+ todo -= len;
+ } while (todo);
+
+ return 0;
+}
+
+static int verity_bv_hash_update(struct dm_verity *v, struct dm_verity_io *io,
+ u8 *data, size_t len)
+{
+ return verity_hash_update(v, verity_io_hash_desc(v, io), data, len);
+}
+
+/*
* Verify one "dm_verity_io" structure.
*/
static int verity_verify_io(struct dm_verity_io *io)
@@ -342,10 +393,10 @@ static int verity_verify_io(struct dm_verity_io *io)
struct dm_verity *v = io->v;
unsigned b;
unsigned vector = 0, offset = 0;
+ unsigned start_vector, start_offset;
for (b = 0; b < io->n_blocks; b++) {
int r;
- unsigned todo;
struct shash_desc *desc = verity_io_hash_desc(v, io);
r = verity_hash_for_block(v, io, io->block + b,
@@ -357,33 +408,13 @@ static int verity_verify_io(struct dm_verity_io *io)
if (unlikely(r < 0))
return r;
- todo = 1 << v->data_dev_block_bits;
- do {
- struct bio_vec *bv;
- u8 *page;
- unsigned len;
-
- BUG_ON(vector >= io->io_vec_size);
- bv = &io->io_vec[vector];
- page = kmap_atomic(bv->bv_page);
- len = bv->bv_len - offset;
- if (likely(len >= todo))
- len = todo;
- r = verity_hash_update(v, desc,
- page + bv->bv_offset + offset, len);
- kunmap_atomic(page);
-
- if (unlikely(r < 0))
- return r;
-
- offset += len;
- if (likely(offset == bv->bv_len)) {
- offset = 0;
- vector++;
- }
- todo -= len;
- } while (todo);
+ start_vector = vector;
+ start_offset = offset;
+ r = verity_for_bv_block(v, io, &vector, &offset,
+ verity_bv_hash_update);
+ if (unlikely(r < 0))
+ return r;
r = verity_hash_final(v, desc, verity_io_real_digest(v, io));
if (unlikely(r < 0))
return r;
diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
index 3817759a1..0eb38bb6b 100644
--- a/drivers/md/dm-verity.h
+++ b/drivers/md/dm-verity.h
@@ -109,6 +109,12 @@ static inline u8 *verity_io_want_digest(struct dm_verity *v,
return (u8 *)(io + 1) + v->shash_descsize + v->digest_size;
}
+extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io,
+ unsigned *vector, unsigned *offset,
+ int (*process)(struct dm_verity *v,
+ struct dm_verity_io *io,
+ u8 *data, size_t len));
+
extern int verity_hash(struct dm_verity *v, struct shash_desc *desc,
const u8 *data, size_t len, u8 *digest);