diff options
| author | Mike Snitzer <snitzer@redhat.com> | 2010-08-11 23:14:10 -0400 |
|---|---|---|
| committer | Alasdair G Kergon <agk@redhat.com> | 2010-08-11 23:14:10 -0400 |
| commit | 56a67df766039666f61fb15b079f713e44a735ae (patch) | |
| tree | cfeeb4f0a151b440293da593c723e9982368a58f | |
| parent | 06a426cee9b35505aeb7516a67bd26496ca7ed08 (diff) | |
dm: factor out max_io_len_target_boundary
Split max_io_len_target_boundary out of max_io_len so that the discard
support can make use of it without duplicating max_io_len code.
Avoiding max_io_len's split_io logic enables DM's discard support to
submit the entire discard request to a target. But discards must still
be split on target boundaries.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
| -rw-r--r-- | drivers/md/dm.c | 26 | ||||
| -rw-r--r-- | include/linux/device-mapper.h | 6 |
2 files changed, 24 insertions, 8 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3dd846e801fb..561313a7dac2 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -1030,17 +1030,27 @@ static void end_clone_request(struct request *clone, int error) | |||
| 1030 | dm_complete_request(clone, error); | 1030 | dm_complete_request(clone, error); |
| 1031 | } | 1031 | } |
| 1032 | 1032 | ||
| 1033 | static sector_t max_io_len(struct mapped_device *md, | 1033 | /* |
| 1034 | sector_t sector, struct dm_target *ti) | 1034 | * Return maximum size of I/O possible at the supplied sector up to the current |
| 1035 | * target boundary. | ||
| 1036 | */ | ||
| 1037 | static sector_t max_io_len_target_boundary(sector_t sector, struct dm_target *ti) | ||
| 1038 | { | ||
| 1039 | sector_t target_offset = dm_target_offset(ti, sector); | ||
| 1040 | |||
| 1041 | return ti->len - target_offset; | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | static sector_t max_io_len(sector_t sector, struct dm_target *ti) | ||
| 1035 | { | 1045 | { |
| 1036 | sector_t offset = sector - ti->begin; | 1046 | sector_t len = max_io_len_target_boundary(sector, ti); |
| 1037 | sector_t len = ti->len - offset; | ||
| 1038 | 1047 | ||
| 1039 | /* | 1048 | /* |
| 1040 | * Does the target need to split even further ? | 1049 | * Does the target need to split even further ? |
| 1041 | */ | 1050 | */ |
| 1042 | if (ti->split_io) { | 1051 | if (ti->split_io) { |
| 1043 | sector_t boundary; | 1052 | sector_t boundary; |
| 1053 | sector_t offset = dm_target_offset(ti, sector); | ||
| 1044 | boundary = ((offset + ti->split_io) & ~(ti->split_io - 1)) | 1054 | boundary = ((offset + ti->split_io) & ~(ti->split_io - 1)) |
| 1045 | - offset; | 1055 | - offset; |
| 1046 | if (len > boundary) | 1056 | if (len > boundary) |
| @@ -1258,7 +1268,7 @@ static int __clone_and_map_discard(struct clone_info *ci) | |||
| 1258 | if (!ti->num_discard_requests) | 1268 | if (!ti->num_discard_requests) |
| 1259 | return -EOPNOTSUPP; | 1269 | return -EOPNOTSUPP; |
| 1260 | 1270 | ||
| 1261 | max = max_io_len(ci->md, ci->sector, ti); | 1271 | max = max_io_len(ci->sector, ti); |
| 1262 | 1272 | ||
| 1263 | if (ci->sector_count > max) | 1273 | if (ci->sector_count > max) |
| 1264 | /* | 1274 | /* |
| @@ -1290,7 +1300,7 @@ static int __clone_and_map(struct clone_info *ci) | |||
| 1290 | if (!dm_target_is_valid(ti)) | 1300 | if (!dm_target_is_valid(ti)) |
| 1291 | return -EIO; | 1301 | return -EIO; |
| 1292 | 1302 | ||
| 1293 | max = max_io_len(ci->md, ci->sector, ti); | 1303 | max = max_io_len(ci->sector, ti); |
| 1294 | 1304 | ||
| 1295 | if (ci->sector_count <= max) { | 1305 | if (ci->sector_count <= max) { |
| 1296 | /* | 1306 | /* |
| @@ -1341,7 +1351,7 @@ static int __clone_and_map(struct clone_info *ci) | |||
| 1341 | if (!dm_target_is_valid(ti)) | 1351 | if (!dm_target_is_valid(ti)) |
| 1342 | return -EIO; | 1352 | return -EIO; |
| 1343 | 1353 | ||
| 1344 | max = max_io_len(ci->md, ci->sector, ti); | 1354 | max = max_io_len(ci->sector, ti); |
| 1345 | } | 1355 | } |
| 1346 | 1356 | ||
| 1347 | len = min(remaining, max); | 1357 | len = min(remaining, max); |
| @@ -1428,7 +1438,7 @@ static int dm_merge_bvec(struct request_queue *q, | |||
| 1428 | /* | 1438 | /* |
| 1429 | * Find maximum amount of I/O that won't need splitting | 1439 | * Find maximum amount of I/O that won't need splitting |
| 1430 | */ | 1440 | */ |
| 1431 | max_sectors = min(max_io_len(md, bvm->bi_sector, ti), | 1441 | max_sectors = min(max_io_len(bvm->bi_sector, ti), |
| 1432 | (sector_t) BIO_MAX_SECTORS); | 1442 | (sector_t) BIO_MAX_SECTORS); |
| 1433 | max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size; | 1443 | max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size; |
| 1434 | if (max_size < 0) | 1444 | if (max_size < 0) |
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 751ce21dea7b..2970022faa63 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
| @@ -398,6 +398,12 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); | |||
| 398 | #define dm_array_too_big(fixed, obj, num) \ | 398 | #define dm_array_too_big(fixed, obj, num) \ |
| 399 | ((num) > (UINT_MAX - (fixed)) / (obj)) | 399 | ((num) > (UINT_MAX - (fixed)) / (obj)) |
| 400 | 400 | ||
| 401 | /* | ||
| 402 | * Sector offset taken relative to the start of the target instead of | ||
| 403 | * relative to the start of the device. | ||
| 404 | */ | ||
| 405 | #define dm_target_offset(ti, sector) ((sector) - (ti)->begin) | ||
| 406 | |||
| 401 | static inline sector_t to_sector(unsigned long n) | 407 | static inline sector_t to_sector(unsigned long n) |
| 402 | { | 408 | { |
| 403 | return (n >> SECTOR_SHIFT); | 409 | return (n >> SECTOR_SHIFT); |
