summaryrefslogtreecommitdiff
path: root/fdisk/fdisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'fdisk/fdisk.c')
-rw-r--r--fdisk/fdisk.c50
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) {