if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
return grub_errno;
- /* Look whether there is a RAID superblock. */
- if (sb.md_magic != SB_MAGIC)
+ /* Look whether there is a mdraid 0.90 superblock. */
+ if (sb.md_magic == SB_MAGIC)
+ goto superblock_0_90;
+
+ /* Check for an 1.x superblock.
+ * It's always aligned to a 4K boundary
+ * and depending on the minor version it can be:
+ * 0: At least 8K, but less than 12K, from end of device
+ * 1: At start of device
+ * 2: 4K from start of device.
+ */
+
+ sb_1x = grub_malloc (sizeof (struct grub_raid_super_1x));
+ if (!sb_1x)
+ return grub_errno;
+
+ for (minor_version = 0; minor_version < 3; ++minor_version)
+ {
+ switch (minor_version)
+ {
+ case 0:
+ sector = (size - 8 * 2) & ~(4 * 2 - 1);
+ break;
+ case 1:
+ sector = 0;
+ break;
+ case 2:
+ sector = 4 * 2;
+ break;
+ }
+
+ if (grub_disk_read
+ (disk, sector, 0, sizeof (struct grub_raid_super_1x), sb_1x))
+ {
+ grub_free (sb_1x);
+ return grub_errno;
+ }
+
+ if (sb_1x->magic == SB_MAGIC)
+ goto superblock_1_x;
+ }
+
+ /* Neither 0.90 nor 1.x. */
+ if (grub_le_to_cpu32 (sb_1x->magic) != SB_MAGIC)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
- /* FIXME: Also support version 1.0. */
+superblock_0_90:
+
if (sb.major_version != 0 || sb.minor_version != 90)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
- "Unsupported RAID version: %d.%d",
+ "unsupported RAID version: %d.%d",
sb.major_version, sb.minor_version);
- /* FIXME: Check the checksum. */
+ /* FIXME: Check the checksum. */
/* Multipath. */
if ((int) sb.level == -4)
if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
sb.level != 5 && sb.level != 6 && sb.level != 10)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
- "Unsupported RAID level: %d", sb.level);
+ "unsupported RAID level: %d", sb.level);
+ array->name = NULL;
array->number = sb.md_minor;
array->level = sb.level;
array->layout = sb.layout;