From patchwork Thu Apr 28 19:10:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonthan Brassow X-Patchwork-Id: 739551 X-Patchwork-Delegate: agk@redhat.com Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3SJD4R3022562 for ; Thu, 28 Apr 2011 19:13:26 GMT Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p3SJAO2l028724; Thu, 28 Apr 2011 15:10:26 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p3SJANq3024241 for ; Thu, 28 Apr 2011 15:10:23 -0400 Received: from mx1.redhat.com (ext-mx12.extmail.prod.ext.phx2.redhat.com [10.5.110.17]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p3SJAIpB030941 for ; Thu, 28 Apr 2011 15:10:18 -0400 Received: from localhost6.localdomain6 ([75.72.197.0]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p3SJAEK8014108 for ; Thu, 28 Apr 2011 15:10:14 -0400 Received: from localhost6.localdomain6 (localhost.localdomain [127.0.0.1]) by localhost6.localdomain6 (8.14.4/8.14.4) with ESMTP id p3SJADtW029449 for ; Thu, 28 Apr 2011 14:10:13 -0500 Received: (from jbrassow@localhost) by localhost6.localdomain6 (8.14.4/8.14.4/Submit) id p3SJADWK029447 for dm-devel@redhat.com; Thu, 28 Apr 2011 14:10:13 -0500 From: Jonathan Brassow Message-Id: <201104281910.p3SJADWK029447@localhost6.localdomain6> Date: Thu, 28 Apr 2011 14:10:13 -0500 To: dm-devel@redhat.com User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 X-RedHat-Blacklist-Warning: Relay 75.72.197.0 is blacklisted by a RBL system X-RedHat-NoPTR: 75.72.197.0 has sent a message and has no valid PTR record X-RedHat-Spam-Score: 5.212 ***** (NO_DNS_FOR_FROM, RCVD_IN_PBL, RCVD_IN_SORBS_DUL, RDNS_NONE) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Scanned-By: MIMEDefang 2.68 on 10.5.110.17 Subject: [dm-devel] [PATCH] DM RAID: add region_size param X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 28 Apr 2011 19:13:26 +0000 (UTC) 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 --- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel 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: * [optional_args] @@ -247,12 +298,13 @@ static int dev_parms(struct raid_set *rs * [max_recovery_rate ] Throttle RAID initialization * [max_write_behind ] See '-write-behind=' (man mdadm) * [stripe_cache ] Stripe cache size for higher RAIDs + * [region_size ] 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++) {