Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dm-verity-fec: move computation of offset and rsb down a level

verity_fec_decode() computes (offset, rsb) from the target block index
and calls fec_decode_rsb() with these parameters. Move this computation
into fec_decode_rsb(), and rename fec_decode_rsb() to fec_decode().

This ends up being simpler and enables further refactoring, specifically
making use of the quotient from the division more easily. The function
renaming also eliminates a reference to the ambiguous term "rsb".

This change does mean the same div64_u64_rem() can now be executed twice
per block, since verity_fec_decode() calls fec_decode() up to twice per
block. However, this cost is negligible compared to the rest of FEC.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

authored by

Eric Biggers and committed by
Mikulas Patocka
ca0da6cc 3ad2b952

+18 -28
+18 -28
drivers/md/dm-verity-fec.c
··· 306 306 } 307 307 308 308 /* 309 - * Decode all RS blocks in a single data block and return the target block 310 - * (indicated by @offset) in fio->output. If @use_erasures is non-zero, uses 311 - * hashes to locate erasures. 309 + * Try to correct the message (data or hash) block at index @target_block. 310 + * 311 + * If @use_erasures is true, use verity hashes to locate erasures. This makes 312 + * the error correction slower but up to twice as capable. 313 + * 314 + * On success, return 0 and write the corrected block to @fio->output. 0 is 315 + * returned only if the digest of the corrected block matches @want_digest; this 316 + * is critical to ensure that FEC can't cause dm-verity to return bad data. 312 317 */ 313 - static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io, 314 - struct dm_verity_fec_io *fio, u64 rsb, u64 offset, 315 - const u8 *want_digest, bool use_erasures) 318 + static int fec_decode(struct dm_verity *v, struct dm_verity_io *io, 319 + struct dm_verity_fec_io *fio, u64 target_block, 320 + const u8 *want_digest, bool use_erasures) 316 321 { 317 322 int r, neras = 0; 318 323 unsigned int out_pos; 324 + u64 offset = target_block << v->data_dev_block_bits; 325 + u64 rsb; 326 + 327 + div64_u64_rem(offset, v->fec->region_blocks << v->data_dev_block_bits, 328 + &rsb); 319 329 320 330 for (out_pos = 0; out_pos < v->fec->block_size;) { 321 331 fec_init_bufs(v, fio); ··· 363 353 { 364 354 int r; 365 355 struct dm_verity_fec_io *fio; 366 - u64 offset, rsb; 367 356 368 357 if (!verity_fec_is_enabled(v)) 369 358 return -EOPNOTSUPP; ··· 380 371 block = block - v->hash_start + v->data_blocks; 381 372 382 373 /* 383 - * For RS(n, k), the continuous FEC data is divided into blocks of k 384 - * bytes. Since block size may not be divisible by k, the last block 385 - * is zero padded when decoding. 386 - * 387 - * Each byte of the block is covered by a different RS(n, k) code, 388 - * and each code is interleaved over k blocks to make it less likely 389 - * that bursty corruption will leave us in unrecoverable state. 390 - */ 391 - 392 - offset = block << v->data_dev_block_bits; 393 - 394 - /* 395 - * The base RS block we can feed to the interleaver to find out all 396 - * blocks required for decoding. 397 - */ 398 - div64_u64_rem(offset, v->fec->region_blocks << v->data_dev_block_bits, 399 - &rsb); 400 - 401 - /* 402 374 * Locating erasures is slow, so attempt to recover the block without 403 375 * them first. Do a second attempt with erasures if the corruption is 404 376 * bad enough. 405 377 */ 406 - r = fec_decode_rsb(v, io, fio, rsb, offset, want_digest, false); 378 + r = fec_decode(v, io, fio, block, want_digest, false); 407 379 if (r < 0) { 408 - r = fec_decode_rsb(v, io, fio, rsb, offset, want_digest, true); 380 + r = fec_decode(v, io, fio, block, want_digest, true); 409 381 if (r < 0) 410 382 goto done; 411 383 }