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); |