diff options
Diffstat (limited to 'fdisk/fdisk.c')
-rw-r--r-- | fdisk/fdisk.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index 6572c51d..68293213 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -180,6 +180,8 @@ static int type_open = O_RDWR; */ unsigned char *MBRbuffer; +int MBRbuffer_changed; + /* * per partition table entry data * @@ -217,12 +219,11 @@ unsigned long long sector_offset = 1, extended_offset = 0, sectors; unsigned int heads, cylinders, sector_size = DEFAULT_SECTOR_SIZE, - sector_factor = 1, user_set_sector_size = 0, units_per_sector = 1, display_in_cyl_units = 0; -unsigned long long total_number_of_sectors; /* (!) 512-byte sectors */ +unsigned long long total_number_of_sectors; /* in logical sectors */ unsigned long grain = DEFAULT_SECTOR_SIZE, io_size = DEFAULT_SECTOR_SIZE, min_io_size = DEFAULT_SECTOR_SIZE, @@ -658,7 +659,7 @@ static int lba_is_aligned(unsigned long long lba) { unsigned int granularity = max(phy_sector_size, min_io_size); - unsigned long long offset = (lba << 9) & (granularity - 1); + unsigned long long offset = (lba * sector_size) & (granularity - 1); return !((granularity + alignment_offset - offset) & (granularity - 1)); } @@ -770,7 +771,8 @@ void update_units(void) static void warn_limits(void) { if (total_number_of_sectors > UINT_MAX && !nowarn) { - int giga = (total_number_of_sectors << 9) / 1000000000; + unsigned long long bytes = total_number_of_sectors * sector_size; + int giga = bytes / 1000000000; int hectogiga = (giga + 50) / 100; fprintf(stderr, _("\n" @@ -779,7 +781,7 @@ warn_limits(void) { "larger than (%llu bytes) for %d-byte sectors. Use parted(1) and GUID \n" "partition table format (GPT).\n\n"), hectogiga / 10, hectogiga % 10, - total_number_of_sectors << 9, + bytes, (unsigned long long ) UINT_MAX * sector_size, sector_size); } @@ -934,6 +936,7 @@ dos_set_mbr_id(void) { return; dos_write_mbr_id(MBRbuffer, new_id); + MBRbuffer_changed = 1; dos_print_mbr_id(); } @@ -1119,10 +1122,9 @@ update_sector_offset(void) void get_geometry(int fd, struct geom *g) { - unsigned long long llcyls; + unsigned long long llcyls, nsects = 0; get_topology(fd); - sector_factor = sector_size / 512; guess_device_type(fd); heads = cylinders = sectors = 0; kern_heads = kern_sectors = 0; @@ -1138,12 +1140,13 @@ get_geometry(int fd, struct geom *g) { pt_sectors ? pt_sectors : kern_sectors ? kern_sectors : 63; - if (blkdev_get_sectors(fd, &total_number_of_sectors) == -1) - total_number_of_sectors = 0; + /* get number of 512-byte sectors, and convert it the real sectors */ + if (blkdev_get_sectors(fd, &nsects) == 0) + total_number_of_sectors = (nsects / (sector_size >> 9)); update_sector_offset(); - llcyls = total_number_of_sectors / (heads * sectors * sector_factor); + llcyls = total_number_of_sectors / (heads * sectors); cylinders = llcyls; if (cylinders != llcyls) /* truncated? */ cylinders = ~0; @@ -1886,7 +1889,7 @@ check_alignment(unsigned long long lba, int partition) static void list_disk_geometry(void) { - long long bytes = (total_number_of_sectors << 9); + unsigned long long bytes = total_number_of_sectors * sector_size; long megabytes = bytes/1000000; if (megabytes < 10000) @@ -1894,14 +1897,13 @@ list_disk_geometry(void) { disk_device, megabytes, bytes); else { long hectomega = (megabytes + 50) / 100; - printf(_("\nDisk %s: %ld.%ld GB, %lld bytes\n"), + printf(_("\nDisk %s: %ld.%ld GB, %llu bytes\n"), disk_device, hectomega / 10, hectomega % 10, bytes); } printf(_("%d heads, %llu sectors/track, %d cylinders"), heads, sectors, cylinders); if (units_per_sector == 1) - printf(_(", total %llu sectors"), - total_number_of_sectors / sector_factor); + printf(_(", total %llu sectors"), total_number_of_sectors); printf("\n"); printf(_("Units = %s of %d * %d = %d bytes\n"), str_units(PLURAL), @@ -2210,7 +2212,7 @@ static void verify(void) { int i, j; unsigned long long total = 1; - unsigned long long n_sectors = (total_number_of_sectors / sector_factor); + unsigned long long n_sectors = total_number_of_sectors; unsigned long long first[partitions], last[partitions]; struct partition *p; @@ -2324,7 +2326,7 @@ add_partition(int n, int sys) { if (display_in_cyl_units || !total_number_of_sectors) llimit = heads * sectors * cylinders - 1; else - llimit = (total_number_of_sectors / sector_factor) - 1; + llimit = total_number_of_sectors - 1; limit = llimit; if (limit != llimit) limit = 0x7fffffff; @@ -2553,10 +2555,18 @@ write_table(void) { int i; if (dos_label) { - for (i=0; i<3; i++) - if (ptes[i].changed) - ptes[3].changed = 1; - for (i = 3; i < partitions; i++) { + /* MBR (primary partitions) */ + if (!MBRbuffer_changed) { + for (i = 0; i < 4; i++) + if (ptes[i].changed) + MBRbuffer_changed = 1; + } + if (MBRbuffer_changed) { + write_part_table_flag(MBRbuffer); + write_sector(fd, 0, MBRbuffer); + } + /* EBR (logical partitions) */ + for (i = 4; i < partitions; i++) { struct pte *pe = &ptes[i]; if (pe->changed) { |