diff --git a/ChangeLog b/ChangeLog index a367f6891..0ab95813a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-17 Vladimir Serbinenko + + * include/grub/bsdlabel.h (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION): New definition. + * partmap/bsdlabel.c (bsdlabel_partition_map_iterate): Use FreeBSD + delta determination style. Works with most NetBSD partitions too. + 2010-07-17 Vladimir Serbinenko * kern/partition.c [GRUB_UTIL]: Add missing util/misc.h inclusion. diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h index d88b25353..636bd41a1 100644 --- a/include/grub/bsdlabel.h +++ b/include/grub/bsdlabel.h @@ -63,6 +63,8 @@ #define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18 #define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19 +#define GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION 2 + /* The BSD partition entry. */ struct grub_partition_bsd_entry { diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c index f671f76d8..a27b8eaec 100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@ -41,9 +41,6 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, grub_disk_addr_t delta = 0; unsigned pos; - /* BSDLabel offsets are absolute even when it's embed inside partition. */ - delta = grub_partition_get_start (disk->partition); - /* Read the BSD label. */ if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, sizeof (label), &label)) @@ -53,6 +50,24 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + /* A kludge to determine a base of be.offset. */ + if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION + < grub_cpu_to_le16 (label.num_partitions)) + { + struct grub_partition_bsd_entry whole_disk_be; + + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR + * GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry) + * GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION; + + if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE, + pos % GRUB_DISK_SECTOR_SIZE, sizeof (whole_disk_be), + &whole_disk_be)) + return grub_errno; + + delta = grub_le_to_cpu32 (whole_disk_be.offset); + } + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR * GRUB_DISK_SECTOR_SIZE; @@ -62,6 +77,9 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, { struct grub_partition_bsd_entry be; + if (p.number == GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION) + continue; + p.offset = pos / GRUB_DISK_SECTOR_SIZE; p.index = pos % GRUB_DISK_SECTOR_SIZE; @@ -78,7 +96,7 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, (unsigned long long) p.start, (unsigned long long) p.len); - if (be.fs_type == GRUB_PC_PARTITION_BSD_TYPE_UNUSED) + if (p.len == 0) continue; if (p.start < delta)