aboutsummaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2014-02-27 22:46:48 +0100
committerMister Oyster <oysterized@gmail.com>2018-01-02 13:53:16 +0100
commitec241d7ed72583cf2a77f3b3db1ba2b5cac96caa (patch)
tree3bf1268ec4e75bcf7472a14ebb60af5e852d105c /drivers/md
parentf0e25e0d5fa4c62c09e8657f72504c99e24f05fe (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 [@nathanchance: fixed conflicts since no iters in 3.10] Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> Signed-off-by: Joe Maples <joe@frap129.org>
Diffstat (limited to 'drivers/md')
-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 277f2ac43..2609d3f26 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -564,13 +564,14 @@ static void remap_to_cache(struct cache *cache, struct bio *bio,
dm_cblock_t cblock)
{
sector_t bi_sector = bio->bi_sector;
+ sector_t block = from_cblock(cblock);
bio->bi_bdev = cache->cache_dev->bdev;
if (!block_size_is_power_of_two(cache))
- bio->bi_sector = (from_cblock(cblock) * cache->sectors_per_block) +
+ bio->bi_sector = (block * cache->sectors_per_block) +
sector_div(bi_sector, cache->sectors_per_block);
else
- bio->bi_sector = (from_cblock(cblock) << cache->sectors_per_block_shift) |
+ bio->bi_sector = (block << cache->sectors_per_block_shift) |
(bi_sector & (cache->sectors_per_block - 1));
}