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 19/22] dm-verity-fec: pass down index_in_region instead of rsb
Date: Thu, 5 Feb 2026 20:59:38 -0800 [thread overview]
Message-ID: <20260206045942.52965-20-ebiggers@kernel.org> (raw)
In-Reply-To: <20260206045942.52965-1-ebiggers@kernel.org>
Replace 'rsb', which is a byte index, with 'index_in_region' which is a
block index. The block index is slightly easier to compute, it matches
what fec_read_bufs() wants, and it avoids the mismatch between the name
and the units of the variable. ('rsb' stood for "Reed-Solomon block",
but its units were bytes, not blocks.)
fec_decode_bufs() does want it as a byte index when computing
parity_block, but that's easily handled locally.
As long as the parameters to the log messages are being adjusted, also
eliminate the unnecessary casts to 'unsigned long long'. %llu is the
correct way to print a u64 in the Linux kernel, as documented in
printk-formats.rst. There's no PRIu64 macro like there is in userspace.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/md/dm-verity-fec.c | 47 +++++++++++++++++++++-----------------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 1b5052ba4f5a5..37c4eb6a11dee 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -47,11 +47,11 @@ static inline u8 *fec_buffer_rs_message(struct dm_verity *v,
/*
* Decode all RS codewords whose message bytes were loaded into fio->bufs. Copy
* the corrected bytes into fio->output starting from out_pos.
*/
static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
- struct dm_verity_fec_io *fio, u64 rsb,
+ struct dm_verity_fec_io *fio, u64 index_in_region,
int target_region, unsigned int out_pos, int neras)
{
int r, corrected = 0, res;
struct dm_buffer *buf;
unsigned int n, i, j, parity_pos, to_copy;
@@ -65,18 +65,20 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
* the starting position in that block. Then read that block.
*
* 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 + out_pos) * v->fec->roots;
+ parity_block = ((index_in_region << v->data_dev_block_bits) + out_pos) *
+ v->fec->roots;
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",
- v->data_dev->name, rsb, parity_block, PTR_ERR(par));
+ v->data_dev->name, index_in_region, parity_block,
+ PTR_ERR(par));
return PTR_ERR(par);
}
/*
* Decode the RS codewords whose message bytes are in bufs. Each RS
@@ -101,12 +103,12 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
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",
- v->data_dev->name, rsb, parity_block,
- PTR_ERR(par));
+ v->data_dev->name, index_in_region,
+ parity_block, PTR_ERR(par));
return PTR_ERR(par);
}
for (; j < v->fec->roots; j++)
par_buf[j] = par[parity_pos++];
}
@@ -130,14 +132,14 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
error:
dm_bufio_release(buf);
if (r < 0 && neras)
DMERR_LIMIT("%s: FEC %llu: failed to correct: %d",
- v->data_dev->name, (unsigned long long)rsb, r);
+ v->data_dev->name, index_in_region, r);
else if (r > 0)
DMWARN_LIMIT("%s: FEC %llu: corrected %d errors",
- v->data_dev->name, (unsigned long long)rsb, r);
+ v->data_dev->name, index_in_region, r);
return r;
}
/*
@@ -156,18 +158,18 @@ static int fec_is_erasure(struct dm_verity *v, struct dm_verity_io *io,
/*
* Read data blocks that are part of the RS block and deinterleave as much as
* fits into buffers. Check for erasure locations if @neras is non-NULL.
*/
static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
- u64 rsb, unsigned int out_pos, int *neras)
+ u64 index_in_region, unsigned int out_pos, int *neras)
{
bool is_zero;
int i, j;
struct dm_buffer *buf;
struct dm_bufio_client *bufio;
struct dm_verity_fec_io *fio = io->fec_io;
- u64 block, ileaved;
+ u64 block;
u8 *bbuf;
u8 want_digest[HASH_MAX_DIGESTSIZE];
unsigned int n, src_pos;
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
@@ -180,12 +182,11 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
/*
* read each of the rs_k data blocks that are part of the RS block, and
* interleave contents to available bufs
*/
for (i = 0; i < v->fec->rs_k; i++) {
- ileaved = rsb + i * (v->fec->region_blocks << v->data_dev_block_bits);
- block = ileaved >> v->data_dev_block_bits;
+ block = i * v->fec->region_blocks + index_in_region;
bufio = v->fec->data_bufio;
if (block >= v->data_blocks) {
block -= v->data_blocks;
@@ -201,13 +202,12 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
}
bbuf = dm_bufio_read_with_ioprio(bufio, block, &buf, bio->bi_ioprio);
if (IS_ERR(bbuf)) {
DMWARN_LIMIT("%s: FEC %llu: read failed (%llu): %ld",
- v->data_dev->name,
- (unsigned long long)rsb,
- (unsigned long long)block, PTR_ERR(bbuf));
+ v->data_dev->name, index_in_region, block,
+ PTR_ERR(bbuf));
/* assume the block is corrupted */
if (neras && *neras <= v->fec->roots)
fio->erasures[(*neras)++] = i;
@@ -310,28 +310,33 @@ static int fec_decode(struct dm_verity *v, struct dm_verity_io *io,
struct dm_verity_fec_io *fio, u64 target_block,
const u8 *want_digest, bool use_erasures)
{
int r, neras = 0;
unsigned int target_region, out_pos;
- u64 rsb;
+ u64 index_in_region;
- target_region = div64_u64_rem(
- target_block << v->data_dev_block_bits,
- v->fec->region_blocks << v->data_dev_block_bits, &rsb);
+ /*
+ * Compute 'target_region', the index of the region the target block is
+ * in; and 'index_in_region', the index of the target block within its
+ * region. The latter value is also the index within its region of each
+ * message block that shares its RS codewords with the target block.
+ */
+ target_region = div64_u64_rem(target_block, v->fec->region_blocks,
+ &index_in_region);
if (WARN_ON_ONCE(target_region >= v->fec->rs_k))
/* target_block is out-of-bounds. Should never happen. */
return -EIO;
for (out_pos = 0; out_pos < v->fec->block_size;) {
fec_init_bufs(v, fio);
- r = fec_read_bufs(v, io, rsb, out_pos,
+ r = fec_read_bufs(v, io, index_in_region, out_pos,
use_erasures ? &neras : NULL);
if (unlikely(r < 0))
return r;
- r = fec_decode_bufs(v, io, fio, rsb, target_region,
+ r = fec_decode_bufs(v, io, fio, index_in_region, target_region,
out_pos, neras);
if (r < 0)
return r;
out_pos += fio->nbufs << DM_VERITY_FEC_BUF_RS_BITS;
@@ -342,11 +347,11 @@ static int fec_decode(struct dm_verity *v, struct dm_verity_io *io,
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)",
- v->data_dev->name, (unsigned long long)rsb, neras);
+ v->data_dev->name, index_in_region, neras);
return -EILSEQ;
}
return 0;
}
--
2.52.0
next prev parent reply other threads:[~2026-02-06 5:02 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 ` [PATCH 11/22] dm-verity-fec: replace io_size with block_size Eric Biggers
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 ` Eric Biggers [this message]
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-20-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.