Merge tag 'for-5.12/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:
"Fix DM verity target's optional Forward Error Correction (FEC) for
Reed-Solomon roots that are unaligned to block size"

* tag 'for-5.12/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm verity: fix FEC for RS roots unaligned to block size
dm bufio: subtract the number of initial sectors in dm_bufio_get_device_size

Changed files
+16 -11
drivers
+4
drivers/md/dm-bufio.c
··· 1526 1526 sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) 1527 1527 { 1528 1528 sector_t s = i_size_read(c->bdev->bd_inode) >> SECTOR_SHIFT; 1529 + if (s >= c->start) 1530 + s -= c->start; 1531 + else 1532 + s = 0; 1529 1533 if (likely(c->sectors_per_block_bits >= 0)) 1530 1534 s >>= c->sectors_per_block_bits; 1531 1535 else
+12 -11
drivers/md/dm-verity-fec.c
··· 61 61 static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, 62 62 unsigned *offset, struct dm_buffer **buf) 63 63 { 64 - u64 position, block; 64 + u64 position, block, rem; 65 65 u8 *res; 66 66 67 67 position = (index + rsb) * v->fec->roots; 68 - block = position >> v->data_dev_block_bits; 69 - *offset = (unsigned)(position - (block << v->data_dev_block_bits)); 68 + block = div64_u64_rem(position, v->fec->roots << SECTOR_SHIFT, &rem); 69 + *offset = (unsigned)rem; 70 70 71 - res = dm_bufio_read(v->fec->bufio, v->fec->start + block, buf); 71 + res = dm_bufio_read(v->fec->bufio, block, buf); 72 72 if (IS_ERR(res)) { 73 73 DMERR("%s: FEC %llu: parity read failed (block %llu): %ld", 74 74 v->data_dev->name, (unsigned long long)rsb, 75 - (unsigned long long)(v->fec->start + block), 76 - PTR_ERR(res)); 75 + (unsigned long long)block, PTR_ERR(res)); 77 76 *buf = NULL; 78 77 } 79 78 ··· 154 155 155 156 /* read the next block when we run out of parity bytes */ 156 157 offset += v->fec->roots; 157 - if (offset >= 1 << v->data_dev_block_bits) { 158 + if (offset >= v->fec->roots << SECTOR_SHIFT) { 158 159 dm_bufio_release(buf); 159 160 160 161 par = fec_read_parity(v, rsb, block_offset, &offset, &buf); ··· 673 674 { 674 675 struct dm_verity_fec *f = v->fec; 675 676 struct dm_target *ti = v->ti; 676 - u64 hash_blocks; 677 + u64 hash_blocks, fec_blocks; 677 678 int ret; 678 679 679 680 if (!verity_fec_is_enabled(v)) { ··· 743 744 } 744 745 745 746 f->bufio = dm_bufio_client_create(f->dev->bdev, 746 - 1 << v->data_dev_block_bits, 747 + f->roots << SECTOR_SHIFT, 747 748 1, 0, NULL, NULL); 748 749 if (IS_ERR(f->bufio)) { 749 750 ti->error = "Cannot initialize FEC bufio client"; 750 751 return PTR_ERR(f->bufio); 751 752 } 752 753 753 - if (dm_bufio_get_device_size(f->bufio) < 754 - ((f->start + f->rounds * f->roots) >> v->data_dev_block_bits)) { 754 + dm_bufio_set_sector_offset(f->bufio, f->start << (v->data_dev_block_bits - SECTOR_SHIFT)); 755 + 756 + fec_blocks = div64_u64(f->rounds * f->roots, v->fec->roots << SECTOR_SHIFT); 757 + if (dm_bufio_get_device_size(f->bufio) < fec_blocks) { 755 758 ti->error = "FEC device is too small"; 756 759 return -E2BIG; 757 760 }