From 7eae7080e2e9edd69d31ae2c88d9e28d1c24217c Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 26 Jun 2006 12:26:09 +1000 Subject: [PATCH] Work around bug in --add handling for version-1 superblocks In 2.6.17 (and prior), the dev_number is ignored when a device is added to an active array. Rather the first free number is used. So we work around this by making sure we use the first free number for dev_number. Description... --- ChangeLog | 2 ++ Manage.c | 17 ++++++++++++++--- super1.c | 6 +++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6b1a13..ecbb598 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ Changes Prior to this release - Stop map_dev from returning [0:0], as that breaks things. - Add 'Array Slot' line to --examine for version-1 superblocks to make it a bit easier to see what is happening. + - Work around bug in --add handling for version-1 superblocks + in 2.6.17 (and prior). Changes Prior to 2.5.1 release - Various fixes for gcc warnings diff --git a/Manage.c b/Manage.c index a1e152c..1067bfe 100644 --- a/Manage.c +++ b/Manage.c @@ -271,8 +271,14 @@ int Manage_subdevs(char *devname, int fd, * If so, we can simply re-add it. */ st->ss->uuid_from_super(duuid, dsuper); - - if (osuper) { + + /* re-add doesn't work for version-1 superblocks + * before 2.6.18 :-( + */ + if (array.major_version == 1 && + get_linux_version() <= 2006018) + ; + else if (osuper) { st->ss->uuid_from_super(ouuid, osuper); if (memcmp(duuid, ouuid, sizeof(ouuid))==0) { /* look close enough for now. Kernel @@ -295,7 +301,12 @@ int Manage_subdevs(char *devname, int fd, } } } - for (j=0; j< st->max_devs; j++) { + /* in 2.6.17 and earlier, version-1 superblocks won't + * use the number we write, but will choose a free number. + * we must choose the same free number, which requires + * starting at 'raid_disks' and counting up + */ + for (j = array.raid_disks; j< st->max_devs; j++) { disc.number = j; if (ioctl(fd, GET_DISK_INFO, &disc)) break; diff --git a/super1.c b/super1.c index 6862155..8e6703b 100644 --- a/super1.c +++ b/super1.c @@ -779,7 +779,11 @@ static int write_init_super1(struct supertype *st, void *sbv, if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) { /* same array, so preserve events and dev_number */ sb->events = refsb->events; - sb->dev_number = refsb->dev_number; + /* bugs in 2.6.17 and earlier mean the dev_number + * chosen in Manage must be preserved + */ + if (get_linux_version() >= 2006018) + sb->dev_number = refsb->dev_number; } free(refsb); }