Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0d849fa authored by Heinz Mauelshagen's avatar Heinz Mauelshagen Committed by Mike Snitzer
Browse files

dm cache: fix truncation bug when mapping I/O to >2TB fast device



When remapping a block to the cache's fast device that is larger than
2TB we must not truncate the destination sector to 32bits.  The 32bit
temporary result of from_cblock() was being overflowed in
remap_to_cache() due to the logical left shift.

Use an intermediate 64bit type to store the 32bit from_cblock() result
to fix the overflow.

Signed-off-by: default avatarHeinz Mauelshagen <heinzm@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Cc: stable@vger.kernel.org
parent 7d48935e
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -671,15 +671,16 @@ static void remap_to_cache(struct cache *cache, struct bio *bio,
			   dm_cblock_t cblock)
			   dm_cblock_t cblock)
{
{
	sector_t bi_sector = bio->bi_iter.bi_sector;
	sector_t bi_sector = bio->bi_iter.bi_sector;
	sector_t block = from_cblock(cblock);


	bio->bi_bdev = cache->cache_dev->bdev;
	bio->bi_bdev = cache->cache_dev->bdev;
	if (!block_size_is_power_of_two(cache))
	if (!block_size_is_power_of_two(cache))
		bio->bi_iter.bi_sector =
		bio->bi_iter.bi_sector =
			(from_cblock(cblock) * cache->sectors_per_block) +
			(block * cache->sectors_per_block) +
			sector_div(bi_sector, cache->sectors_per_block);
			sector_div(bi_sector, cache->sectors_per_block);
	else
	else
		bio->bi_iter.bi_sector =
		bio->bi_iter.bi_sector =
			(from_cblock(cblock) << cache->sectors_per_block_shift) |
			(block << cache->sectors_per_block_shift) |
			(bi_sector & (cache->sectors_per_block - 1));
			(bi_sector & (cache->sectors_per_block - 1));
}
}