summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/device-mapper/dm-raid.txt4
-rw-r--r--drivers/md/dm-raid.c82
2 files changed, 83 insertions, 3 deletions
diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt
index 4f9dd3cecc11..be4419a30781 100644
--- a/Documentation/device-mapper/dm-raid.txt
+++ b/Documentation/device-mapper/dm-raid.txt
@@ -52,6 +52,10 @@ The target is named "raid" and it accepts the following parameters:
52 [max_recovery_rate <kB/sec/disk>] Throttle RAID initialization 52 [max_recovery_rate <kB/sec/disk>] Throttle RAID initialization
53 [max_write_behind <sectors>] See '-write-behind=' (man mdadm) 53 [max_write_behind <sectors>] See '-write-behind=' (man mdadm)
54 [stripe_cache <sectors>] Stripe cache size (higher RAIDs only) 54 [stripe_cache <sectors>] Stripe cache size (higher RAIDs only)
55 [region_size <sectors>]
56 The region_size multiplied by the number of regions is the
57 logical size of the array. The bitmap records the device
58 synchronisation state for each region.
55 59
56<#raid_devs>: The number of devices composing the array. 60<#raid_devs>: The number of devices composing the array.
57 Each device consists of two entries. The first is the device 61 Each device consists of two entries. The first is the device
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index d4e95b2e39f6..a8a1915a450d 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -52,7 +52,7 @@ struct raid_dev {
52#define DMPF_MAX_RECOVERY_RATE 0x20 52#define DMPF_MAX_RECOVERY_RATE 0x20
53#define DMPF_MAX_WRITE_BEHIND 0x40 53#define DMPF_MAX_WRITE_BEHIND 0x40
54#define DMPF_STRIPE_CACHE 0x80 54#define DMPF_STRIPE_CACHE 0x80
55 55#define DMPF_REGION_SIZE 0X100
56struct raid_set { 56struct raid_set {
57 struct dm_target *ti; 57 struct dm_target *ti;
58 58
@@ -237,6 +237,67 @@ static int dev_parms(struct raid_set *rs, char **argv)
237} 237}
238 238
239/* 239/*
240 * validate_region_size
241 * @rs
242 * @region_size: region size in sectors. If 0, pick a size (4MiB default).
243 *
244 * Set rs->md.bitmap_info.chunksize (which really refers to 'region size').
245 * Ensure that (ti->len/region_size < 2^21) - required by MD bitmap.
246 *
247 * Returns: 0 on success, -EINVAL on failure.
248 */
249static int validate_region_size(struct raid_set *rs, unsigned long region_size)
250{
251 unsigned long min_region_size = rs->ti->len / (1 << 21);
252
253 if (!region_size) {
254 /*
255 * Choose a reasonable default. All figures in sectors.
256 */
257 if (min_region_size > (1 << 13)) {
258 DMINFO("Choosing default region size of %lu sectors",
259 region_size);
260 region_size = min_region_size;
261 } else {
262 DMINFO("Choosing default region size of 4MiB");
263 region_size = 1 << 13; /* sectors */
264 }
265 } else {
266 /*
267 * Validate user-supplied value.
268 */
269 if (region_size > rs->ti->len) {
270 rs->ti->error = "Supplied region size is too large";
271 return -EINVAL;
272 }
273
274 if (region_size < min_region_size) {
275 DMERR("Supplied region_size (%lu sectors) below minimum (%lu)",
276 region_size, min_region_size);
277 rs->ti->error = "Supplied region size is too small";
278 return -EINVAL;
279 }
280
281 if (!is_power_of_2(region_size)) {
282 rs->ti->error = "Region size is not a power of 2";
283 return -EINVAL;
284 }
285
286 if (region_size < rs->md.chunk_sectors) {
287 rs->ti->error = "Region size is smaller than the chunk size";
288 return -EINVAL;
289 }
290 }
291
292 /*
293 * Convert sectors to bytes.
294 */
295 rs->md.bitmap_info.chunksize = (region_size << 9);
296
297 return 0;
298}
299
300/*
240 * Possible arguments are... 301 * Possible arguments are...
241 * RAID456: 302 * RAID456:
242 * <chunk_size> [optional_args] 303 * <chunk_size> [optional_args]
@@ -249,12 +310,13 @@ static int dev_parms(struct raid_set *rs, char **argv)
249 * [max_recovery_rate <kB/sec/disk>] Throttle RAID initialization 310 * [max_recovery_rate <kB/sec/disk>] Throttle RAID initialization
250 * [max_write_behind <sectors>] See '-write-behind=' (man mdadm) 311 * [max_write_behind <sectors>] See '-write-behind=' (man mdadm)
251 * [stripe_cache <sectors>] Stripe cache size for higher RAIDs 312 * [stripe_cache <sectors>] Stripe cache size for higher RAIDs
313 * [region_size <sectors>] Defines granularity of bitmap
252 */ 314 */
253static int parse_raid_params(struct raid_set *rs, char **argv, 315static int parse_raid_params(struct raid_set *rs, char **argv,
254 unsigned num_raid_params) 316 unsigned num_raid_params)
255{ 317{
256 unsigned i, rebuild_cnt = 0; 318 unsigned i, rebuild_cnt = 0;
257 unsigned long value; 319 unsigned long value, region_size = 0;
258 char *key; 320 char *key;
259 321
260 /* 322 /*
@@ -365,6 +427,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
365 return -EINVAL; 427 return -EINVAL;
366 } 428 }
367 rs->md.sync_speed_max = (int)value; 429 rs->md.sync_speed_max = (int)value;
430 } else if (!strcasecmp(key, "region_size")) {
431 rs->print_flags |= DMPF_REGION_SIZE;
432 region_size = value;
368 } else { 433 } else {
369 DMERR("Unable to parse RAID parameter: %s", key); 434 DMERR("Unable to parse RAID parameter: %s", key);
370 rs->ti->error = "Unable to parse RAID parameters"; 435 rs->ti->error = "Unable to parse RAID parameters";
@@ -372,6 +437,14 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
372 } 437 }
373 } 438 }
374 439
440 if (validate_region_size(rs, region_size))
441 return -EINVAL;
442
443 if (rs->md.chunk_sectors)
444 rs->ti->split_io = rs->md.chunk_sectors;
445 else
446 rs->ti->split_io = region_size;
447
375 /* Assume there are no metadata devices until the drives are parsed */ 448 /* Assume there are no metadata devices until the drives are parsed */
376 rs->md.persistent = 0; 449 rs->md.persistent = 0;
377 rs->md.external = 1; 450 rs->md.external = 1;
@@ -469,7 +542,6 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
469 goto bad; 542 goto bad;
470 543
471 INIT_WORK(&rs->md.event_work, do_table_event); 544 INIT_WORK(&rs->md.event_work, do_table_event);
472 ti->split_io = rs->md.chunk_sectors;
473 ti->private = rs; 545 ti->private = rs;
474 546
475 mutex_lock(&rs->md.reconfig_mutex); 547 mutex_lock(&rs->md.reconfig_mutex);
@@ -596,6 +668,10 @@ static int raid_status(struct dm_target *ti, status_type_t type,
596 conf ? conf->max_nr_stripes * 2 : 0); 668 conf ? conf->max_nr_stripes * 2 : 0);
597 } 669 }
598 670
671 if (rs->print_flags & DMPF_REGION_SIZE)
672 DMEMIT(" region_size %lu",
673 rs->md.bitmap_info.chunksize >> 9);
674
599 DMEMIT(" %d", rs->md.raid_disks); 675 DMEMIT(" %d", rs->md.raid_disks);
600 for (i = 0; i < rs->md.raid_disks; i++) { 676 for (i = 0; i < rs->md.raid_disks; i++) {
601 DMEMIT(" -"); /* metadata device */ 677 DMEMIT(" -"); /* metadata device */