diff options
| -rw-r--r-- | drivers/md/dm-thin.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 828649256902..93e3e542cff9 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -512,6 +512,7 @@ struct pool { | |||
| 512 | 512 | ||
| 513 | dm_block_t low_water_blocks; | 513 | dm_block_t low_water_blocks; |
| 514 | uint32_t sectors_per_block; | 514 | uint32_t sectors_per_block; |
| 515 | int sectors_per_block_shift; | ||
| 515 | 516 | ||
| 516 | struct pool_features pf; | 517 | struct pool_features pf; |
| 517 | unsigned low_water_triggered:1; /* A dm event has been sent */ | 518 | unsigned low_water_triggered:1; /* A dm event has been sent */ |
| @@ -679,7 +680,10 @@ static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio) | |||
| 679 | { | 680 | { |
| 680 | sector_t block_nr = bio->bi_sector; | 681 | sector_t block_nr = bio->bi_sector; |
| 681 | 682 | ||
| 682 | (void) sector_div(block_nr, tc->pool->sectors_per_block); | 683 | if (tc->pool->sectors_per_block_shift < 0) |
| 684 | (void) sector_div(block_nr, tc->pool->sectors_per_block); | ||
| 685 | else | ||
| 686 | block_nr >>= tc->pool->sectors_per_block_shift; | ||
| 683 | 687 | ||
| 684 | return block_nr; | 688 | return block_nr; |
| 685 | } | 689 | } |
| @@ -690,8 +694,12 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block) | |||
| 690 | sector_t bi_sector = bio->bi_sector; | 694 | sector_t bi_sector = bio->bi_sector; |
| 691 | 695 | ||
| 692 | bio->bi_bdev = tc->pool_dev->bdev; | 696 | bio->bi_bdev = tc->pool_dev->bdev; |
| 693 | bio->bi_sector = (block * pool->sectors_per_block) + | 697 | if (tc->pool->sectors_per_block_shift < 0) |
| 694 | sector_div(bi_sector, pool->sectors_per_block); | 698 | bio->bi_sector = (block * pool->sectors_per_block) + |
| 699 | sector_div(bi_sector, pool->sectors_per_block); | ||
| 700 | else | ||
| 701 | bio->bi_sector = (block << pool->sectors_per_block_shift) | | ||
| 702 | (bi_sector & (pool->sectors_per_block - 1)); | ||
| 695 | } | 703 | } |
| 696 | 704 | ||
| 697 | static void remap_to_origin(struct thin_c *tc, struct bio *bio) | 705 | static void remap_to_origin(struct thin_c *tc, struct bio *bio) |
| @@ -936,10 +944,7 @@ static void process_prepared(struct pool *pool, struct list_head *head, | |||
| 936 | */ | 944 | */ |
| 937 | static int io_overlaps_block(struct pool *pool, struct bio *bio) | 945 | static int io_overlaps_block(struct pool *pool, struct bio *bio) |
| 938 | { | 946 | { |
| 939 | sector_t bi_sector = bio->bi_sector; | 947 | return bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT); |
| 940 | |||
| 941 | return !sector_div(bi_sector, pool->sectors_per_block) && | ||
| 942 | (bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT)); | ||
| 943 | } | 948 | } |
| 944 | 949 | ||
| 945 | static int io_overwrites_block(struct pool *pool, struct bio *bio) | 950 | static int io_overwrites_block(struct pool *pool, struct bio *bio) |
| @@ -1721,6 +1726,10 @@ static struct pool *pool_create(struct mapped_device *pool_md, | |||
| 1721 | 1726 | ||
| 1722 | pool->pmd = pmd; | 1727 | pool->pmd = pmd; |
| 1723 | pool->sectors_per_block = block_size; | 1728 | pool->sectors_per_block = block_size; |
| 1729 | if (block_size & (block_size - 1)) | ||
| 1730 | pool->sectors_per_block_shift = -1; | ||
| 1731 | else | ||
| 1732 | pool->sectors_per_block_shift = __ffs(block_size); | ||
| 1724 | pool->low_water_blocks = 0; | 1733 | pool->low_water_blocks = 0; |
| 1725 | pool_features_init(&pool->pf); | 1734 | pool_features_init(&pool->pf); |
| 1726 | pool->prison = prison_create(PRISON_CELLS); | 1735 | pool->prison = prison_create(PRISON_CELLS); |
