drivers/md/dm-verity-fec.c
Source file repositories/reference/linux-study-clean/drivers/md/dm-verity-fec.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-verity-fec.c- Extension
.c- Size
- 20865 bytes
- Lines
- 735
- Domain
- Driver Families
- Bucket
- drivers/md
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
dm-verity-fec.hlinux/math64.h
Detected Declarations
function Copyrightfunction fec_decode_bufsfunction fec_is_erasurefunction fec_read_bufsfunction fec_for_each_buffer_rs_messagefunction fec_init_bufsfunction fec_decodefunction verity_fec_decodefunction __verity_fec_finish_iofunction verity_fec_status_tablefunction verity_fec_dtrfunction fec_rs_freefunction verity_is_fec_opt_argfunction verity_fec_parse_opt_argsfunction verity_fec_ctr_allocfunction verity_fec_ctr
Annotated Snippet
if (to_copy < v->fec->roots) {
parity_block++;
parity_pos = 0;
dm_bufio_release(buf);
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, target_block,
parity_block, PTR_ERR(par));
return PTR_ERR(par);
}
for (; j < v->fec->roots; j++)
par_buf[j] = par[parity_pos++];
}
/* Decode an RS codeword using the Reed-Solomon library. */
res = decode_rs8(fio->rs, msg_buf, par_buf, v->fec->rs_k,
NULL, neras, fio->erasures, 0, NULL);
if (res < 0) {
r = res;
goto done;
}
corrected += res;
fio->output[out_pos++] = msg_buf[target_region];
if (out_pos >= v->fec->block_size)
goto done;
}
done:
dm_bufio_release(buf);
if (r < 0 && neras)
DMERR_LIMIT("%s: FEC %llu: failed to correct: %d",
v->data_dev->name, target_block, r);
else if (r == 0)
DMWARN_LIMIT("%s: FEC %llu: corrected %d errors",
v->data_dev->name, target_block, corrected);
return r;
}
/*
* 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, v->fec->block_size,
io->tmp_digest)))
return 0;
return memcmp(io->tmp_digest, want_digest, v->digest_size) != 0;
}
/*
* Read the message block at index @index_in_region within each of the
* @v->fec->rs_k regions and deinterleave their contents into @io->fec_io->bufs.
*
* @target_block gives the index of specific block within this sequence that is
* being corrected, relative to the start of all the FEC message blocks.
*
* @out_pos gives the current output position, i.e. the position in (each) block
* from which to start the deinterleaving. Deinterleaving continues until
* either end-of-block is reached or there's no more buffer space.
*
* If @neras is non-NULL, then also use verity hashes and the presence/absence
* of I/O errors to determine which of the message blocks in the sequence are
* likely to be incorrect. Write the number of such blocks to *@neras and the
* indices of the corresponding RS message bytes in [0, k - 1] to
* @io->fec_io->erasures, up to a limit of @v->fec->roots + 1 such blocks.
*/
static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
u64 target_block, 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;
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);
if (neras)
Annotation
- Immediate include surface: `dm-verity-fec.h`, `linux/math64.h`.
- Detected declarations: `function Copyright`, `function fec_decode_bufs`, `function fec_is_erasure`, `function fec_read_bufs`, `function fec_for_each_buffer_rs_message`, `function fec_init_bufs`, `function fec_decode`, `function verity_fec_decode`, `function __verity_fec_finish_io`, `function verity_fec_status_table`.
- Atlas domain: Driver Families / drivers/md.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.