aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2014-02-27 16:46:48 -0500
committerMike Snitzer <snitzer@redhat.com>2014-02-28 09:23:02 -0500
commite0d849fad746cb36a6822e4595d8ba9bf0adf7fa (patch)
treed5ea46f6692bc8de0260843a59d386db4bb9030c /drivers
parent7d48935eff401bb7970e73e822871a10e3643df1 (diff)
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: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-cache-target.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index db0944465127..1af70145fab9 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -671,15 +671,16 @@ static void remap_to_cache(struct cache *cache, struct bio *bio,
671 dm_cblock_t cblock) 671 dm_cblock_t cblock)
672{ 672{
673 sector_t bi_sector = bio->bi_iter.bi_sector; 673 sector_t bi_sector = bio->bi_iter.bi_sector;
674 sector_t block = from_cblock(cblock);
674 675
675 bio->bi_bdev = cache->cache_dev->bdev; 676 bio->bi_bdev = cache->cache_dev->bdev;
676 if (!block_size_is_power_of_two(cache)) 677 if (!block_size_is_power_of_two(cache))
677 bio->bi_iter.bi_sector = 678 bio->bi_iter.bi_sector =
678 (from_cblock(cblock) * cache->sectors_per_block) + 679 (block * cache->sectors_per_block) +
679 sector_div(bi_sector, cache->sectors_per_block); 680 sector_div(bi_sector, cache->sectors_per_block);
680 else 681 else
681 bio->bi_iter.bi_sector = 682 bio->bi_iter.bi_sector =
682 (from_cblock(cblock) << cache->sectors_per_block_shift) | 683 (block << cache->sectors_per_block_shift) |
683 (bi_sector & (cache->sectors_per_block - 1)); 684 (bi_sector & (cache->sectors_per_block - 1));
684} 685}
685 686