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...
This commit is contained in:
Neil Brown 2006-06-26 12:26:09 +10:00
parent c3684618b7
commit 7eae7080e2
3 changed files with 21 additions and 4 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);
}