diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/faulty.c | 13 | ||||
-rw-r--r-- | drivers/md/md.c | 23 | ||||
-rw-r--r-- | drivers/md/md.h | 2 | ||||
-rw-r--r-- | drivers/md/raid5.c | 42 |
4 files changed, 41 insertions, 39 deletions
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 8695809b24b0..6513b7b3e379 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
@@ -255,14 +255,14 @@ static void status(struct seq_file *seq, mddev_t *mddev) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | 257 | ||
258 | static int reconfig(mddev_t *mddev, int layout, int chunk_size) | 258 | static int reconfig(mddev_t *mddev) |
259 | { | 259 | { |
260 | int mode = layout & ModeMask; | 260 | int mode = mddev->new_layout & ModeMask; |
261 | int count = layout >> ModeShift; | 261 | int count = mddev->new_layout >> ModeShift; |
262 | conf_t *conf = mddev->private; | 262 | conf_t *conf = mddev->private; |
263 | 263 | ||
264 | if (chunk_size != -1) | 264 | if (mddev->new_layout < 0) |
265 | return -EINVAL; | 265 | return 0; |
266 | 266 | ||
267 | /* new layout */ | 267 | /* new layout */ |
268 | if (mode == ClearFaults) | 268 | if (mode == ClearFaults) |
@@ -279,6 +279,7 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size) | |||
279 | atomic_set(&conf->counters[mode], count); | 279 | atomic_set(&conf->counters[mode], count); |
280 | } else | 280 | } else |
281 | return -EINVAL; | 281 | return -EINVAL; |
282 | mddev->new_layout = -1; | ||
282 | mddev->layout = -1; /* makes sure further changes come through */ | 283 | mddev->layout = -1; /* makes sure further changes come through */ |
283 | return 0; | 284 | return 0; |
284 | } | 285 | } |
@@ -315,7 +316,7 @@ static int run(mddev_t *mddev) | |||
315 | md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); | 316 | md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); |
316 | mddev->private = conf; | 317 | mddev->private = conf; |
317 | 318 | ||
318 | reconfig(mddev, mddev->layout, -1); | 319 | reconfig(mddev); |
319 | 320 | ||
320 | return 0; | 321 | return 0; |
321 | } | 322 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index f996d8342a85..5caa421c2367 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2809,9 +2809,12 @@ layout_store(mddev_t *mddev, const char *buf, size_t len) | |||
2809 | int err; | 2809 | int err; |
2810 | if (mddev->pers->reconfig == NULL) | 2810 | if (mddev->pers->reconfig == NULL) |
2811 | return -EBUSY; | 2811 | return -EBUSY; |
2812 | err = mddev->pers->reconfig(mddev, n, -1); | 2812 | mddev->new_layout = n; |
2813 | if (err) | 2813 | err = mddev->pers->reconfig(mddev); |
2814 | if (err) { | ||
2815 | mddev->new_layout = mddev->layout; | ||
2814 | return err; | 2816 | return err; |
2817 | } | ||
2815 | } else { | 2818 | } else { |
2816 | mddev->new_layout = n; | 2819 | mddev->new_layout = n; |
2817 | if (mddev->reshape_position == MaxSector) | 2820 | if (mddev->reshape_position == MaxSector) |
@@ -2884,9 +2887,12 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len) | |||
2884 | int err; | 2887 | int err; |
2885 | if (mddev->pers->reconfig == NULL) | 2888 | if (mddev->pers->reconfig == NULL) |
2886 | return -EBUSY; | 2889 | return -EBUSY; |
2887 | err = mddev->pers->reconfig(mddev, -1, n); | 2890 | mddev->new_chunk_sectors = n >> 9; |
2888 | if (err) | 2891 | err = mddev->pers->reconfig(mddev); |
2892 | if (err) { | ||
2893 | mddev->new_chunk_sectors = mddev->chunk_sectors; | ||
2889 | return err; | 2894 | return err; |
2895 | } | ||
2890 | } else { | 2896 | } else { |
2891 | mddev->new_chunk_sectors = n >> 9; | 2897 | mddev->new_chunk_sectors = n >> 9; |
2892 | if (mddev->reshape_position == MaxSector) | 2898 | if (mddev->reshape_position == MaxSector) |
@@ -5220,8 +5226,13 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
5220 | */ | 5226 | */ |
5221 | if (mddev->pers->reconfig == NULL) | 5227 | if (mddev->pers->reconfig == NULL) |
5222 | return -EINVAL; | 5228 | return -EINVAL; |
5223 | else | 5229 | else { |
5224 | return mddev->pers->reconfig(mddev, info->layout, -1); | 5230 | mddev->new_layout = info->layout; |
5231 | rv = mddev->pers->reconfig(mddev); | ||
5232 | if (rv) | ||
5233 | mddev->new_layout = mddev->layout; | ||
5234 | return rv; | ||
5235 | } | ||
5225 | } | 5236 | } |
5226 | if (info->size >= 0 && mddev->dev_sectors / 2 != info->size) | 5237 | if (info->size >= 0 && mddev->dev_sectors / 2 != info->size) |
5227 | rv = update_size(mddev, (sector_t)info->size * 2); | 5238 | rv = update_size(mddev, (sector_t)info->size * 2); |
diff --git a/drivers/md/md.h b/drivers/md/md.h index e0a2b8e3985d..815013f8da6c 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -326,7 +326,7 @@ struct mdk_personality | |||
326 | int (*check_reshape) (mddev_t *mddev); | 326 | int (*check_reshape) (mddev_t *mddev); |
327 | int (*start_reshape) (mddev_t *mddev); | 327 | int (*start_reshape) (mddev_t *mddev); |
328 | void (*finish_reshape) (mddev_t *mddev); | 328 | void (*finish_reshape) (mddev_t *mddev); |
329 | int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); | 329 | int (*reconfig) (mddev_t *mddev); |
330 | /* quiesce moves between quiescence states | 330 | /* quiesce moves between quiescence states |
331 | * 0 - fully active | 331 | * 0 - fully active |
332 | * 1 - no new requests allowed | 332 | * 1 - no new requests allowed |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index b84766e347c3..136051bc6725 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -5165,7 +5165,7 @@ static void *raid5_takeover_raid6(mddev_t *mddev) | |||
5165 | } | 5165 | } |
5166 | 5166 | ||
5167 | 5167 | ||
5168 | static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk) | 5168 | static int raid5_reconfig(mddev_t *mddev) |
5169 | { | 5169 | { |
5170 | /* For a 2-drive array, the layout and chunk size can be changed | 5170 | /* For a 2-drive array, the layout and chunk size can be changed |
5171 | * immediately as not restriping is needed. | 5171 | * immediately as not restriping is needed. |
@@ -5173,15 +5173,16 @@ static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk) | |||
5173 | * to be used by a reshape pass. | 5173 | * to be used by a reshape pass. |
5174 | */ | 5174 | */ |
5175 | raid5_conf_t *conf = mddev->private; | 5175 | raid5_conf_t *conf = mddev->private; |
5176 | int new_chunk = mddev->new_chunk_sectors; | ||
5176 | 5177 | ||
5177 | if (new_layout >= 0 && !algorithm_valid_raid5(new_layout)) | 5178 | if (mddev->new_layout >= 0 && !algorithm_valid_raid5(mddev->new_layout)) |
5178 | return -EINVAL; | 5179 | return -EINVAL; |
5179 | if (new_chunk > 0) { | 5180 | if (new_chunk > 0) { |
5180 | if (!is_power_of_2(new_chunk)) | 5181 | if (!is_power_of_2(new_chunk)) |
5181 | return -EINVAL; | 5182 | return -EINVAL; |
5182 | if (new_chunk < PAGE_SIZE) | 5183 | if (new_chunk < (PAGE_SIZE>>9)) |
5183 | return -EINVAL; | 5184 | return -EINVAL; |
5184 | if (mddev->array_sectors & ((new_chunk>>9)-1)) | 5185 | if (mddev->array_sectors & (new_chunk-1)) |
5185 | /* not factor of array size */ | 5186 | /* not factor of array size */ |
5186 | return -EINVAL; | 5187 | return -EINVAL; |
5187 | } | 5188 | } |
@@ -5189,48 +5190,37 @@ static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk) | |||
5189 | /* They look valid */ | 5190 | /* They look valid */ |
5190 | 5191 | ||
5191 | if (mddev->raid_disks == 2) { | 5192 | if (mddev->raid_disks == 2) { |
5192 | 5193 | /* can make the change immediately */ | |
5193 | if (new_layout >= 0) { | 5194 | if (mddev->new_layout >= 0) { |
5194 | conf->algorithm = new_layout; | 5195 | conf->algorithm = mddev->new_layout; |
5195 | mddev->layout = mddev->new_layout = new_layout; | 5196 | mddev->layout = mddev->new_layout; |
5196 | } | 5197 | } |
5197 | if (new_chunk > 0) { | 5198 | if (new_chunk > 0) { |
5198 | conf->chunk_sectors = new_chunk >> 9; | 5199 | conf->chunk_sectors = new_chunk ; |
5199 | mddev->new_chunk_sectors = new_chunk >> 9; | 5200 | mddev->chunk_sectors = new_chunk; |
5200 | mddev->chunk_sectors = new_chunk >> 9; | ||
5201 | } | 5201 | } |
5202 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 5202 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
5203 | md_wakeup_thread(mddev->thread); | 5203 | md_wakeup_thread(mddev->thread); |
5204 | } else { | ||
5205 | if (new_layout >= 0) | ||
5206 | mddev->new_layout = new_layout; | ||
5207 | if (new_chunk > 0) | ||
5208 | mddev->new_chunk_sectors = new_chunk >> 9; | ||
5209 | } | 5204 | } |
5210 | return 0; | 5205 | return 0; |
5211 | } | 5206 | } |
5212 | 5207 | ||
5213 | static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk) | 5208 | static int raid6_reconfig(mddev_t *mddev) |
5214 | { | 5209 | { |
5215 | if (new_layout >= 0 && !algorithm_valid_raid6(new_layout)) | 5210 | int new_chunk = mddev->new_chunk_sectors; |
5211 | if (mddev->new_layout >= 0 && !algorithm_valid_raid6(mddev->new_layout)) | ||
5216 | return -EINVAL; | 5212 | return -EINVAL; |
5217 | if (new_chunk > 0) { | 5213 | if (new_chunk > 0) { |
5218 | if (!is_power_of_2(new_chunk)) | 5214 | if (!is_power_of_2(new_chunk)) |
5219 | return -EINVAL; | 5215 | return -EINVAL; |
5220 | if (new_chunk < PAGE_SIZE) | 5216 | if (new_chunk < (PAGE_SIZE >> 9)) |
5221 | return -EINVAL; | 5217 | return -EINVAL; |
5222 | if (mddev->array_sectors & ((new_chunk>>9)-1)) | 5218 | if (mddev->array_sectors & (new_chunk-1)) |
5223 | /* not factor of array size */ | 5219 | /* not factor of array size */ |
5224 | return -EINVAL; | 5220 | return -EINVAL; |
5225 | } | 5221 | } |
5226 | 5222 | ||
5227 | /* They look valid */ | 5223 | /* They look valid */ |
5228 | |||
5229 | if (new_layout >= 0) | ||
5230 | mddev->new_layout = new_layout; | ||
5231 | if (new_chunk > 0) | ||
5232 | mddev->new_chunk_sectors = new_chunk >> 9; | ||
5233 | |||
5234 | return 0; | 5224 | return 0; |
5235 | } | 5225 | } |
5236 | 5226 | ||