Skip to contentSkip to conversation

Introduction

PATCH New NeilBrown 2 participants 5 messages May 13, 2005 – May 24, 2005 MD RAID

lore
Share & tools
lore

NeilBrown

author
#0 lore raw

PATCH 1/1 Introduction

Hi again,
two more patches for md follow. Both raid1 related. These are happy to sit in the queue for after 2.6.12.

Thanks,
NeilBrown

[PATCH md 001 of 2] Cause md/raid1 to "repack" working devices when number of drives is changed. [PATCH md 002 of 2] Make sure recovery happens when add_new_disk is used for hot_add

author
#1 lore raw

PATCH 1/1 Cause md/raid1 to "repack" working devices when number of drives is changed.

i.e. missing or failed drives are moved to the end of the list. The means a 3 drive md array with the first drive missing can be shrunk to a two drive array. Currently that isn't possible.

Also, the "last_used" device number might be out-of-range after the number of devices is reduced, so we set it to 0.

### Diffstat output

 ./drivers/md/raid1.c |   24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)
drivers/md/raid1.c renamed from drivers/md/raid1.c~current~ +19 -5
diff ./drivers/md/raid1.c~current~ ./drivers/md/raid1.c
@@ -1485,17 +1485,26 @@ static int raid1_reshape(mddev_t *mddev,
 	 * We allocate a new r1bio_pool if we can.
 	 * Then raise a device barrier and wait until all IO stops.
 	 * Then resize conf->mirrors and swap in the new r1bio pool.
+	 *
+	 * At the same time, we "pack" the devices so that all the missing
+	 * devices have the higher raid_disk numbers.
 	 */
 	mempool_t *newpool, *oldpool;
 	struct pool_info *newpoolinfo;
 	mirror_info_t *newmirrors;
 	conf_t *conf = mddev_to_conf(mddev);
+	int cnt;
 
-	int d;
+	int d, d2;
 
-	for (d= raid_disks; d < conf->raid_disks; d++)
-		if (conf->mirrors[d].rdev)
+	if (raid_disks < conf->raid_disks) {
+		cnt=0;
+		for (d= 0; d < conf->raid_disks; d++)
+			if (conf->mirrors[d].rdev)
+				cnt++;
+		if (cnt > raid_disks)
 			return -EBUSY;
+	}
 
 	newpoolinfo = kmalloc(sizeof(*newpoolinfo), GFP_KERNEL);
 	if (!newpoolinfo)
@@ -1526,8 +1535,12 @@ static int raid1_reshape(mddev_t *mddev,
 	/* ok, everything is stopped */
 	oldpool = conf->r1bio_pool;
 	conf->r1bio_pool = newpool;
-	for (d=0; d < raid_disks && d < conf->raid_disks; d++)
-		newmirrors[d] = conf->mirrors[d];
+
+	for (d=d2=0; d < conf->raid_disks; d++)
+		if (conf->mirrors[d].rdev) {
+			conf->mirrors[d].rdev->raid_disk = d2;
+			newmirrors[d2++].rdev = conf->mirrors[d].rdev;
+		}
 	kfree(conf->mirrors);
 	conf->mirrors = newmirrors;
 	kfree(conf->poolinfo);
@@ -1536,6 +1549,7 @@ static int raid1_reshape(mddev_t *mddev,
 	mddev->degraded += (raid_disks - conf->raid_disks);
 	conf->raid_disks = mddev->raid_disks = raid_disks;
 
+	conf->last_used = 0; /* just make sure it is in-range */
 	spin_lock_irq(&conf->resync_lock);
 	conf->barrier--;
 	spin_unlock_irq(&conf->resync_lock);
author
#2 lore raw

PATCH 1/1 Make sure recovery happens when add_new_disk is used for hot_add

In reply to NeilBrown

Currently if add_new_disk is used to hot-add a drive to a degraded array, recovery doesn't start ... because we didn't tell it to.

### Diffstat output

 ./drivers/md/md.c |    2 ++
 1 files changed, 2 insertions(+)
drivers/md/md.c renamed from drivers/md/md.c~current~ +2 -0
diff ./drivers/md/md.c~current~ ./drivers/md/md.c
@@ -2232,6 +2232,8 @@ static int add_new_disk(mddev_t * mddev,
 		err = bind_rdev_to_array(rdev, mddev);
 		if (err)
 			export_rdev(rdev);
+
+		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 		if (mddev->thread)
 			md_wakeup_thread(mddev->thread);
 		return err;
#3 lore raw

PATCH 1/1 md: fix hot add for non-persistent superblock arrays

Neil,

hot add is not working for non-persistent superblock arrays (md is trying, and failing, to read a superblock from the new disk)...

attached patch fixes it...

Thanks,
Paul

 md.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletion(-)
drivers/md/md.c +2 -1
diff -purN --exclude-from /export/public/clemep/tmp/dontdiff linux-2.6.12-rc1-mm2-PRISTINE/drivers/md/md.c linux-2.6.12-rc1-mm2/drivers/md/md.c
@@ -2218,7 +2218,8 @@ static int add_new_disk(mddev_t * mddev,
 			       mdname(mddev));
 			return -EINVAL;
 		}
-		rdev = md_import_device(dev, mddev->major_version,
+		rdev = md_import_device(dev, mddev->persistent ?
+					mddev->major_version : -1,
 					mddev->minor_version);
 		if (IS_ERR(rdev)) {
 			printk(KERN_WARNING 
author
#4 lore raw

Re: [PATCH 1/1] md: fix hot add for non-persistent superblock arrays

Quoted 6 lines · On Thursday May 19, [email protected] wrote:

Neil,

hot add is not working for non-persistent superblock arrays (md is trying, and failing, to read a superblock from the new disk)...

attached patch fixes it...

Yep, that looks good, thanks.

NeilBrown

Quoted 21 lines

Thanks,
Paul

 md.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletion(-)

diff -purN --exclude-from /export/public/clemep/tmp/dontdiff linux-2.6.12-rc1-mm2-PRISTINE/drivers/md/md.c linux-2.6.12-rc1-mm2/drivers/md/md.c

drivers/md/md.c +2 -1
@@ -2218,7 +2218,8 @@ static int add_new_disk(mddev_t * mddev,
 			       mdname(mddev));
 			return -EINVAL;
 		}
-		rdev = md_import_device(dev, mddev->major_version,
+		rdev = md_import_device(dev, mddev->persistent ?
+					mddev->major_version : -1,
 					mddev->minor_version);
 		if (IS_ERR(rdev)) {
 			printk(KERN_WARNING