Index: include/parted/device.h =================================================================== RCS file: /cvsroot/parted/stable/include/parted/device.h,v retrieving revision 1.1 diff -u -r1.1 device.h --- include/parted/device.h 13 Jun 2004 06:35:11 -0000 1.1 +++ include/parted/device.h 8 Aug 2004 08:35:19 -0000 @@ -38,6 +38,13 @@ typedef struct _PedDevice PedDevice; typedef struct _PedDeviceArchOps PedDeviceArchOps; +typedef struct _PedCHSGeometry PedCHSGeometry; + +struct _PedCHSGeometry { + int cylinders; + int heads; + int sectors; +}; /* A hard disk device - eg. /dev/hda, not /dev/hda3 */ struct _PedDevice { @@ -56,9 +63,8 @@ int dirty; int boot_dirty; - int heads, sectors, cylinders; - int geom_known; - int geom_already_guessed; + PedCHSGeometry phys_geom; + PedCHSGeometry bios_geom; short host, did; void* arch_specific; Index: libparted/disk_bsd.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/disk_bsd.c,v retrieving revision 1.1 diff -u -r1.1 disk_bsd.c --- libparted/disk_bsd.c 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/disk_bsd.c 8 Aug 2004 08:35:19 -0000 @@ -188,12 +188,15 @@ label->d_type = PED_CPU_TO_LE16 (BSD_DTYPE_SCSI); label->d_flags = 0; label->d_secsize = PED_CPU_TO_LE16 (PED_SECTOR_SIZE); - label->d_nsectors = PED_CPU_TO_LE32 (dev->sectors); - label->d_ntracks = PED_CPU_TO_LE32 (dev->heads); - label->d_ncylinders = PED_CPU_TO_LE32 (dev->cylinders); - label->d_secpercyl = PED_CPU_TO_LE32 (dev->sectors * dev->heads); + label->d_nsectors = PED_CPU_TO_LE32 (dev->bios_geom.sectors); + label->d_ntracks = PED_CPU_TO_LE32 (dev->bios_geom.heads); + label->d_ncylinders = PED_CPU_TO_LE32 (dev->bios_geom.cylinders); + label->d_secpercyl = PED_CPU_TO_LE32 (dev->bios_geom.sectors + * dev->bios_geom.heads); label->d_secperunit - = PED_CPU_TO_LE32 (dev->sectors * dev->heads * dev->cylinders); + = PED_CPU_TO_LE32 (dev->bios_geom.sectors + * dev->bios_geom.heads + * dev->bios_geom.cylinders); label->d_rpm = PED_CPU_TO_LE16 (3600); label->d_interleave = PED_CPU_TO_LE16 (1);; Index: libparted/disk_dos.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/disk_dos.c,v retrieving revision 1.2 diff -u -r1.2 disk_dos.c --- libparted/disk_dos.c 26 Jun 2004 02:32:59 -0000 1.2 +++ libparted/disk_dos.c 8 Aug 2004 08:35:20 -0000 @@ -112,6 +112,16 @@ uint16_t magic; } __attribute__((packed)); +/* OrigState is information we want to preserve about the partition for + * dealing with CHS issues + */ +typedef struct { + PedGeometry geom; + DosRawPartition raw_part; + PedSector lba_offset; /* needed for computing start/end for + * logical partitions */ +} OrigState; + typedef struct { unsigned char system; int boot; @@ -120,14 +130,11 @@ int lvm; int lba; int palo; + OrigState* orig; /* used for CHS stuff */ } DosPartitionData; static PedDiskType msdos_disk_type; -static PedSector chs_to_sector (const PedDevice* dev, const RawCHS* chs); -static int chs_to_cylinder (const RawCHS* chs); -static int raw_part_is_lba (const DosRawPartition* raw_part); - static int msdos_probe (PedDevice *dev) { @@ -212,49 +219,67 @@ } #endif /* !DISCOVER_ONLY */ +static int +chs_get_cylinder (const RawCHS* chs) +{ + return chs->cylinder + ((chs->sector >> 6) << 8); +} + +static int +chs_get_head (const RawCHS* chs) +{ + return chs->head; +} + +static int +chs_get_sector (const RawCHS* chs) +{ + return chs->sector % 0x40 - 1; +} + static PedSector -chs_to_sector (const PedDevice* dev, const RawCHS* chs) +chs_to_sector (PedDevice* dev, const PedCHSGeometry *bios_geom, + const RawCHS* chs) { - PedSector real_c; /* not measured in sectors, but need */ - PedSector real_h; /* lots of bits */ - PedSector real_s; + PedSector c; /* not measured in sectors, but need */ + PedSector h; /* lots of bits */ + PedSector s; - PED_ASSERT (dev != NULL, return 0); + PED_ASSERT (bios_geom != NULL, return 0); + PED_ASSERT (chs != NULL, return 0); - real_s = chs->sector % 0x40 - 1; - real_h = chs->head; - real_c = chs->cylinder + ((chs->sector >> 6) << 8); + c = chs_get_cylinder (chs); + h = chs_get_head (chs); + s = chs_get_sector (chs); - if (real_c >= 1022) /* MAGIC: C/H/S is irrelevant */ + if (c >= 1022) /* MAGIC: C/H/S is irrelevant */ return 0; - return ((real_c * dev->heads + real_h) * dev->sectors + real_s) + return ((c * bios_geom->heads + h) * bios_geom->sectors + s) * (dev->sector_size / 512); } -static int -chs_to_cylinder (const RawCHS* chs) -{ - return chs->cylinder + ((chs->sector >> 6) << 8); -} - static void -sector_to_chs (const PedDevice* dev, PedSector sector, RawCHS* chs) +sector_to_chs (PedDevice* dev, const PedCHSGeometry* bios_geom, + PedSector sector, RawCHS* chs) { PedSector real_c, real_h, real_s; PED_ASSERT (dev != NULL, return); PED_ASSERT (chs != NULL, return); + + if (!bios_geom) + bios_geom = &dev->bios_geom; sector /= (dev->sector_size / 512); - real_c = sector / (dev->heads * dev->sectors); - real_h = (sector / dev->sectors) % dev->heads; - real_s = sector % dev->sectors; + real_c = sector / (bios_geom->heads * bios_geom->sectors); + real_h = (sector / bios_geom->sectors) % bios_geom->heads; + real_s = sector % bios_geom->sectors; if (real_c > 1023) { real_c = 1023; - real_h = dev->heads - 1; - real_s = dev->sectors - 1; + real_h = bios_geom->heads - 1; + real_s = bios_geom->sectors - 1; } chs->cylinder = real_c % 0x100; @@ -263,21 +288,23 @@ } static PedSector -legacy_start (PedDisk* disk, const DosRawPartition* raw_part) +legacy_start (PedDisk* disk, const PedCHSGeometry* bios_geom, + const DosRawPartition* raw_part) { PED_ASSERT (disk != NULL, return 0); PED_ASSERT (raw_part != NULL, return 0); - return chs_to_sector (disk->dev, &raw_part->chs_start); + return chs_to_sector (disk->dev, bios_geom, &raw_part->chs_start); } static PedSector -legacy_end (PedDisk* disk, const DosRawPartition* raw_part) +legacy_end (PedDisk* disk, const PedCHSGeometry* bios_geom, + const DosRawPartition* raw_part) { PED_ASSERT (disk != NULL, return 0); PED_ASSERT (raw_part != NULL, return 0); - return chs_to_sector (disk->dev, &raw_part->chs_end); + return chs_to_sector (disk->dev, bios_geom, &raw_part->chs_end); } static PedSector @@ -306,45 +333,50 @@ #ifndef DISCOVER_ONLY static int -part_check_chs (PedDisk* disk, const PedPartition* part, - const DosRawPartition* raw_part) +partition_check_bios_geometry (PedPartition* part, PedCHSGeometry* bios_geom) { - PedSector leg_start, leg_end; + PedSector leg_start, leg_end; + DosPartitionData* dos_data; + PedDisk* disk; - PED_ASSERT (disk != NULL, return 0); PED_ASSERT (part != NULL, return 0); - PED_ASSERT (raw_part != NULL, return 0); + PED_ASSERT (part->disk != NULL, return 0); + PED_ASSERT (part->disk_specific != NULL, return 0); + dos_data = part->disk_specific; - leg_start = legacy_start (disk, raw_part); - leg_end = legacy_end (disk, raw_part); + if (!dos_data->orig) + return 1; + + disk = part->disk; + leg_start = legacy_start (disk, bios_geom, &dos_data->orig->raw_part); + leg_end = legacy_end (disk, bios_geom, &dos_data->orig->raw_part); - if (leg_start && leg_start != part->geom.start) + if (leg_start && leg_start != dos_data->orig->geom.start) return 0; - if (leg_end && leg_end != part->geom.end) + if (leg_end && leg_end != dos_data->orig->geom.end) return 0; return 1; } static int -check_chs (PedDisk* disk, PedPartition* parts[], const DosRawTable* raw_table) +disk_check_bios_geometry (PedDisk* disk, PedCHSGeometry* bios_geom) { - int i; + PedPartition* part = NULL; PED_ASSERT (disk != NULL, return 0); - PED_ASSERT (parts != NULL, return 0); - PED_ASSERT (raw_table != NULL, return 0); - for (i = 0; i < 4; i++) { - if (!parts[i]) - continue; - if (!part_check_chs (disk, parts[i], &raw_table->partitions[i])) - return 0; + while ((part = ped_disk_next_partition (disk, part))) { + if (ped_partition_is_active (part)) { + if (!partition_check_bios_geometry (part, bios_geom)) + return 0; + } } + return 1; } static int -probe_filesystem_for_geom (PedDisk* disk, const PedPartition* part) +probe_filesystem_for_geom (const PedPartition* part, PedCHSGeometry* bios_geom) { const char* ms_types[] = {"ntfs", "fat16", "fat32", NULL}; int i; @@ -353,8 +385,9 @@ int sectors; int heads; - PED_ASSERT (disk != NULL, return 0); PED_ASSERT (part != NULL, return 0); + PED_ASSERT (part->disk != NULL, return 0); + PED_ASSERT (bios_geom != NULL, return 0); if (!part->fs_type) return 0; @@ -379,144 +412,127 @@ if (heads > 255 || heads < 1) return 0; - disk->dev->sectors = sectors; - disk->dev->heads = heads; - disk->dev->cylinders = disk->dev->length / (sectors * heads); + bios_geom->sectors = sectors; + bios_geom->heads = heads; + bios_geom->cylinders = part->disk->dev->length / (sectors * heads); return 1; } static int -probe_filesystems_for_geom (PedDisk* disk, PedPartition* parts[]) +probe_partition_for_geom (PedPartition* part, PedCHSGeometry* bios_geom) { - int i; + DosPartitionData* dos_data; + RawCHS* start_chs; + RawCHS* end_chs; + PedSector c, h, s, a, a_; /* start */ + PedSector C, H, S, A, A_; /* end */ + PedSector cylinders, heads, sectors; - PED_ASSERT (disk != NULL, return 0); + PED_ASSERT (part != NULL, return 0); + PED_ASSERT (part->disk_specific != NULL, return 0); + PED_ASSERT (bios_geom != NULL, return 0); - for (i = 0; i < 4; i++) { - if (parts[i] && probe_filesystem_for_geom (disk, parts[i])) - return 1; - } - return 0; -} + dos_data = part->disk_specific; -static int -probe_table_for_geom (PedDisk* disk, PedPartition* parts[], - const DosRawTable* raw_table) -{ - int sector_list[] = {63, 61, 48, 32, 16, 0}; - int head_list[] = {255, 192, 128, 96, 64, 61, 32, 17, 16, 0}; - int s_index; - int h_index; - int old_c, old_h, old_s; + if (!dos_data->orig) + return 0; - PED_ASSERT (disk != NULL, return 0); - PED_ASSERT (parts != NULL, return 0); - PED_ASSERT (raw_table != NULL, return 0); + start_chs = &dos_data->orig->raw_part.chs_start; + c = chs_get_cylinder (start_chs); + h = chs_get_head (start_chs); + s = chs_get_sector (start_chs); + a = dos_data->orig->geom.start; + a_ = a - s; - old_c = disk->dev->cylinders; - old_h = disk->dev->heads; - old_s = disk->dev->sectors; - - for (s_index=0; sector_list [s_index]; s_index++) { - disk->dev->sectors = sector_list [s_index]; - for (h_index=0; head_list [h_index]; h_index++) { - disk->dev->heads = head_list [h_index]; - disk->dev->cylinders - = disk->dev->length / - (disk->dev->sectors * disk->dev->heads); - if (check_chs(disk, parts, raw_table)) - return 1; - } - } + end_chs = &dos_data->orig->raw_part.chs_end; + C = chs_get_cylinder (end_chs); + H = chs_get_head (end_chs); + S = chs_get_sector (end_chs); + A = dos_data->orig->geom.end; + A_ = A - S; - disk->dev->cylinders = old_c; - disk->dev->heads = old_h; - disk->dev->sectors = old_s; - return 0; + if (h < 0 || H < 0 || h > 254 || H > 254) + return 0; + + /* Not enough information. In theory, we can do better. Should we? */ + if (C > 1022 || a_ * C - A_ * c == 0 || A_ * h - a_ * H == 0) + return 0; + + heads = (A_ * h - a_ * H) / (a_ * C - A_ * c); + PED_ASSERT (heads > 0, return 0); + PED_ASSERT (heads < 256, return 0); + + sectors = A_ / (C * heads + H); + PED_ASSERT (sectors > 0, return 0); + PED_ASSERT (sectors <= 63, return 0); + + cylinders = part->disk->dev->length / (heads * sectors); + + bios_geom->cylinders = cylinders; + bios_geom->heads = heads; + bios_geom->sectors = sectors; + + return 1; } -static int -process_bad_chs (PedDisk* disk, PedPartition* parts[], - const DosRawTable* raw_table) +static void +partition_probe_bios_geometry (PedPartition* part, PedCHSGeometry* bios_geom) { - int old_c, old_h, old_s; - - PED_ASSERT (disk != NULL, return 0); - PED_ASSERT (parts != NULL, return 0); - PED_ASSERT (raw_table != NULL, return 0); + PED_ASSERT (part != NULL, return); + PED_ASSERT (part->disk != NULL, return); + PED_ASSERT (bios_geom != NULL, return); - if (disk->dev->geom_already_guessed) { - disk->dev->geom_known = 0; - disk->dev->geom_already_guessed = 0; - return 1; + if (ped_partition_is_active) { + if (probe_partition_for_geom (part, bios_geom)) + return; + if (part->type & PED_PARTITION_EXTENDED) { + if (probe_filesystem_for_geom (part, bios_geom)) + return; + } } - disk->dev->geom_already_guessed = 1; - - old_c = disk->dev->cylinders; - old_h = disk->dev->heads; - old_s = disk->dev->sectors; + if (part->type & PED_PARTITION_LOGICAL) { + PedPartition* ext_part; + ext_part = ped_disk_extended_partition (part->disk); + PED_ASSERT (ext_part != NULL, return); + partition_probe_bios_geometry (ext_part, bios_geom); + } else { + *bios_geom = part->disk->dev->bios_geom; + } +} - if (probe_filesystems_for_geom (disk, parts)) - return 1; +static void +disk_probe_bios_geometry (PedDisk* disk, PedCHSGeometry* bios_geom) +{ + PedPartition* part; - if (probe_table_for_geom (disk, parts, raw_table)) { - if (ped_exception_throw ( - PED_EXCEPTION_ERROR, - PED_EXCEPTION_IGNORE_CANCEL, - _("The partition table on %s is inconsistent. " - "There are many reasons why this might be the case. " - "However, the most likely reason is that Linux " - "detected the BIOS geometry for %s incorrectly. " - "GNU Parted suspects the real geometry should be " - "%d/%d/%d (not %d/%d/%d). You should check with your " - "BIOS first, as this may not be correct. You can " - "inform Linux by adding the parameter %s=%d,%d,%d " - "to the command line. See the LILO or GRUB " - "documentation for more information. If you think " - "Parted's suggested geometry is correct, you may " - "select Ignore to continue (and fix Linux later). " - "Otherwise, select Cancel (and fix Linux and/or the " - "BIOS now)."), - disk->dev->path, - disk->dev->path, - (int) disk->dev->cylinders, - (int) disk->dev->heads, - (int) disk->dev->sectors, - old_c, - old_h, - old_s, - disk->dev->path + strlen ("/dev/"), - (int) disk->dev->cylinders, - (int) disk->dev->heads, - (int) disk->dev->sectors) - == PED_EXCEPTION_CANCEL) { - disk->dev->cylinders = old_c; - disk->dev->heads = old_h; - disk->dev->sectors = old_s; - return 0; + /* first look at the boot partition */ + part = NULL; + while ((part = ped_disk_next_partition (disk, part))) { + if (ped_partition_get_flag (part, PED_PARTITION_BOOT)) { + if (probe_filesystem_for_geom (part, bios_geom)) + return; + if (probe_partition_for_geom (part, bios_geom)) + return; } + } - return 1; - } else { - if (ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_IGNORE_CANCEL, - _("The partition table on %s is inconsistent. " - "There are many reasons why this might be the case. " - "Often, the reason is that Linux detected the BIOS " - "geometry incorrectly. However, this does not " - "appear to be the case here. It is safe to ignore," - "but ignoring may cause (fixable) problems with " - "some boot loaders, and may cause problems with " - "FAT file systems. Using LBA is recommended."), - disk->dev->path) - == PED_EXCEPTION_CANCEL) - return 0; + /* that didn't work... try all partition table entries */ + part = NULL; + while ((part = ped_disk_next_partition (disk, part))) { + if (ped_partition_is_active (part)) { + if (probe_partition_for_geom (part, bios_geom)) + return; + } + } - disk->dev->geom_known = 0; - return 1; + /* that didn't work... look at all file systems */ + part = NULL; + while ((part = ped_disk_next_partition (disk, part))) { + if (ped_partition_is_active (part)) { + if (probe_filesystem_for_geom (part, bios_geom)) + return; + } } - return 0; /* should never get here - shut gcc up! */ } #endif /* !DISCOVER_ONLY */ @@ -581,8 +597,8 @@ } PedPartition* -raw_part_parse(PedDisk* disk, const DosRawPartition* raw_part, - PedSector lba_offset, PedPartitionType type) +raw_part_parse (PedDisk* disk, const DosRawPartition* raw_part, + PedSector lba_offset, PedPartitionType type) { PedPartition* part; DosPartitionData* dos_data; @@ -605,6 +621,14 @@ || raw_part->type == PARTITION_LINUX_LVM; dos_data->lba = raw_part_is_lba (raw_part); dos_data->palo = raw_part->type == PARTITION_PALO; + dos_data->orig = ped_malloc (sizeof (OrigState)); + if (!dos_data->orig) { + ped_partition_destroy (part); + return NULL; + } + dos_data->orig->geom = part->geom; + dos_data->orig->raw_part = *raw_part; + dos_data->orig->lba_offset = lba_offset; return part; } @@ -614,7 +638,6 @@ int i; DosRawTable table; DosRawPartition* raw_part; - PedPartition* parsed_parts[4]; PedPartition* part; PedPartitionType type; PedSector lba_offset; @@ -645,7 +668,6 @@ /* parse the partitions from this table */ for (i = 0; i < 4; i++) { - parsed_parts[i] = NULL; raw_part = &table.partitions [i]; if (raw_part->type == PARTITION_EMPTY || !raw_part->length) continue; @@ -685,30 +707,12 @@ if (type != PED_PARTITION_EXTENDED) part->fs_type = ped_file_system_probe (&part->geom); - parsed_parts[i] = part; - } - -#ifndef DISCOVER_ONLY - /* try to figure out the correct BIOS CHS values */ - if (!is_extended_table) { - if (!check_chs (disk, parsed_parts, &table)) { - if (!process_bad_chs (disk, parsed_parts, &table)) - goto error; - } - } -#endif - - /* add the partitions */ - for (i = 0; i < 4; i++) { - part = parsed_parts[i]; - if (!part) - continue; - constraint_exact = ped_constraint_exact (&part->geom); if (!ped_disk_add_partition (disk, part, constraint_exact)) goto error; ped_constraint_destroy (constraint_exact); + /* non-nested extended partition */ if (part->type == PED_PARTITION_EXTENDED) { if (!read_table (disk, part->geom.start, 1)) goto error; @@ -746,7 +750,16 @@ PED_ASSERT (disk->dev != NULL, return 0); ped_disk_delete_all (disk); - return read_table (disk, 0, 0); + if (!read_table (disk, 0, 0)) + return 0; + +#ifndef DISCOVER_ONLY + /* try to figure out the correct BIOS CHS values */ + if (!disk_check_bios_geometry (disk, &disk->dev->bios_geom)) + disk_probe_bios_geometry (disk, &disk->dev->bios_geom); +#endif + + return 1; } #ifndef DISCOVER_ONLY @@ -754,9 +767,13 @@ fill_raw_part (DosRawPartition* raw_part, PedPartition* part, PedSector offset) { DosPartitionData* dos_data; + PedCHSGeometry bios_geom; + PED_ASSERT (raw_part != NULL, return 0); PED_ASSERT (part != NULL, return 0); + partition_probe_bios_geometry (part, &bios_geom); + dos_data = part->disk_specific; raw_part->boot_ind = 0x80 * dos_data->boot; @@ -766,15 +783,25 @@ raw_part->length = PED_CPU_TO_LE32 (part->geom.length / (part->disk->dev->sector_size / 512)); - sector_to_chs (part->disk->dev, part->geom.start, &raw_part->chs_start); - sector_to_chs (part->disk->dev, part->geom.end, &raw_part->chs_end); + sector_to_chs (part->disk->dev, &bios_geom, part->geom.start, + &raw_part->chs_start); + sector_to_chs (part->disk->dev, &bios_geom, part->geom.end, + &raw_part->chs_end); + + if (dos_data->orig) { + DosRawPartition* orig_raw_part = &dos_data->orig->raw_part; + if (dos_data->orig->geom.start == part->geom.start) + raw_part->chs_start = orig_raw_part->chs_start; + if (dos_data->orig->geom.end == part->geom.end) + raw_part->chs_end = orig_raw_part->chs_end; + } return 1; } static int -fill_ext_raw_part_geom (DosRawPartition* raw_part, PedGeometry* geom, - PedSector offset) +fill_ext_raw_part_geom (DosRawPartition* raw_part, PedCHSGeometry* bios_geom, + PedGeometry* geom, PedSector offset) { PED_ASSERT (raw_part != NULL, return 0); PED_ASSERT (geom != NULL, return 0); @@ -787,8 +814,8 @@ raw_part->length = PED_CPU_TO_LE32 (geom->length / (geom->dev->sector_size / 512)); - sector_to_chs (geom->dev, geom->start, &raw_part->chs_start); - sector_to_chs (geom->dev, geom->start + geom->length - 1, + sector_to_chs (geom->dev, bios_geom, geom->start, &raw_part->chs_start); + sector_to_chs (geom->dev, bios_geom, geom->start + geom->length - 1, &raw_part->chs_end); return 1; @@ -798,7 +825,6 @@ write_ext_table (PedDisk* disk, PedSector sector, PedPartition* logical) { DosRawTable table; - PedGeometry* geom; PedPartition* part; PedSector lba_offset; @@ -816,11 +842,16 @@ part = ped_disk_get_partition (disk, logical->num + 1); if (part) { + PedGeometry* geom; + PedCHSGeometry bios_geom; + geom = ped_geometry_new (disk->dev, part->prev->geom.start, part->geom.end - part->prev->geom.start + 1); if (!geom) return 0; - fill_ext_raw_part_geom (&table.partitions[1], geom, lba_offset); + partition_probe_bios_geometry (part, &bios_geom); + fill_ext_raw_part_geom (&table.partitions[1], &bios_geom, + geom, lba_offset); ped_geometry_destroy (geom); if (!write_ext_table (disk, part->prev->geom.start, part)) @@ -850,10 +881,12 @@ { PedPartition* ext_part; PedPartition* part; + PedCHSGeometry bios_geom; PED_ASSERT (disk != NULL, return 0); ext_part = ped_disk_extended_partition (disk); + partition_probe_bios_geometry (ext_part, &bios_geom); part = ped_disk_get_partition (disk, 5); if (part) return write_ext_table (disk, ext_part->geom.start, part); @@ -875,8 +908,7 @@ if (!table.boot_code[0]) { memset (table.boot_code, 0, 512); - memcpy (table.boot_code, MBR_BOOT_CODE, - sizeof (MBR_BOOT_CODE)); + memcpy (table.boot_code, MBR_BOOT_CODE, sizeof (MBR_BOOT_CODE)); } memset (table.partitions, 0, sizeof (DosRawPartition) * 4); @@ -919,6 +951,7 @@ = dos_data = ped_malloc (sizeof (DosPartitionData)); if (!dos_data) goto error_free_part; + dos_data->orig = NULL; dos_data->system = PARTITION_LINUX; dos_data->hidden = 0; dos_data->boot = 0; @@ -979,15 +1012,9 @@ const PedFileSystemType* fs_type) { DosPartitionData* dos_data = part->disk_specific; - PedSector cyl_size = part->disk->dev->sectors * part->disk->dev->heads; part->fs_type = fs_type; - if (part->geom.end >= cyl_size * 1024 - && (part->type & PED_PARTITION_EXTENDED - || (fs_type && !strncmp (fs_type->name, "fat", 3)))) - dos_data->lba = 1; - if (dos_data->hidden && fs_type && strncmp (fs_type->name, "fat", 3) != 0 @@ -1185,10 +1212,11 @@ } static PedGeometry* -_best_solution (const PedPartition* part, PedGeometry* a, PedGeometry* b) +_best_solution (const PedPartition* part, const PedCHSGeometry* bios_geom, + PedGeometry* a, PedGeometry* b) { PedDevice* dev = part->disk->dev; - PedSector cyl_size = dev->heads * dev->sectors; + PedSector cyl_size = bios_geom->heads * bios_geom->sectors; int a_cylinder; int b_cylinder; @@ -1201,8 +1229,8 @@ b_cylinder = b->start / cyl_size; if (a_cylinder == b_cylinder) { - if ( (a->start / dev->sectors) % dev->heads - < (b->start / dev->sectors) % dev->heads) + if ( (a->start / bios_geom->sectors) % bios_geom->heads + < (b->start / bios_geom->sectors) % bios_geom->heads) goto choose_a; else goto choose_b; @@ -1237,10 +1265,11 @@ * rules for that - see the _primary_start_constraint. */ static PedConstraint* -_primary_constraint (PedDisk* disk, PedGeometry* min_geom) +_primary_constraint (PedDisk* disk, const PedCHSGeometry* bios_geom, + PedGeometry* min_geom) { PedDevice* dev = disk->dev; - PedSector cylinder_size = dev->sectors * dev->heads; + PedSector cylinder_size = bios_geom->sectors * bios_geom->heads; PedAlignment start_align; PedAlignment end_align; PedGeometry start_geom; @@ -1276,28 +1305,30 @@ * must start on the 2nd head of the 1st cylinder. */ static PedConstraint* -_primary_start_constraint (PedDisk* disk, PedGeometry* min_geom) +_primary_start_constraint (PedDisk* disk, const PedCHSGeometry* bios_geom, + PedGeometry* min_geom) { PedDevice* dev = disk->dev; - PedSector cylinder_size = dev->sectors * dev->heads; + PedSector cylinder_size = bios_geom->sectors * bios_geom->heads; PedAlignment start_align; PedAlignment end_align; PedGeometry start_geom; PedGeometry end_geom; - if (!ped_alignment_init (&start_align, dev->sectors, 0)) + if (!ped_alignment_init (&start_align, bios_geom->sectors, 0)) return NULL; if (!ped_alignment_init (&end_align, -1, cylinder_size)) return NULL; if (min_geom) { - if (!ped_geometry_init (&start_geom, dev, dev->sectors, 1)) + if (!ped_geometry_init (&start_geom, dev, + bios_geom->sectors, 1)) return NULL; if (!ped_geometry_init (&end_geom, dev, min_geom->end, dev->length - min_geom->end)) return NULL; } else { - if (!ped_geometry_init (&start_geom, dev, dev->sectors, - dev->length - dev->sectors)) + if (!ped_geometry_init (&start_geom, dev, bios_geom->sectors, + dev->length - bios_geom->sectors)) return NULL; if (!ped_geometry_init (&end_geom, dev, 0, dev->length)) return NULL; @@ -1309,18 +1340,19 @@ /* constraints for logical partitions: * - start_offset is the offset in the start alignment. "normally", - * this is dev->sectors. exceptions: MINOR > 5 at the beginning of the + * this is bios_geom->sectors. exceptions: MINOR > 5 at the beginning of the * extended partition, or MINOR == 5 in the middle of the extended partition * - is_start_part == 1 if the constraint is for the first cylinder of * the extended partition, or == 0 if the constraint is for the second cylinder * onwards of the extended partition. */ static PedConstraint* -_logical_constraint (PedDisk* disk, PedSector start_offset, int is_start_part) +_logical_constraint (PedDisk* disk, const PedCHSGeometry* bios_geom, + PedSector start_offset, int is_start_part) { PedPartition* ext_part = ped_disk_extended_partition (disk); PedDevice* dev = disk->dev; - PedSector cylinder_size = dev->sectors * dev->heads; + PedSector cylinder_size = bios_geom->sectors * bios_geom->heads; PedAlignment start_align; PedAlignment end_align; PedGeometry max_geom; @@ -1361,16 +1393,14 @@ * * the extended partition table */ static PedGeometry* -_get_min_extended_part_geom (const PedPartition* ext_part) +_get_min_extended_part_geom (const PedPartition* ext_part, + const PedCHSGeometry* bios_geom) { PedDisk* disk = ext_part->disk; - PedSector head_size = disk->dev->sectors; + PedSector head_size = bios_geom ? bios_geom->sectors : 1; PedPartition* walk; PedGeometry* min_geom; - if (!disk->dev->geom_known) - head_size = 1; /* hack! */ - walk = ped_disk_get_partition (disk, 5); if (!walk) return NULL; @@ -1392,7 +1422,8 @@ } static int -_align_primary (PedPartition* part, const PedConstraint* constraint) +_align_primary (PedPartition* part, const PedCHSGeometry* bios_geom, + const PedConstraint* constraint) { PedDisk* disk = part->disk; PedDevice* dev = disk->dev; @@ -1400,15 +1431,16 @@ PedGeometry* solution = NULL; if (part->type == PED_PARTITION_EXTENDED) - min_geom = _get_min_extended_part_geom (part); + min_geom = _get_min_extended_part_geom (part, bios_geom); - solution = _best_solution (part, solution, + solution = _best_solution (part, bios_geom, solution, _try_constraint (part, constraint, _primary_start_constraint (disk, - min_geom))); - solution = _best_solution (part, solution, + bios_geom, min_geom))); + solution = _best_solution (part, bios_geom, solution, _try_constraint (part, constraint, - _primary_constraint (disk, min_geom))); + _primary_constraint (disk, bios_geom, + min_geom))); if (min_geom) ped_geometry_destroy (min_geom); @@ -1424,16 +1456,16 @@ } static int -_logical_min_start_head (PedPartition* part, PedPartition* ext_part, - int is_start_ext_part) +_logical_min_start_head (PedPartition* part, const PedCHSGeometry* bios_geom, + PedPartition* ext_part, int is_start_ext_part) { PedDevice* dev = part->disk->dev; - PedSector cylinder_size = dev->sectors * dev->heads; + PedSector cylinder_size = bios_geom->sectors * bios_geom->heads; PedSector base_head; if (is_start_ext_part) base_head = 1 + (ext_part->geom.start % cylinder_size) - / dev->sectors; + / bios_geom->sectors; else base_head = 0; @@ -1444,12 +1476,13 @@ } static int -_align_logical (PedPartition* part, const PedConstraint* constraint) +_align_logical (PedPartition* part, const PedCHSGeometry* bios_geom, + const PedConstraint* constraint) { PedDisk* disk = part->disk; PedDevice* dev = disk->dev; PedPartition* ext_part = ped_disk_extended_partition (disk); - PedSector cyl_size = dev->sectors * dev->heads; + PedSector cyl_size = bios_geom->sectors * bios_geom->heads; PedSector start_base; int head; PedGeometry* solution = NULL; @@ -1458,19 +1491,20 @@ start_base = ped_round_down_to (part->geom.start, cyl_size); - for (head = _logical_min_start_head (part, ext_part, 0); - head < PED_MIN (5, dev->heads); head++) { + for (head = _logical_min_start_head (part, bios_geom, ext_part, 0); + head < PED_MIN (5, bios_geom->heads); head++) { PedConstraint* disk_constraint; - PedSector start = start_base + head * dev->sectors; + PedSector start = start_base + head * bios_geom->sectors; - if (head >= _logical_min_start_head (part, ext_part, 1)) + if (head >= _logical_min_start_head (part, bios_geom, + ext_part, 1)) disk_constraint = - _logical_constraint (disk, start, 1); + _logical_constraint (disk, bios_geom, start, 1); else disk_constraint = - _logical_constraint (disk, start, 0); + _logical_constraint (disk, bios_geom, start, 0); - solution = _best_solution (part, solution, + solution = _best_solution (part, bios_geom, solution, _try_constraint (part, constraint, disk_constraint)); } @@ -1486,12 +1520,13 @@ } static int -_align (PedPartition* part, const PedConstraint* constraint) +_align (PedPartition* part, const PedCHSGeometry* bios_geom, + const PedConstraint* constraint) { if (part->type == PED_PARTITION_LOGICAL) - return _align_logical (part, constraint); + return _align_logical (part, bios_geom, constraint); else - return _align_primary (part, constraint); + return _align_primary (part, bios_geom, constraint); } static PedConstraint* @@ -1507,7 +1542,7 @@ _no_geom_extended_constraint (PedPartition* part) { PedDevice* dev = part->disk->dev; - PedGeometry* min = _get_min_extended_part_geom (part); + PedGeometry* min = _get_min_extended_part_geom (part, NULL); PedGeometry start_range; PedGeometry end_range; PedConstraint* constraint; @@ -1605,28 +1640,14 @@ static int msdos_partition_align (PedPartition* part, const PedConstraint* constraint) { + PedCHSGeometry bios_geom; + PED_ASSERT (part != NULL, return 0); - - if (_align (part, constraint)) + + partition_probe_bios_geometry (part, &bios_geom); + + if (_align (part, &bios_geom, constraint)) return 1; - - if (part->disk->dev->geom_known) { -#ifndef DISCOVER_ONLY - if (ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_IGNORE_CANCEL, - _("Unable to align partition properly. This probably " - "means that another partitioning tool generated an " - "incorrect partition table, because it didn't have " - "the correct BIOS geometry. It is safe to ignore," - "but ignoring may cause (fixable) problems with " - "some boot loaders.")) - == PED_EXCEPTION_CANCEL) - return 0; -#endif /* !DISCOVER_ONLY */ - part->disk->dev->geom_known = 0; - } - if (_align_no_geom (part, constraint)) return 1; @@ -1671,20 +1692,17 @@ static int _add_logical_part_metadata (PedDisk* disk, PedPartition* log_part) { + PedPartition* ext_part = ped_disk_extended_partition (disk); PedPartition* prev = log_part->prev; PedDevice* dev = disk->dev; - PedSector cyl_size = dev->sectors * dev->heads; + PedCHSGeometry bios_geom; + PedSector cyl_size; PedSector metadata_start; PedSector metadata_end; PedSector metadata_length; - if (!dev->geom_known) { - PedSector metadata_sector = log_part->geom.start - 1; - if (log_part->num == 5) - return 1; - return add_metadata_part (disk, PED_PARTITION_LOGICAL, - metadata_sector, metadata_sector); - } + partition_probe_bios_geometry (ext_part, &bios_geom); + cyl_size = bios_geom.sectors * bios_geom.heads; /* if there's metadata shortly before the partition (on the same * cylinder), then make this new metadata partition touch the end of @@ -1705,10 +1723,10 @@ metadata_length = metadata_end - metadata_start + 1; /* partition 5 doesn't need to have any metadata */ - if (log_part->num == 5 && metadata_length < dev->sectors) + if (log_part->num == 5 && metadata_length < bios_geom.sectors) return 1; - PED_ASSERT (metadata_length >= dev->sectors, return 0); + PED_ASSERT (metadata_length >= bios_geom.sectors, return 0); PED_ASSERT (metadata_start / cyl_size == log_part->geom.start / cyl_size, return 0); @@ -1727,18 +1745,12 @@ PED_ASSERT (disk->dev != NULL, return 0); dev = disk->dev; - cyl_size = dev->sectors * dev->heads; + cyl_size = dev->bios_geom.sectors * dev->bios_geom.heads; - if (dev->geom_known) { - if (!add_metadata_part (disk, 0, 0, dev->sectors - 1)) - return 0; - } else { - if (!add_metadata_part (disk, 0, 0, 0)) - return 0; - } + if (!add_metadata_part (disk, 0, 0, dev->bios_geom.sectors - 1)) + return 0; - if (dev->geom_known - && ped_round_down_to (dev->length, cyl_size) != dev->length) { + if (ped_round_down_to (dev->length, cyl_size) != dev->length) { if (!add_metadata_part ( disk, 0, @@ -1750,7 +1762,11 @@ ext_part = ped_disk_extended_partition (disk); if (ext_part) { int i; - PedSector meta_length = dev->geom_known? dev->sectors : 1; + PedSector meta_length; + PedCHSGeometry bios_geom; + + partition_probe_bios_geometry (ext_part, &bios_geom); + meta_length = bios_geom.sectors; if (!add_metadata_part (disk, PED_PARTITION_LOGICAL, ext_part->geom.start, Index: libparted/disk_dvh.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/disk_dvh.c,v retrieving revision 1.2 diff -u -r1.2 disk_dvh.c --- libparted/disk_dvh.c 21 Jun 2004 04:29:16 -0000 1.2 +++ libparted/disk_dvh.c 8 Aug 2004 08:35:20 -0000 @@ -491,9 +491,11 @@ vh.vh_dp = dvh_disk_data->dev_params; /* Set up rudimentary device geometry */ - vh.vh_dp.dp_cyls = PED_CPU_TO_BE16 ((short)disk->dev->cylinders); - vh.vh_dp.dp_trks0 = PED_CPU_TO_BE16 ((short)disk->dev->heads); - vh.vh_dp.dp_secs = PED_CPU_TO_BE16 ((short)disk->dev->sectors); + vh.vh_dp.dp_cyls + = PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.cylinders); + vh.vh_dp.dp_trks0 = PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.heads); + vh.vh_dp.dp_secs + = PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.sectors); vh.vh_dp.dp_secbytes = PED_CPU_TO_BE16 ((short)disk->dev->sector_size); for (i = 0; i < NPARTAB; i++) { @@ -767,7 +769,7 @@ PedAlignment start_align; PedAlignment end_align; PedGeometry max_geom; - PedSector block = dev->sectors * dev->heads; + PedSector block = dev->bios_geom.sectors * dev->bios_geom.heads; PedSector start_lower_bound; PedPartition* extended_partition = ped_disk_extended_partition (disk); Index: libparted/disk_pc98.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/disk_pc98.c,v retrieving revision 1.1 diff -u -r1.1 disk_pc98.c --- libparted/disk_pc98.c 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/disk_pc98.c 8 Aug 2004 08:35:20 -0000 @@ -147,15 +147,15 @@ check_partition_consistency (const PedDevice* dev, const PC98RawPartition* raw_part) { - if (raw_part->ipl_sect >= dev->sectors - || raw_part->sector >= dev->sectors - || raw_part->end_sector >= dev->sectors - || raw_part->ipl_head >= dev->heads - || raw_part->head >= dev->heads - || raw_part->end_head >= dev->heads - || PED_LE16_TO_CPU(raw_part->ipl_cyl) >= dev->cylinders - || PED_LE16_TO_CPU(raw_part->cyl) >= dev->cylinders - || PED_LE16_TO_CPU(raw_part->end_cyl) >= dev->cylinders + if (raw_part->ipl_sect >= dev->phys_geom.sectors + || raw_part->sector >= dev->phys_geom.sectors + || raw_part->end_sector >= dev->phys_geom.sectors + || raw_part->ipl_head >= dev->phys_geom.heads + || raw_part->head >= dev->phys_geom.heads + || raw_part->end_head >= dev->phys_geom.heads + || PED_LE16_TO_CPU(raw_part->ipl_cyl) >= dev->phys_geom.cylinders + || PED_LE16_TO_CPU(raw_part->cyl) >= dev->phys_geom.cylinders + || PED_LE16_TO_CPU(raw_part->end_cyl) >= dev->phys_geom.cylinders || PED_LE16_TO_CPU(raw_part->cyl) > PED_LE16_TO_CPU(raw_part->end_cyl) #if 0 @@ -267,19 +267,24 @@ chs_to_sector (const PedDevice* dev, int c, int h, int s) { PED_ASSERT (dev != NULL, return 0); - return (c * dev->heads + h) * dev->sectors + s; + return (c * dev->phys_geom.heads + h) * dev->phys_geom.sectors + s; } static void sector_to_chs (const PedDevice* dev, PedSector sector, int* c, int* h, int* s) { + PedSector cyl_size; + PED_ASSERT (dev != NULL, return); PED_ASSERT (c != NULL, return); PED_ASSERT (h != NULL, return); PED_ASSERT (s != NULL, return); - *c = (sector) / (dev->heads * dev->sectors); - *h = ((sector) % (dev->heads * dev->sectors)) / dev->sectors; - *s = ((sector) % (dev->heads * dev->sectors)) % dev->sectors; + + cyl_size = dev->phys_geom.heads * dev->phys_geom.sectors; + + *c = sector / cyl_size; + *h = (sector) % cyl_size / dev->phys_geom.sectors; + *s = (sector) % cyl_size % dev->phys_geom.sectors; } static PedSector @@ -301,8 +306,8 @@ if (raw_part->end_head == 0 && raw_part->end_sector == 0) { return chs_to_sector (disk->dev, PED_LE16_TO_CPU(raw_part->end_cyl), - disk->dev->heads - 1, - disk->dev->sectors - 1); + disk->dev->phys_geom.heads - 1, + disk->dev->phys_geom.sectors - 1); } else { return chs_to_sector (disk->dev, PED_LE16_TO_CPU(raw_part->end_cyl), @@ -471,8 +476,8 @@ } sector_to_chs (part->disk->dev, part->geom.end, &c, &h, &s); - if (h != part->disk->dev->heads - 1 - || s != part->disk->dev->sectors - 1) { + if (h != part->disk->dev->phys_geom.heads - 1 + || s != part->disk->dev->phys_geom.sectors - 1) { ped_exception_throw ( PED_EXCEPTION_NO_FEATURE, PED_EXCEPTION_CANCEL, @@ -726,7 +731,7 @@ PedGeometry max_geom; PedSector cylinder_size; - cylinder_size = dev->sectors * dev->heads; + cylinder_size = dev->phys_geom.sectors * dev->phys_geom.heads; if (!ped_alignment_init (&start_align, 0, cylinder_size)) return NULL; @@ -797,14 +802,16 @@ { PedPartition* new_part; PedConstraint* constraint_any = NULL; + PedSector cyl_size; PED_ASSERT (disk != NULL, goto error); PED_ASSERT (disk->dev != NULL, goto error); constraint_any = ped_constraint_any (disk->dev); + cyl_size = disk->dev->phys_geom.sectors * disk->dev->phys_geom.heads; new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL, - 0, disk->dev->sectors * disk->dev->heads - 1); + 0, cyl_size - 1); if (!new_part) goto error; Index: libparted/disk_sun.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/disk_sun.c,v retrieving revision 1.1 diff -u -r1.1 disk_sun.c --- libparted/disk_sun.c 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/disk_sun.c 8 Aug 2004 08:35:21 -0000 @@ -184,19 +184,20 @@ defaults since most people do anyway...sue me. */ label->magic = PED_CPU_TO_BE16 (SUN_DISK_MAGIC); label->nacyl = PED_CPU_TO_BE16 (2); - label->pcylcount = PED_CPU_TO_BE16 (dev->cylinders); + label->pcylcount = PED_CPU_TO_BE16 (dev->phys_geom.cylinders); label->rspeed = PED_CPU_TO_BE16 (5400); label->ilfact = PED_CPU_TO_BE16 (1); - label->sparecyl = PED_CPU_TO_BE16 (dev->sectors); - label->ntrks = PED_CPU_TO_BE16 (dev->heads); - label->nsect = PED_CPU_TO_BE16 (dev->sectors); - label->ncyl = PED_CPU_TO_BE16 (dev->cylinders - 2); + label->sparecyl = PED_CPU_TO_BE16 (dev->phys_geom.sectors); + label->ntrks = PED_CPU_TO_BE16 (dev->phys_geom.heads); + label->nsect = PED_CPU_TO_BE16 (dev->phys_geom.sectors); + label->ncyl = PED_CPU_TO_BE16 (dev->phys_geom.cylinders - 2); /* Add a whole disk partition at a minimum */ label->infos[WHOLE_DISK_PART].id = WHOLE_DISK_ID; label->partitions[WHOLE_DISK_PART].start_cylinder = 0; label->partitions[WHOLE_DISK_PART].num_sectors = - PED_CPU_TO_BE32((dev->cylinders-2) * dev->heads * dev->sectors); + PED_CPU_TO_BE32((dev->phys_geom.cylinders-2) + * dev->phys_geom.heads * dev->phys_geom.sectors); /* Now a neato string to describe this label */ snprintf(label->info, sizeof(label->info) - 1, @@ -241,8 +242,12 @@ { PedDevice* dev = disk->dev; - if (PED_BE16_TO_CPU(label->nsect) != dev->sectors || - PED_BE16_TO_CPU(label->ntrks) != dev->heads) { + if (PED_BE16_TO_CPU(label->nsect) == dev->phys_geom.sectors && + PED_BE16_TO_CPU(label->ntrks) == dev->phys_geom.heads) + dev->bios_geom = dev->phys_geom; + + if (PED_BE16_TO_CPU(label->nsect) != dev->bios_geom.sectors || + PED_BE16_TO_CPU(label->ntrks) != dev->bios_geom.heads) { #ifndef DISCOVER_ONLY if (ped_exception_throw ( PED_EXCEPTION_WARNING, @@ -250,18 +255,21 @@ _("The disk CHS geometry (%d,%d,%d) does not " "match the geometry stored on the disk " "label (%d,%d,%d)."), - dev->cylinders, dev->heads, dev->sectors, + dev->phys_geom.cylinders, + dev->phys_geom.heads, + dev->phys_geom.sectors, PED_BE16_TO_CPU(label->pcylcount), PED_BE16_TO_CPU(label->ntrks), PED_BE16_TO_CPU(label->nsect)) == PED_EXCEPTION_CANCEL) return 0; #endif - dev->sectors = PED_BE16_TO_CPU(label->nsect); - dev->heads = PED_BE16_TO_CPU(label->ntrks); - dev->cylinders = PED_BE16_TO_CPU(label->pcylcount); + dev->bios_geom.sectors = PED_BE16_TO_CPU(label->nsect); + dev->bios_geom.heads = PED_BE16_TO_CPU(label->ntrks); + dev->bios_geom.cylinders = PED_BE16_TO_CPU(label->pcylcount); - if (dev->sectors * dev->heads * dev->cylinders > dev->length) { + if (dev->bios_geom.sectors * dev->bios_geom.heads + * dev->bios_geom.cylinders > dev->length) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, @@ -300,8 +308,8 @@ if (!_check_geometry_sanity (disk, label)) goto error; - block = disk->dev->sectors * disk->dev->heads; - disk_data->length = block * (disk->dev->cylinders + block = disk->dev->bios_geom.sectors * disk->dev->bios_geom.heads; + disk_data->length = block * (disk->dev->bios_geom.cylinders - PED_BE16_TO_CPU(label->nacyl)); for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) { @@ -402,7 +410,8 @@ label->infos[i].id = sun_data->type; label->partitions[i].start_cylinder = PED_CPU_TO_BE32 (part->geom.start - / (disk->dev->sectors * disk->dev->heads)); + / (disk->dev->bios_geom.sectors + * disk->dev->bios_geom.heads)); label->partitions[i].num_sectors = PED_CPU_TO_BE32 (part->geom.end - part->geom.start + 1); @@ -416,8 +425,8 @@ smaller than it really is, but we'll have that problem even if we don't do this. */ - label->pcylcount = PED_CPU_TO_BE16 (disk->dev->cylinders); - label->ncyl = PED_CPU_TO_BE16 (disk->dev->cylinders + label->pcylcount = PED_CPU_TO_BE16 (disk->dev->bios_geom.cylinders); + label->ncyl = PED_CPU_TO_BE16 (disk->dev->bios_geom.cylinders - PED_BE32_TO_CPU(label->nacyl)); sun_compute_checksum (label); @@ -620,7 +629,7 @@ PedAlignment end_align; PedGeometry max_geom; SunDiskData* disk_data = disk->disk_specific; - PedSector block = dev->sectors * dev->heads; + PedSector block = dev->bios_geom.sectors * dev->bios_geom.heads; if (!ped_alignment_init (&start_align, 0, block)) return NULL; @@ -640,7 +649,7 @@ PedAlignment start_align; PedGeometry max_geom; SunDiskData* disk_data = disk->disk_specific; - PedSector block = dev->sectors * dev->heads; + PedSector block = dev->bios_geom.sectors * dev->bios_geom.heads; if (!ped_alignment_init (&start_align, 0, block)) return NULL; Index: libparted/gnu.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/gnu.c,v retrieving revision 1.1 diff -u -r1.1 gnu.c --- libparted/gnu.c 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/gnu.c 8 Aug 2004 08:35:21 -0000 @@ -72,10 +72,9 @@ return 0; /* XXX: We have no way to get this! */ - dev->sectors = 32; - dev->heads = 4; - dev->geom_known = 0; - dev->cylinders = dev->length / (dev->heads * dev->sectors + dev->bios_geom.sectors = 32; + dev->bios_geom.heads = 4; + dev->bios_geom.cylinders = dev->length / (dev->heads * dev->sectors * (dev->sector_size / PED_SECTOR_SIZE)); return 1; @@ -175,8 +174,6 @@ dev->external_mode = 0; dev->dirty = 0; dev->boot_dirty = 0; - dev->geom_known = 1; - dev->geom_already_guessed = 0; return dev; Index: libparted/linux.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/linux.c,v retrieving revision 1.1 diff -u -r1.1 linux.c --- libparted/linux.c 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/linux.c 8 Aug 2004 08:35:22 -0000 @@ -61,10 +61,10 @@ #define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */ struct hd_geometry { - unsigned char heads; - unsigned char sectors; - unsigned short cylinders; - unsigned long start; + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + unsigned long start; }; /* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */ @@ -405,7 +405,7 @@ if (_kernel_has_blkgetsize64()) { if (ioctl(arch_specific->fd, BLKGETSIZE64, &bytes) == 0) { - return bytes / _device_get_sector_size(dev); + return bytes / PED_SECTOR_SIZE; } } @@ -430,43 +430,39 @@ struct hd_geometry geometry; if (!_device_stat (dev, &dev_stat)) - goto error; - PED_ASSERT (S_ISBLK (dev_stat.st_mode), goto error); + return 0; + PED_ASSERT (S_ISBLK (dev_stat.st_mode), return 0); dev->length = _device_get_length (dev); if (!dev->length) - goto error; - - if (ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)) { - ped_exception_throw (PED_EXCEPTION_ERROR, - PED_EXCEPTION_CANCEL, - _("Could not read geometry of %s - %s."), - dev->path, strerror (errno)); - goto error; - } + return 0; dev->sector_size = _device_get_sector_size (dev); if (!dev->sector_size) - goto error; - - dev->sectors = geometry.sectors; - dev->heads = geometry.heads; - if (!dev->sectors || !dev->heads) - goto error_dodgey_geometry; + return 0; - dev->cylinders = dev->length / (dev->heads * dev->sectors - * (dev->sector_size / PED_SECTOR_SIZE)); + /* The GETGEO ioctl is no longer useful (as of linux 2.6.x). We could + * still use it in 2.4.x, but this is contentious. Perhaps we should + * move to EDD. */ + dev->bios_geom.sectors = 63; + dev->bios_geom.heads = 255; + dev->bios_geom.cylinders + = dev->length / (63 * 255) + / (dev->sector_size / PED_SECTOR_SIZE); + + /* FIXME: what should we put here? (TODO: discuss on linux-kernel) */ + if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)) { + dev->phys_geom.sectors = geometry.sectors; + dev->phys_geom.heads = geometry.heads; + dev->phys_geom.cylinders + = dev->length / (dev->phys_geom.heads + * dev->phys_geom.sectors) + / (dev->sector_size / PED_SECTOR_SIZE); + } else { + dev->phys_geom = dev->bios_geom; + } return 1; - -error_dodgey_geometry: - ped_exception_throw ( - PED_EXCEPTION_ERROR, - PED_EXCEPTION_CANCEL, - _("Device %s has dodgey geometry."), - dev->path); -error: - return 0; } static char* @@ -685,11 +681,10 @@ ped_device_close (dev); - dev->cylinders = dev->length / 4 / 32; - dev->heads = 4; - dev->sectors = 32; + dev->bios_geom.cylinders = dev->length / 4 / 32; + dev->bios_geom.heads = 4; + dev->bios_geom.sectors = 32; dev->sector_size = 512; - dev->geom_known = 0; dev->model = strdup (""); return 1; @@ -737,11 +732,10 @@ /* what should we stick in here? */ dev->length = dev_stat.st_size / PED_SECTOR_SIZE; - dev->cylinders = dev->length / 4 / 32; - dev->heads = 4; - dev->sectors = 32; + dev->bios_geom.cylinders = dev->length / 4 / 32; + dev->bios_geom.heads = 4; + dev->bios_geom.sectors = 32; dev->sector_size = PED_SECTOR_SIZE; - dev->geom_known = 0; } dev->model = strdup (model_name); @@ -780,8 +774,6 @@ dev->external_mode = 0; dev->dirty = 0; dev->boot_dirty = 0; - dev->geom_known = 1; - dev->geom_already_guessed = 0; if (!_device_probe_type (dev)) goto error_free_arch_specific; Index: libparted/fs_fat/bootsector.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/fs_fat/bootsector.c,v retrieving revision 1.2 diff -u -r1.2 bootsector.c --- libparted/fs_fat/bootsector.c 16 Jun 2004 01:33:29 -0000 1.2 +++ libparted/fs_fat/bootsector.c 8 Aug 2004 08:35:22 -0000 @@ -144,6 +144,8 @@ } fs_info->logical_sector_size = PED_LE16_TO_CPU (bs->sector_size) / 512; + fs_info->sectors_per_track = PED_LE16_TO_CPU (bs->secs_track); + fs_info->heads = PED_LE16_TO_CPU (bs->heads); if (bs->sectors) fs_info->sector_count = PED_LE16_TO_CPU (bs->sectors) @@ -254,7 +256,6 @@ fat_boot_sector_generate (FatBootSector* bs, const PedFileSystem* fs) { FatSpecific* fs_info = FAT_SPECIFIC (fs); - int heads, sectors; PED_ASSERT (bs != NULL, return 0); @@ -283,10 +284,8 @@ bs->media = 0xf8; - sectors = fs->geom->dev->sectors; - heads = fs->geom->dev->heads; - bs->secs_track = PED_CPU_TO_LE16 (sectors); - bs->heads = PED_CPU_TO_LE16 (heads); + bs->secs_track = PED_CPU_TO_LE16 (fs_info->sectors_per_track); + bs->heads = PED_CPU_TO_LE16 (fs_info->heads); bs->hidden = PED_CPU_TO_LE32 (fs->geom->start); if (fs_info->fat_type == FAT_TYPE_FAT32) { Index: libparted/fs_fat/fat.c =================================================================== RCS file: /cvsroot/parted/stable/libparted/fs_fat/fat.c,v retrieving revision 1.1 diff -u -r1.1 fat.c --- libparted/fs_fat/fat.c 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/fs_fat/fat.c 8 Aug 2004 08:35:22 -0000 @@ -291,6 +291,8 @@ fs_info = (FatSpecific*) fs->type_specific; fs_info->logical_sector_size = 1; + fs_info->sectors_per_track = geom->dev->bios_geom.sectors; + fs_info->heads = geom->dev->bios_geom.heads; fs_info->sector_count = fs->geom->length; fs_info->fat_table_count = 2; /* some initial values, to be changed later */ Index: libparted/fs_fat/fat.h =================================================================== RCS file: /cvsroot/parted/stable/libparted/fs_fat/fat.h,v retrieving revision 1.1 diff -u -r1.1 fat.h --- libparted/fs_fat/fat.h 13 Jun 2004 06:35:11 -0000 1.1 +++ libparted/fs_fat/fat.h 8 Aug 2004 08:35:22 -0000 @@ -86,6 +86,9 @@ int logical_sector_size; /* illogical sector size :-) */ PedSector sector_count; + int sectors_per_track; /* BIOS CHS stuff (S) */ + int heads; /* BIOS CHS stuff (H) */ + int cluster_size; PedSector cluster_sectors; FatCluster cluster_count; Index: parted/ui.c =================================================================== RCS file: /cvsroot/parted/stable/parted/ui.c,v retrieving revision 1.1 diff -u -r1.1 ui.c --- parted/ui.c 13 Jun 2004 06:35:11 -0000 1.1 +++ parted/ui.c 8 Aug 2004 08:35:23 -0000 @@ -957,102 +957,10 @@ exit (0); } -/* we need a CHS warning if there is a DOS partition table with a FAT - * partition(s) without the LBA flag set - */ -static int -_need_chs_warning (PedDevice* dev) -{ -#if defined (__i386__) - PedDisk* disk; - PedPartition* walk; - int has_non_lba_fat; - - disk = ped_disk_new (dev); - if (!disk) - return 0; - - if (strcmp (disk->type->name, "msdos")) { - ped_disk_destroy (disk); - return 0; - } - - has_non_lba_fat = 0; - for (walk = ped_disk_next_partition (disk, NULL); walk; - walk = ped_disk_next_partition (disk, walk)) { - if (!ped_partition_is_active (walk)) - continue; - if (!walk->fs_type) - continue; - - if (!strcmp(walk->fs_type->name, "FAT") - && !ped_partition_get_flag (walk, PED_PARTITION_LBA)) - has_non_lba_fat = 1; - } - - ped_disk_destroy (disk); - return has_non_lba_fat; -#else - return 0; -#endif -} - -/* if we need to scare users about CHS stuff, do it... - */ -static void -_do_chs_check (PedDevice* dev) -{ -#if defined (__i386__) - PedExceptionType ex_type; - char* warning_msg; - - if (_need_chs_warning (dev)) { - ex_type = PED_EXCEPTION_WARNING; - warning_msg = _(" You have Windows FAT partition(s) that are " - "not using LBA. If your BIOS supports LBA, " - "then you should switch to LBA by setting the " - "LBA flag on all FAT partitions. Otherwise, " - "make sure the operating system and the BIOS " - "have the same geometry before resizing any " - "FAT partitions."); - } else { - ex_type = PED_EXCEPTION_INFORMATION; - warning_msg = ""; - } - - /* already been subjected to a rant */ - if (!dev->geom_known) - return; - - if (dev->cylinders > 1024) - ped_exception_throw ( - ex_type, - PED_EXCEPTION_OK, - _("The operating system thinks the geometry on %s is " - "%d/%d/%d. Therefore, cylinder 1024 ends at %.3fM.%s"), - dev->path, - dev->cylinders, dev->heads, dev->sectors, - (1024 * dev->heads * dev->sectors - 1) / 2 / 1024.0, - warning_msg); - else - ped_exception_throw ( - ex_type, - PED_EXCEPTION_OK, - _("The operating system thinks the geometry on %s is " - "%d/%d/%d.%s"), - dev->path, - dev->cylinders, dev->heads, dev->sectors, - warning_msg); -#endif -} - void print_using_dev (PedDevice* dev) { printf (_("Using %s\n"), dev->path); - if (dev->type != PED_DEVICE_UNKNOWN - && dev->type != PED_DEVICE_FILE) - _do_chs_check (dev); } int