diff options
author | Mike Snitzer <snitzer@redhat.com> | 2012-07-27 10:08:00 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 10:08:00 -0400 |
commit | 542f90381422676544382d4071ba44a2de90a0c1 (patch) | |
tree | 0eae6798ab2fdef68a0eb1ea5ac14f3cc3ffb740 /drivers/md/dm-snap.c | |
parent | 1df05483d758ea43abc375869fbe06be506ba827 (diff) |
dm: support non power of two target max_io_len
Remove the restriction that limits a target's specified maximum incoming
I/O size to be a power of 2.
Rename this setting from 'split_io' to the less-ambiguous 'max_io_len'.
Change it from sector_t to uint32_t, which is plenty big enough, and
introduce a wrapper function dm_set_target_max_io_len() to set it.
Use sector_div() to process it now that it is not necessarily a power of 2.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r-- | drivers/md/dm-snap.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a228c20e40b3..6c0f3e33923a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -691,7 +691,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) | |||
691 | * Return a minimum chunk size of all snapshots that have the specified origin. | 691 | * Return a minimum chunk size of all snapshots that have the specified origin. |
692 | * Return zero if the origin has no snapshots. | 692 | * Return zero if the origin has no snapshots. |
693 | */ | 693 | */ |
694 | static sector_t __minimum_chunk_size(struct origin *o) | 694 | static uint32_t __minimum_chunk_size(struct origin *o) |
695 | { | 695 | { |
696 | struct dm_snapshot *snap; | 696 | struct dm_snapshot *snap; |
697 | unsigned chunk_size = 0; | 697 | unsigned chunk_size = 0; |
@@ -701,7 +701,7 @@ static sector_t __minimum_chunk_size(struct origin *o) | |||
701 | chunk_size = min_not_zero(chunk_size, | 701 | chunk_size = min_not_zero(chunk_size, |
702 | snap->store->chunk_size); | 702 | snap->store->chunk_size); |
703 | 703 | ||
704 | return chunk_size; | 704 | return (uint32_t) chunk_size; |
705 | } | 705 | } |
706 | 706 | ||
707 | /* | 707 | /* |
@@ -1172,7 +1172,10 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1172 | ti->error = "Chunk size not set"; | 1172 | ti->error = "Chunk size not set"; |
1173 | goto bad_read_metadata; | 1173 | goto bad_read_metadata; |
1174 | } | 1174 | } |
1175 | ti->split_io = s->store->chunk_size; | 1175 | |
1176 | r = dm_set_target_max_io_len(ti, s->store->chunk_size); | ||
1177 | if (r) | ||
1178 | goto bad_read_metadata; | ||
1176 | 1179 | ||
1177 | return 0; | 1180 | return 0; |
1178 | 1181 | ||
@@ -1239,7 +1242,7 @@ static void __handover_exceptions(struct dm_snapshot *snap_src, | |||
1239 | snap_dest->store->snap = snap_dest; | 1242 | snap_dest->store->snap = snap_dest; |
1240 | snap_src->store->snap = snap_src; | 1243 | snap_src->store->snap = snap_src; |
1241 | 1244 | ||
1242 | snap_dest->ti->split_io = snap_dest->store->chunk_size; | 1245 | snap_dest->ti->max_io_len = snap_dest->store->chunk_size; |
1243 | snap_dest->valid = snap_src->valid; | 1246 | snap_dest->valid = snap_src->valid; |
1244 | 1247 | ||
1245 | /* | 1248 | /* |
@@ -1817,9 +1820,9 @@ static void snapshot_resume(struct dm_target *ti) | |||
1817 | up_write(&s->lock); | 1820 | up_write(&s->lock); |
1818 | } | 1821 | } |
1819 | 1822 | ||
1820 | static sector_t get_origin_minimum_chunksize(struct block_device *bdev) | 1823 | static uint32_t get_origin_minimum_chunksize(struct block_device *bdev) |
1821 | { | 1824 | { |
1822 | sector_t min_chunksize; | 1825 | uint32_t min_chunksize; |
1823 | 1826 | ||
1824 | down_read(&_origins_lock); | 1827 | down_read(&_origins_lock); |
1825 | min_chunksize = __minimum_chunk_size(__lookup_origin(bdev)); | 1828 | min_chunksize = __minimum_chunk_size(__lookup_origin(bdev)); |
@@ -1838,9 +1841,9 @@ static void snapshot_merge_resume(struct dm_target *ti) | |||
1838 | snapshot_resume(ti); | 1841 | snapshot_resume(ti); |
1839 | 1842 | ||
1840 | /* | 1843 | /* |
1841 | * snapshot-merge acts as an origin, so set ti->split_io | 1844 | * snapshot-merge acts as an origin, so set ti->max_io_len |
1842 | */ | 1845 | */ |
1843 | ti->split_io = get_origin_minimum_chunksize(s->origin->bdev); | 1846 | ti->max_io_len = get_origin_minimum_chunksize(s->origin->bdev); |
1844 | 1847 | ||
1845 | start_merge(s); | 1848 | start_merge(s); |
1846 | } | 1849 | } |
@@ -2073,12 +2076,12 @@ static int origin_write_extent(struct dm_snapshot *merging_snap, | |||
2073 | struct origin *o; | 2076 | struct origin *o; |
2074 | 2077 | ||
2075 | /* | 2078 | /* |
2076 | * The origin's __minimum_chunk_size() got stored in split_io | 2079 | * The origin's __minimum_chunk_size() got stored in max_io_len |
2077 | * by snapshot_merge_resume(). | 2080 | * by snapshot_merge_resume(). |
2078 | */ | 2081 | */ |
2079 | down_read(&_origins_lock); | 2082 | down_read(&_origins_lock); |
2080 | o = __lookup_origin(merging_snap->origin->bdev); | 2083 | o = __lookup_origin(merging_snap->origin->bdev); |
2081 | for (n = 0; n < size; n += merging_snap->ti->split_io) | 2084 | for (n = 0; n < size; n += merging_snap->ti->max_io_len) |
2082 | if (__origin_write(&o->snapshots, sector + n, NULL) == | 2085 | if (__origin_write(&o->snapshots, sector + n, NULL) == |
2083 | DM_MAPIO_SUBMITTED) | 2086 | DM_MAPIO_SUBMITTED) |
2084 | must_wait = 1; | 2087 | must_wait = 1; |
@@ -2138,14 +2141,14 @@ static int origin_map(struct dm_target *ti, struct bio *bio, | |||
2138 | } | 2141 | } |
2139 | 2142 | ||
2140 | /* | 2143 | /* |
2141 | * Set the target "split_io" field to the minimum of all the snapshots' | 2144 | * Set the target "max_io_len" field to the minimum of all the snapshots' |
2142 | * chunk sizes. | 2145 | * chunk sizes. |
2143 | */ | 2146 | */ |
2144 | static void origin_resume(struct dm_target *ti) | 2147 | static void origin_resume(struct dm_target *ti) |
2145 | { | 2148 | { |
2146 | struct dm_dev *dev = ti->private; | 2149 | struct dm_dev *dev = ti->private; |
2147 | 2150 | ||
2148 | ti->split_io = get_origin_minimum_chunksize(dev->bdev); | 2151 | ti->max_io_len = get_origin_minimum_chunksize(dev->bdev); |
2149 | } | 2152 | } |
2150 | 2153 | ||
2151 | static int origin_status(struct dm_target *ti, status_type_t type, char *result, | 2154 | static int origin_status(struct dm_target *ti, status_type_t type, char *result, |