Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Device-mapper Development (http://www.linux-archive.org/device-mapper-development/)
-   -   DM RAID: add region_size param (http://www.linux-archive.org/device-mapper-development/519648-dm-raid-add-region_size-param.html)

Jonathan Brassow 04-28-2011 07:10 PM

DM RAID: add region_size param
 
Patch name: dm-raid-add-region_size-param.patch

Allow the user to specify region_size. Ensure that the supplied value meets
MD's constraints that the number of regions does not exceed 2^21.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>

Index: linux-2.6/drivers/md/dm-raid.c
================================================== =================
--- linux-2.6.orig/drivers/md/dm-raid.c
+++ linux-2.6/drivers/md/dm-raid.c
@@ -50,6 +50,7 @@ struct raid_dev {
#define DMPF_STRIPE_CACHE 0x10
#define DMPF_MIN_RECOVERY_RATE 0x20
#define DMPF_MAX_RECOVERY_RATE 0x40
+#define DMPF_REGION_SIZE 0x80

struct raid_set {
struct dm_target *ti;
@@ -235,6 +236,56 @@ static int dev_parms(struct raid_set *rs
}

/*
+ * validate_region_size
+ * @rs
+ * @region_size: region size in sectors. If 0, pick a size (4MiB default)
+ *
+ * Set rs->md.bitmap_info.chunksize (which really refers to 'region size')
+ * Ensure that (ti->len/region_size < 2^21) - required by MD bitmap
+ *
+ * Returns: 0 on success, -EINVAL on failure
+ */
+static int validate_region_size(struct raid_set *rs, unsigned long region_size)
+{
+ unsigned long min_region_size = rs->ti->len / (1 << 21);
+
+ if (!region_size) {
+ /* Pick a reasonable default - Math in sectors */
+
+ if (min_region_size > (1 << 13)) {
+ DMINFO("Choosing default region size of %lu sectors",
+ region_size);
+ rs->md.bitmap_info.chunksize = min_region_size;
+ } else {
+ DMINFO("Choosing default region size of 4MiB");
+ rs->md.bitmap_info.chunksize = 1 << 13; /* sectors */
+ }
+ } else {
+ /* User-supplied value - validate it */
+
+ if (region_size > rs->ti->len) {
+ rs->ti->error = "Supplied region size is too large";
+ return -EINVAL;
+ }
+
+ if (region_size < min_region_size) {
+ DMERR("Supplied region_size = %lu (Min = %lu)",
+ region_size, min_region_size);
+ rs->ti->error = "Supplied region size is too small";
+ return -EINVAL;
+ }
+
+ rs->md.bitmap_info.chunksize = region_size;
+ }
+
+ /* Convert to Bytes */
+ rs->md.bitmap_info.chunksize <<= 9;
+
+ return 0;
+}
+
+
+/*
* Possible arguments are...
* RAID456:
* <chunk_size> [optional_args]
@@ -247,12 +298,13 @@ static int dev_parms(struct raid_set *rs
* [max_recovery_rate <kB/sec/disk>] Throttle RAID initialization
* [max_write_behind <sectors>] See '-write-behind=' (man mdadm)
* [stripe_cache <sectors>] Stripe cache size for higher RAIDs
+ * [region_size <sectors>] Defines granularity of bitmap
*/
static int parse_raid_params(struct raid_set *rs, char **argv,
unsigned num_raid_params)
{
unsigned i, rebuild_cnt = 0;
- unsigned long value;
+ unsigned long value, region_size = 0;
char *key;

/*
@@ -362,6 +414,13 @@ static int parse_raid_params(struct raid
return -EINVAL;
}
rs->md.sync_speed_max = (int)value;
+ } else if (!strcmp(key, "region_size")) {
+ rs->print_flags |= DMPF_REGION_SIZE;
+ region_size = value;
+ if (!is_power_of_2(region_size)) {
+ rs->ti->error = "Region size is not a power of 2";
+ return -EINVAL;
+ }
} else {
DMERR("Unable to parse RAID parameter: %s", key);
rs->ti->error = "Unable to parse RAID parameters";
@@ -369,6 +428,9 @@ static int parse_raid_params(struct raid
}
}

+ if (validate_region_size(rs, region_size))
+ return -EINVAL;
+
/* Assume there are no metadata devices until the drives are parsed */
rs->md.persistent = 0;
rs->md.external = 1;
@@ -571,7 +633,6 @@ static int raid_status(struct dm_target
DMEMIT(" sync");
if (rs->print_flags & DMPF_NOSYNC)
DMEMIT(" nosync");
-
for (i = 0; i < rs->md.raid_disks; i++)
if (rs->dev[i].data_dev &&
!test_bit(In_sync, &rs->dev[i].rdev.flags))
@@ -598,6 +659,9 @@ static int raid_status(struct dm_target
DMEMIT(" stripe_cache %d",
conf ? conf->max_nr_stripes * 2 : 0);
}
+ if (rs->print_flags & DMPF_REGION_SIZE)
+ DMEMIT(" region_size %lu",
+ rs->md.bitmap_info.chunksize >> 9);

DMEMIT(" %d", rs->md.raid_disks);
for (i = 0; i < rs->md.raid_disks; i++) {
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Mike Snitzer 04-28-2011 07:17 PM

DM RAID: add region_size param
 
On Thu, Apr 28 2011 at 3:10pm -0400,
Jonathan Brassow <jbrassow@redhat.com> wrote:

> Patch name: dm-raid-add-region_size-param.patch
>
> Allow the user to specify region_size. Ensure that the supplied value meets
> MD's constraints that the number of regions does not exceed 2^21.

Would it make any sense to have MD #define this 2^21 limit so that DM
can just include it?

Mike
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Jonathan Brassow 06-08-2011 10:17 PM

DM RAID: add region_size param
 
Allow the user to specify region_size. Ensure that the supplied value meets
MD's constraints that the number of regions does not exceed 2^21.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>

Index: linux-2.6/drivers/md/dm-raid.c
================================================== =================
--- linux-2.6.orig/drivers/md/dm-raid.c
+++ linux-2.6/drivers/md/dm-raid.c
@@ -51,7 +51,7 @@ struct raid_dev {
#define DMPF_MAX_RECOVERY_RATE 0x20
#define DMPF_MAX_WRITE_BEHIND 0x40
#define DMPF_STRIPE_CACHE 0x80
-
+#define DMPF_REGION_SIZE 0X100
struct raid_set {
struct dm_target *ti;

@@ -236,6 +236,65 @@ static int dev_parms(struct raid_set *rs
}

/*
+ * validate_region_size
+ * @rs
+ * @region_size: region size in sectors. If 0, pick a size (4MiB default)
+ *
+ * Set rs->md.bitmap_info.chunksize (which really refers to 'region size')
+ * Ensure that (ti->len/region_size < 2^21) - required by MD bitmap
+ *
+ * Returns: 0 on success, -EINVAL on failure
+ */
+static int validate_region_size(struct raid_set *rs, unsigned long region_size)
+{
+ unsigned long min_region_size = rs->ti->len / (1 << 21);
+
+ if (!region_size) {
+ /* Pick a reasonable default - Math in sectors */
+
+ if (min_region_size > (1 << 13)) {
+ DMINFO("Choosing default region size of %lu sectors",
+ region_size);
+ rs->md.bitmap_info.chunksize = min_region_size;
+ } else {
+ DMINFO("Choosing default region size of 4MiB");
+ rs->md.bitmap_info.chunksize = 1 << 13; /* sectors */
+ }
+ } else {
+ /* User-supplied value - validate it */
+
+ if (region_size > rs->ti->len) {
+ rs->ti->error = "Supplied region size is too large";
+ return -EINVAL;
+ }
+
+ if (region_size < min_region_size) {
+ DMERR("Supplied region_size = %lu (Min = %lu)",
+ region_size, min_region_size);
+ rs->ti->error = "Supplied region size is too small";
+ return -EINVAL;
+ }
+
+ if (!is_power_of_2(region_size)) {
+ rs->ti->error = "Region size is not a power of 2";
+ return -EINVAL;
+ }
+
+ if (region_size < rs->md.chunk_sectors) {
+ rs->ti->error = "Region size is smaller than the chunk size";
+ return -EINVAL;
+ }
+ rs->md.bitmap_info.chunksize = region_size;
+ }
+
+ /* Convert to Bytes */
+ rs->md.bitmap_info.chunksize <<= 9;
+
+ return 0;
+}
+
+
+/*
* Possible arguments are...
* RAID456:
* <chunk_size> [optional_args]
@@ -248,12 +307,13 @@ static int dev_parms(struct raid_set *rs
* [max_recovery_rate <kB/sec/disk>] Throttle RAID initialization
* [max_write_behind <sectors>] See '-write-behind=' (man mdadm)
* [stripe_cache <sectors>] Stripe cache size for higher RAIDs
+ * [region_size <sectors>] Defines granularity of bitmap
*/
static int parse_raid_params(struct raid_set *rs, char **argv,
unsigned num_raid_params)
{
unsigned i, rebuild_cnt = 0;
- unsigned long value;
+ unsigned long value, region_size = 0;
char *key;

/*
@@ -364,6 +424,9 @@ static int parse_raid_params(struct raid
return -EINVAL;
}
rs->md.sync_speed_max = (int)value;
+ } else if (!strcmp(key, "region_size")) {
+ rs->print_flags |= DMPF_REGION_SIZE;
+ region_size = value;
} else {
DMERR("Unable to parse RAID parameter: %s", key);
rs->ti->error = "Unable to parse RAID parameters";
@@ -371,6 +434,14 @@ static int parse_raid_params(struct raid
}
}

+ if (validate_region_size(rs, region_size))
+ return -EINVAL;
+
+ if (rs->md.chunk_sectors)
+ rs->ti->split_io = rs->md.chunk_sectors;
+ else
+ rs->ti->split_io = region_size;
+
/* Assume there are no metadata devices until the drives are parsed */
rs->md.persistent = 0;
rs->md.external = 1;
@@ -468,7 +539,6 @@ static int raid_ctr(struct dm_target *ti
goto bad;

INIT_WORK(&rs->md.event_work, do_table_event);
- ti->split_io = rs->md.chunk_sectors;
ti->private = rs;

mutex_lock(&rs->md.reconfig_mutex);
@@ -566,7 +636,6 @@ static int raid_status(struct dm_target
DMEMIT(" sync");
if (rs->print_flags & DMPF_NOSYNC)
DMEMIT(" nosync");
-
for (i = 0; i < rs->md.raid_disks; i++)
if ((rs->print_flags & DMPF_REBUILD) &&
rs->dev[i].data_dev &&
@@ -594,6 +663,9 @@ static int raid_status(struct dm_target
DMEMIT(" stripe_cache %d",
conf ? conf->max_nr_stripes * 2 : 0);
}
+ if (rs->print_flags & DMPF_REGION_SIZE)
+ DMEMIT(" region_size %lu",
+ rs->md.bitmap_info.chunksize >> 9);

DMEMIT(" %d", rs->md.raid_disks);
for (i = 0; i < rs->md.raid_disks; i++) {
Index: linux-2.6/Documentation/device-mapper/dm-raid.txt
================================================== =================
--- linux-2.6.orig/Documentation/device-mapper/dm-raid.txt
+++ linux-2.6/Documentation/device-mapper/dm-raid.txt
@@ -35,6 +35,9 @@ The possible parameters are as follows:
[max_recovery_rate <kB/sec/disk>] Throttle RAID initialization
[max_write_behind <sectors>] See '-write-behind=' (man mdadm)
[stripe_cache <sectors>] Stripe cache size for higher RAIDs
+ [region_size <sectors>] Array_size / region_size = # of regions. A
+ region is the granularity at which the bitmap
+ tracks whether a device is in-sync or not.

Line 3 contains the list of devices that compose the array in
metadata/data device pairs. If the metadata is stored separately, a '-'


--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel


All times are GMT. The time now is 02:48 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.