=== modified file 'disk/mdraid_linux.c' --- disk/mdraid_linux.c 2010-07-23 05:25:00 +0000 +++ disk/mdraid_linux.c 2010-07-24 05:53:53 +0000 @@ -363,6 +363,19 @@ return grub_error (GRUB_ERR_OUT_OF_RANGE, "csum invalid"); } + if (grub_le_to_cpu32 (real_sb->dev_number) < + grub_le_to_cpu32 (real_sb->max_dev)) + array->index = grub_le_to_cpu16 + (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); + else + array->index = 0xffff; /* disk will be later not used! */ + + if (array->index == 0xffff || array->index == 0xfffe) + { + grub_free (real_sb); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "spare or faulty drive"); + } + array->name = grub_strdup (real_sb->set_name); if (! array->name) { @@ -375,14 +388,11 @@ array->layout = grub_le_to_cpu32 (real_sb->layout); array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); array->disk_size = grub_le_to_cpu64 (real_sb->size); + if (!array->disk_size) + /* Level 0 doesn't seem to set sb->size */ + array->disk_size = grub_le_to_cpu64 (real_sb->data_size); array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); array->freshness = grub_le_to_cpu32(real_sb->events); - if (grub_le_to_cpu32 (real_sb->dev_number) < - grub_le_to_cpu32 (real_sb->max_dev)) - array->index = grub_le_to_cpu16 - (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); - else - array->index = 0xffff; /* disk will be later not used! */ array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) === modified file 'disk/raid.c' --- disk/raid.c 2010-07-23 05:25:00 +0000 +++ disk/raid.c 2010-07-24 09:57:05 +0000 @@ -555,25 +555,28 @@ grub_memset (&array->device, 0, sizeof (array->device)); grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); + /* mdraid 1.x superblocks don't have a number but we need a unique id + for the cache system. Start numbering down from the top. */ if (array->name) - goto skip_duplicate_check; + array->number = -1; + /* Check whether we don't have multiple arrays with the same number. */ for (p = array_list; p != NULL; p = p->next) { - if (! p->name && p->number == array->number) + if (p->number == array->number) break; } if (p) { /* The number is already in use, so we need to find a new one. */ - int i = 0; + int i = array->name ? -2 : 0; while (1) { for (p = array_list; p != NULL; p = p->next) { - if (! p->name && p->number == i) + if (p->number == i) break; } @@ -584,10 +587,10 @@ break; } - i++; + i += array->name ? -1 : 1; } } - skip_duplicate_check: + /* mdraid 1.x superblocks have only a name stored not a number. Use it directly as GRUB device. */ if (! array->name)