diff options
author | Heinz Mauelshagen <heinzm@redhat.com> | 2014-02-27 22:46:48 +0100 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2014-02-28 09:23:02 -0500 |
commit | e0d849fad746cb36a6822e4595d8ba9bf0adf7fa (patch) | |
tree | d5ea46f6692bc8de0260843a59d386db4bb9030c | |
parent | 7d48935eff401bb7970e73e822871a10e3643df1 (diff) | |
download | linux-e0d849fad746cb36a6822e4595d8ba9bf0adf7fa.tar.bz2 |
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
-rw-r--r-- | drivers/md/dm-cache-target.c | 5 |
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, dm_cblock_t cblock) { sector_t bi_sector = bio->bi_iter.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_iter.bi_sector = - (from_cblock(cblock) * cache->sectors_per_block) + + (block * cache->sectors_per_block) + sector_div(bi_sector, cache->sectors_per_block); else 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)); } |