diff --git a/ChangeLog.raid b/ChangeLog.raid index c546a7632..a66bd6905 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,19 @@ +2010-07-18 Colin Watson + + * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Add start_sector + parameter. Set its pointer target to 0. + * disk/mdraid_linux.c (grub_mdraid_detect): Add start_sector + parameter. Set its pointer target to 0 for 0.9 metadata, or to the + `data_offset' value from the superblock for 1.x metadata. + * disk/raid.c (grub_raid_read): Offset reads by the start sector of + data on the device. + (insert_array): Record the start sector of data on the device. + (grub_raid_register): Pass start_sector parameters to + grub_raid_list->detect and insert_array. + * include/grub/raid.h (struct grub_raid_array): Add start_sector + member. + (struct grub_raid): Add start_sector parameter to `detect'. + 2010-07-18 Colin Watson * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices, diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c index 3e4ae33be..d3f45935c 100644 --- a/disk/dmraid_nvidia.c +++ b/disk/dmraid_nvidia.c @@ -89,7 +89,8 @@ struct grub_nv_super } __attribute__ ((packed)); static grub_err_t -grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) +grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector) { grub_disk_addr_t sector; struct grub_nv_super sb; @@ -145,6 +146,8 @@ grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) grub_memcpy (array->uuid, (char *) &sb.array.signature, sizeof (sb.array.signature)); + *start_sector = 0; + return 0; } diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 08e10ab45..b97e458ce 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -229,7 +229,8 @@ struct grub_raid_super_1x #define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ static grub_err_t -grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) +grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector) { grub_disk_addr_t sector; grub_uint64_t size, sb_size; @@ -328,6 +329,8 @@ superblock_0_90: uuid[2] = sb.set_uuid2; uuid[3] = sb.set_uuid3; + *start_sector = 0; + return 0; superblock_1_x: @@ -387,6 +390,8 @@ superblock_0_90: grub_memcpy (array->uuid, sb_1x->set_uuid, 16); + *start_sector = sb_1x->data_offset; + grub_free (sb_1x); return 0; } diff --git a/disk/raid.c b/disk/raid.c index 1dc361e8e..30d4b7ac4 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -254,7 +254,8 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, grub_errno = GRUB_ERR_NONE; err = grub_disk_read (array->device[k], - read_sector + j * far_ofs + b, + array->start_sector[k] + + read_sector + j * far_ofs + b, 0, read_size << GRUB_DISK_SECTOR_BITS, buf); @@ -366,7 +367,8 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, grub_errno = GRUB_ERR_NONE; err = grub_disk_read (array->device[disknr], - read_sector + b, 0, + array->start_sector[disknr] + + read_sector + b, 0, read_size << GRUB_DISK_SECTOR_BITS, buf); @@ -475,7 +477,7 @@ grub_raid_write (grub_disk_t disk __attribute ((unused)), static grub_err_t insert_array (grub_disk_t disk, struct grub_raid_array *new_array, - const char *scanner_name) + grub_disk_addr_t start_sector, const char *scanner_name) { struct grub_raid_array *array = 0, *p; @@ -524,6 +526,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, *array = *new_array; array->nr_devs = 0; grub_memset (&array->device, 0, sizeof (array->device)); + grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); if (array->name) goto skip_duplicate_check; @@ -587,6 +590,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* Add the device to the array. */ array->device[new_array->index] = disk; + array->start_sector[new_array->index] = start_sector; array->nr_devs++; return 0; @@ -628,6 +632,7 @@ grub_raid_register (grub_raid_t raid) { grub_disk_t disk; struct grub_raid_array array; + grub_disk_addr_t start_sector; grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name); @@ -636,8 +641,8 @@ grub_raid_register (grub_raid_t raid) return 0; if ((disk->total_sectors != GRUB_ULONG_MAX) && - (! grub_raid_list->detect (disk, &array)) && - (! insert_array (disk, &array, grub_raid_list->name))) + (! grub_raid_list->detect (disk, &array, &start_sector)) && + (! insert_array (disk, &array, start_sector, grub_raid_list->name))) return 0; /* This error usually means it's not raid, no need to display diff --git a/include/grub/raid.h b/include/grub/raid.h index 8fa4c3814..00df9c10c 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -51,6 +51,8 @@ struct grub_raid_array char *name; /* That will be "md". */ unsigned int nr_devs; /* The number of devices we've found so far. */ grub_disk_t device[GRUB_RAID_MAX_DEVICES]; /* Array of total_devs devices. */ + grub_disk_addr_t start_sector[GRUB_RAID_MAX_DEVICES]; + /* Start of each device, in 512 byte sectors. */ struct grub_raid_array *next; }; @@ -58,7 +60,8 @@ struct grub_raid { const char *name; - grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array); + grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector); struct grub_raid *next; };