From: Eric Biggers <ebiggers@kernel.org>
To: dm-devel@lists.linux.dev, Alasdair Kergon <agk@redhat.com>,
Mike Snitzer <snitzer@kernel.org>,
Mikulas Patocka <mpatocka@redhat.com>,
Benjamin Marzinski <bmarzins@redhat.com>
Cc: Sami Tolvanen <samitolvanen@google.com>,
linux-kernel@vger.kernel.org, Eric Biggers <ebiggers@kernel.org>
Subject: [PATCH 11/22] dm-verity-fec: replace io_size with block_size
Date: Thu, 5 Feb 2026 20:59:30 -0800 [thread overview]
Message-ID: <20260206045942.52965-12-ebiggers@kernel.org> (raw)
In-Reply-To: <20260206045942.52965-1-ebiggers@kernel.org>
dm-verity's FEC implementation assumes that data_block_size ==
hash_block_size, and it accesses the FEC device in units of the same
size. Many places in the code want that size and compute it on-demand
as '1 << v->data_dev_block_bits'. However, it's actually already
available in v->fec->io_size. Rename that field to block_size,
initialize it a bit earlier, and use it in the appropriate places.
Note that while these sizes could in principle be different, that case
is not supported. So there's no need to complicate the code for it.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/md/dm-verity-fec.c | 30 +++++++++++++-----------------
drivers/md/dm-verity-fec.h | 2 +-
2 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 619645edaf509..6ba9a1e039be3 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -82,15 +82,15 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
/*
* Compute the index of the first parity block that will be needed and
* the starting position in that block. Then read that block.
*
- * io_size is always a power of 2, but roots might not be. Note that
+ * block_size is always a power of 2, but roots might not be. Note that
* when it's not, a codeword's parity bytes can span a block boundary.
*/
parity_block = (rsb + block_offset) * v->fec->roots;
- parity_pos = parity_block & (v->fec->io_size - 1);
+ parity_pos = parity_block & (v->fec->block_size - 1);
parity_block >>= v->data_dev_block_bits;
par = dm_bufio_read_with_ioprio(v->fec->bufio, parity_block, &buf,
bio->bi_ioprio);
if (IS_ERR(par)) {
DMERR("%s: FEC %llu: parity read failed (block %llu): %ld",
@@ -108,11 +108,11 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
/*
* Copy the next 'roots' parity bytes to 'par_buf', reading
* another parity block if needed.
*/
- to_copy = min(v->fec->io_size - parity_pos, v->fec->roots);
+ to_copy = min(v->fec->block_size - parity_pos, v->fec->roots);
for (j = 0; j < to_copy; j++)
par_buf[j] = par[parity_pos++];
if (to_copy < v->fec->roots) {
parity_block++;
parity_pos = 0;
@@ -141,11 +141,11 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
corrected += res;
fio->output[block_offset] = msg_buf[byte_index];
block_offset++;
- if (block_offset >= 1 << v->data_dev_block_bits)
+ if (block_offset >= v->fec->block_size)
goto done;
}
done:
r = corrected;
error:
@@ -165,11 +165,11 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
* Locate data block erasures using verity hashes.
*/
static int fec_is_erasure(struct dm_verity *v, struct dm_verity_io *io,
const u8 *want_digest, const u8 *data)
{
- if (unlikely(verity_hash(v, io, data, 1 << v->data_dev_block_bits,
+ if (unlikely(verity_hash(v, io, data, v->fec->block_size,
io->tmp_digest)))
return 0;
return memcmp(io->tmp_digest, want_digest, v->digest_size) != 0;
}
@@ -266,11 +266,11 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
* starting from block_offset
*/
fec_for_each_buffer_rs_message(fio, n, j) {
k = fec_buffer_rs_index(n, j) + block_offset;
- if (k >= 1 << v->data_dev_block_bits)
+ if (k >= v->fec->block_size)
goto done;
fec_buffer_rs_message(v, fio, n, j)[i] = bbuf[k];
}
done:
@@ -339,11 +339,11 @@ static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io,
const u8 *want_digest, bool use_erasures)
{
int r, neras = 0;
unsigned int pos;
- for (pos = 0; pos < 1 << v->data_dev_block_bits; ) {
+ for (pos = 0; pos < v->fec->block_size;) {
fec_init_bufs(v, fio);
r = fec_read_bufs(v, io, rsb, offset, pos,
use_erasures ? &neras : NULL);
if (unlikely(r < 0))
@@ -355,12 +355,11 @@ static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io,
pos += fio->nbufs << DM_VERITY_FEC_BUF_RS_BITS;
}
/* Always re-validate the corrected block against the expected hash */
- r = verity_hash(v, io, fio->output, 1 << v->data_dev_block_bits,
- io->tmp_digest);
+ r = verity_hash(v, io, fio->output, v->fec->block_size, io->tmp_digest);
if (unlikely(r < 0))
return r;
if (memcmp(io->tmp_digest, want_digest, v->digest_size)) {
DMERR_LIMIT("%s: FEC %llu: failed to correct (%d erasures)",
@@ -424,11 +423,11 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
r = fec_decode_rsb(v, io, fio, rsb, offset, want_digest, true);
if (r < 0)
goto done;
}
- memcpy(dest, fio->output, 1 << v->data_dev_block_bits);
+ memcpy(dest, fio->output, v->fec->block_size);
atomic64_inc(&v->fec->corrected);
done:
fio->level--;
return r;
@@ -645,10 +644,11 @@ int verity_fec_ctr(struct dm_verity *v)
*/
if (v->data_dev_block_bits != v->hash_dev_block_bits) {
ti->error = "Block sizes must match to use FEC";
return -EINVAL;
}
+ f->block_size = 1 << v->data_dev_block_bits;
if (!f->roots) {
ti->error = "Missing " DM_VERITY_OPT_FEC_ROOTS;
return -EINVAL;
}
@@ -682,14 +682,11 @@ int verity_fec_ctr(struct dm_verity *v)
ti->error = "Hash device is too small for "
DM_VERITY_OPT_FEC_BLOCKS;
return -E2BIG;
}
- f->io_size = 1 << v->data_dev_block_bits;
-
- f->bufio = dm_bufio_client_create(f->dev->bdev,
- f->io_size,
+ f->bufio = dm_bufio_client_create(f->dev->bdev, f->block_size,
1, 0, NULL, NULL, 0);
if (IS_ERR(f->bufio)) {
ti->error = "Cannot initialize FEC bufio client";
return PTR_ERR(f->bufio);
}
@@ -699,12 +696,11 @@ int verity_fec_ctr(struct dm_verity *v)
if (dm_bufio_get_device_size(f->bufio) < f->rounds * f->roots) {
ti->error = "FEC device is too small";
return -E2BIG;
}
- f->data_bufio = dm_bufio_client_create(v->data_dev->bdev,
- 1 << v->data_dev_block_bits,
+ f->data_bufio = dm_bufio_client_create(v->data_dev->bdev, f->block_size,
1, 0, NULL, NULL, 0);
if (IS_ERR(f->data_bufio)) {
ti->error = "Cannot initialize FEC data bufio client";
return PTR_ERR(f->data_bufio);
}
@@ -747,11 +743,11 @@ int verity_fec_ctr(struct dm_verity *v)
return ret;
}
/* Preallocate an output buffer for each thread */
ret = mempool_init_kmalloc_pool(&f->output_pool, num_online_cpus(),
- 1 << v->data_dev_block_bits);
+ f->block_size);
if (ret) {
ti->error = "Cannot allocate FEC output pool";
return ret;
}
diff --git a/drivers/md/dm-verity-fec.h b/drivers/md/dm-verity-fec.h
index 257a609274c7c..49d43894ea746 100644
--- a/drivers/md/dm-verity-fec.h
+++ b/drivers/md/dm-verity-fec.h
@@ -27,11 +27,11 @@
/* configuration */
struct dm_verity_fec {
struct dm_dev *dev; /* parity data device */
struct dm_bufio_client *data_bufio; /* for data dev access */
struct dm_bufio_client *bufio; /* for parity data access */
- size_t io_size; /* IO size for roots */
+ size_t block_size; /* size of data, hash, and parity blocks in bytes */
sector_t start; /* parity data start in blocks */
sector_t blocks; /* number of blocks covered */
sector_t rounds; /* number of interleaving rounds */
sector_t hash_blocks; /* blocks covered after v->hash_start */
unsigned char roots; /* parity bytes per RS codeword, n-k of RS(n, k) */
--
2.52.0
next prev parent reply other threads:[~2026-02-06 5:01 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-06 4:59 [PATCH 00/22] dm-verity: more FEC fixes and cleanups Eric Biggers
2026-02-06 4:59 ` [PATCH 01/22] dm-verity-fec: correctly reject too-small FEC devices Eric Biggers
2026-02-06 4:59 ` [PATCH 02/22] dm-verity-fec: correctly reject too-small hash devices Eric Biggers
2026-02-06 4:59 ` [PATCH 03/22] dm-verity-fec: fix corrected block count stat Eric Biggers
2026-02-06 4:59 ` [PATCH 04/22] dm-verity-fec: fix the size of dm_verity_fec_io::erasures Eric Biggers
2026-02-06 4:59 ` [PATCH 05/22] dm-verity-fec: fix reading parity bytes split across blocks (take 3) Eric Biggers
2026-02-06 4:59 ` [PATCH 06/22] dm-verity: rename dm_verity::hash_blocks to dm_verity::hash_end Eric Biggers
2026-02-06 4:59 ` [PATCH 07/22] dm-verity-fec: improve documentation for Forward Error Correction Eric Biggers
2026-02-06 4:59 ` [PATCH 08/22] dm-verity-fec: replace {MAX,MIN}_RSN with {MIN,MAX}_ROOTS Eric Biggers
2026-02-06 4:59 ` [PATCH 09/22] dm-verity-fec: use standard names for Reed-Solomon parameters Eric Biggers
2026-02-06 4:59 ` [PATCH 10/22] dm-verity-fec: rename "RS block" to "RS codeword" Eric Biggers
2026-02-06 4:59 ` Eric Biggers [this message]
2026-02-06 4:59 ` [PATCH 12/22] dm-verity-fec: rename rounds to region_blocks Eric Biggers
2026-02-06 4:59 ` [PATCH 13/22] dm-verity-fec: simplify computation of rsb Eric Biggers
2026-02-06 4:59 ` [PATCH 14/22] dm-verity-fec: simplify computation of ileaved Eric Biggers
2026-02-06 4:59 ` [PATCH 15/22] dm-verity-fec: simplify deinterleaving Eric Biggers
2026-02-06 4:59 ` [PATCH 16/22] dm-verity-fec: rename block_offset to out_pos Eric Biggers
2026-02-06 4:59 ` [PATCH 17/22] dm-verity-fec: move computation of offset and rsb down a level Eric Biggers
2026-02-06 4:59 ` [PATCH 18/22] dm-verity-fec: compute target region directly Eric Biggers
2026-02-06 4:59 ` [PATCH 19/22] dm-verity-fec: pass down index_in_region instead of rsb Eric Biggers
2026-02-06 4:59 ` [PATCH 20/22] dm-verity-fec: make fec_decode_bufs() just return 0 or error Eric Biggers
2026-02-06 4:59 ` [PATCH 21/22] dm-verity-fec: log target_block instead of index_in_region Eric Biggers
2026-02-06 4:59 ` [PATCH 22/22] dm-verity-fec: improve comments for fec_read_bufs() Eric Biggers
2026-02-11 22:29 ` [PATCH 00/22] dm-verity: more FEC fixes and cleanups Sami Tolvanen
2026-03-03 20:16 ` Eric Biggers
2026-03-04 8:25 ` Milan Broz
2026-03-04 9:00 ` Eric Biggers
2026-03-04 9:34 ` Milan Broz
2026-03-04 17:45 ` Eric Biggers
2026-03-04 19:29 ` Milan Broz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260206045942.52965-12-ebiggers@kernel.org \
--to=ebiggers@kernel.org \
--cc=agk@redhat.com \
--cc=bmarzins@redhat.com \
--cc=dm-devel@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=mpatocka@redhat.com \
--cc=samitolvanen@google.com \
--cc=snitzer@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox