diff options
author | Neil Brown <neilb@suse.de> | 2006-06-26 04:26:09 +0200 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2006-06-26 04:26:09 +0200 |
commit | 7eae7080e2e9edd69d31ae2c88d9e28d1c24217c (patch) | |
tree | 4418e400c725690d29f3e66752515bab63f3fe77 | |
parent | Add 'Array Slot' line to --examine for version-1 superblocks (diff) | |
download | mdadm-7eae7080e2e9edd69d31ae2c88d9e28d1c24217c.tar.xz mdadm-7eae7080e2e9edd69d31ae2c88d9e28d1c24217c.zip |
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...
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | Manage.c | 17 | ||||
-rw-r--r-- | super1.c | 6 |
3 files changed, 21 insertions, 4 deletions
@@ -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 @@ -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; @@ -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); } |