diff options
author | NeilBrown <neilb@suse.de> | 2012-08-01 06:40:02 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-08-01 06:40:02 -0400 |
commit | bb181e2e48f8c85db08c9cb015cbba9618dbf05c (patch) | |
tree | 191bc24dd97bcb174535cc217af082f16da3b43d /drivers/md/dm.c | |
parent | d57368afe63b3b7b45ce6c2b8c5276417935be2f (diff) | |
parent | c039c332f23e794deb6d6f37b9f07ff3b27fb2cf (diff) |
Merge commit 'c039c332f23e794deb6d6f37b9f07ff3b27fb2cf' into md
Pull in pre-requisites for adding raid10 support to dm-raid.
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index e24143cc2040..4e09b6ff5b49 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -968,22 +968,41 @@ static sector_t max_io_len_target_boundary(sector_t sector, struct dm_target *ti | |||
968 | static sector_t max_io_len(sector_t sector, struct dm_target *ti) | 968 | static sector_t max_io_len(sector_t sector, struct dm_target *ti) |
969 | { | 969 | { |
970 | sector_t len = max_io_len_target_boundary(sector, ti); | 970 | sector_t len = max_io_len_target_boundary(sector, ti); |
971 | sector_t offset, max_len; | ||
971 | 972 | ||
972 | /* | 973 | /* |
973 | * Does the target need to split even further ? | 974 | * Does the target need to split even further? |
974 | */ | 975 | */ |
975 | if (ti->split_io) { | 976 | if (ti->max_io_len) { |
976 | sector_t boundary; | 977 | offset = dm_target_offset(ti, sector); |
977 | sector_t offset = dm_target_offset(ti, sector); | 978 | if (unlikely(ti->max_io_len & (ti->max_io_len - 1))) |
978 | boundary = ((offset + ti->split_io) & ~(ti->split_io - 1)) | 979 | max_len = sector_div(offset, ti->max_io_len); |
979 | - offset; | 980 | else |
980 | if (len > boundary) | 981 | max_len = offset & (ti->max_io_len - 1); |
981 | len = boundary; | 982 | max_len = ti->max_io_len - max_len; |
983 | |||
984 | if (len > max_len) | ||
985 | len = max_len; | ||
982 | } | 986 | } |
983 | 987 | ||
984 | return len; | 988 | return len; |
985 | } | 989 | } |
986 | 990 | ||
991 | int dm_set_target_max_io_len(struct dm_target *ti, sector_t len) | ||
992 | { | ||
993 | if (len > UINT_MAX) { | ||
994 | DMERR("Specified maximum size of target IO (%llu) exceeds limit (%u)", | ||
995 | (unsigned long long)len, UINT_MAX); | ||
996 | ti->error = "Maximum size of target IO is too large"; | ||
997 | return -EINVAL; | ||
998 | } | ||
999 | |||
1000 | ti->max_io_len = (uint32_t) len; | ||
1001 | |||
1002 | return 0; | ||
1003 | } | ||
1004 | EXPORT_SYMBOL_GPL(dm_set_target_max_io_len); | ||
1005 | |||
987 | static void __map_bio(struct dm_target *ti, struct bio *clone, | 1006 | static void __map_bio(struct dm_target *ti, struct bio *clone, |
988 | struct dm_target_io *tio) | 1007 | struct dm_target_io *tio) |
989 | { | 1008 | { |
@@ -1196,7 +1215,10 @@ static int __clone_and_map_discard(struct clone_info *ci) | |||
1196 | if (!ti->num_discard_requests) | 1215 | if (!ti->num_discard_requests) |
1197 | return -EOPNOTSUPP; | 1216 | return -EOPNOTSUPP; |
1198 | 1217 | ||
1199 | len = min(ci->sector_count, max_io_len_target_boundary(ci->sector, ti)); | 1218 | if (!ti->split_discard_requests) |
1219 | len = min(ci->sector_count, max_io_len_target_boundary(ci->sector, ti)); | ||
1220 | else | ||
1221 | len = min(ci->sector_count, max_io_len(ci->sector, ti)); | ||
1200 | 1222 | ||
1201 | __issue_target_requests(ci, ti, ti->num_discard_requests, len); | 1223 | __issue_target_requests(ci, ti, ti->num_discard_requests, len); |
1202 | 1224 | ||