From 4c9f3f1ff45c816c9b46e8e98a91792657259eca Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 12 Aug 2010 04:14:10 +0100 Subject: [PATCH] --- yaml --- r: 209166 b: refs/heads/master c: 56a67df766039666f61fb15b079f713e44a735ae h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/md/dm.c | 26 ++++++++++++++++++-------- trunk/include/linux/device-mapper.h | 6 ++++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 0c895a097c78..6e4458060d25 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 06a426cee9b35505aeb7516a67bd26496ca7ed08 +refs/heads/master: 56a67df766039666f61fb15b079f713e44a735ae diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 3dd846e801fb..561313a7dac2 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -1030,17 +1030,27 @@ static void end_clone_request(struct request *clone, int error) dm_complete_request(clone, error); } -static sector_t max_io_len(struct mapped_device *md, - sector_t sector, struct dm_target *ti) +/* + * Return maximum size of I/O possible at the supplied sector up to the current + * target boundary. + */ +static sector_t max_io_len_target_boundary(sector_t sector, struct dm_target *ti) +{ + sector_t target_offset = dm_target_offset(ti, sector); + + return ti->len - target_offset; +} + +static sector_t max_io_len(sector_t sector, struct dm_target *ti) { - sector_t offset = sector - ti->begin; - sector_t len = ti->len - offset; + sector_t len = max_io_len_target_boundary(sector, ti); /* * Does the target need to split even further ? */ if (ti->split_io) { sector_t boundary; + sector_t offset = dm_target_offset(ti, sector); boundary = ((offset + ti->split_io) & ~(ti->split_io - 1)) - offset; if (len > boundary) @@ -1258,7 +1268,7 @@ static int __clone_and_map_discard(struct clone_info *ci) if (!ti->num_discard_requests) return -EOPNOTSUPP; - max = max_io_len(ci->md, ci->sector, ti); + max = max_io_len(ci->sector, ti); if (ci->sector_count > max) /* @@ -1290,7 +1300,7 @@ static int __clone_and_map(struct clone_info *ci) if (!dm_target_is_valid(ti)) return -EIO; - max = max_io_len(ci->md, ci->sector, ti); + max = max_io_len(ci->sector, ti); if (ci->sector_count <= max) { /* @@ -1341,7 +1351,7 @@ static int __clone_and_map(struct clone_info *ci) if (!dm_target_is_valid(ti)) return -EIO; - max = max_io_len(ci->md, ci->sector, ti); + max = max_io_len(ci->sector, ti); } len = min(remaining, max); @@ -1428,7 +1438,7 @@ static int dm_merge_bvec(struct request_queue *q, /* * Find maximum amount of I/O that won't need splitting */ - max_sectors = min(max_io_len(md, bvm->bi_sector, ti), + max_sectors = min(max_io_len(bvm->bi_sector, ti), (sector_t) BIO_MAX_SECTORS); max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size; if (max_size < 0) diff --git a/trunk/include/linux/device-mapper.h b/trunk/include/linux/device-mapper.h index 751ce21dea7b..2970022faa63 100644 --- a/trunk/include/linux/device-mapper.h +++ b/trunk/include/linux/device-mapper.h @@ -398,6 +398,12 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); #define dm_array_too_big(fixed, obj, num) \ ((num) > (UINT_MAX - (fixed)) / (obj)) +/* + * Sector offset taken relative to the start of the target instead of + * relative to the start of the device. + */ +#define dm_target_offset(ti, sector) ((sector) - (ti)->begin) + static inline sector_t to_sector(unsigned long n) { return (n >> SECTOR_SHIFT);