From: Karel Zak Date: Mon, 21 Jan 2013 11:06:17 +0000 (+0100) Subject: fdisk: (dos) move fix order code to fdiskdoslabe.c X-Git-Tag: v2.23-rc1~141 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dfc96cbf1fee8b52d36cbcbb262024ccd3073873;p=thirdparty%2Futil-linux.git fdisk: (dos) move fix order code to fdiskdoslabe.c Signed-off-by: Karel Zak --- diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index ee4c3ca07f..cb655117bb 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -794,141 +794,6 @@ list_disk_geometry(struct fdisk_context *cxt) { printf("\n"); } -/* - * Check whether partition entries are ordered by their starting positions. - * Return 0 if OK. Return i if partition i should have been earlier. - * Two separate checks: primary and logical partitions. - */ -int -wrong_p_order(int *prev) { - struct pte *pe; - struct partition *p; - unsigned int last_p_start_pos = 0, p_start_pos; - int i, last_i = 0; - - for (i = 0 ; i < partitions; i++) { - if (i == 4) { - last_i = 4; - last_p_start_pos = 0; - } - pe = &ptes[i]; - if ((p = pe->part_table)->sys_ind) { - p_start_pos = get_partition_start(pe); - - if (last_p_start_pos > p_start_pos) { - if (prev) - *prev = last_i; - return i; - } - - last_p_start_pos = p_start_pos; - last_i = i; - } - } - return 0; -} - -/* - * Fix the chain of logicals. - * extended_offset is unchanged, the set of sectors used is unchanged - * The chain is sorted so that sectors increase, and so that - * starting sectors increase. - * - * After this it may still be that cfdisk doesn't like the table. - * (This is because cfdisk considers expanded parts, from link to - * end of partition, and these may still overlap.) - * Now - * sfdisk /dev/hda > ohda; sfdisk /dev/hda < ohda - * may help. - */ -static void -fix_chain_of_logicals(void) { - int j, oj, ojj, sj, sjj; - struct partition *pj,*pjj,tmp; - - /* Stage 1: sort sectors but leave sector of part 4 */ - /* (Its sector is the global extended_offset.) */ - stage1: - for (j = 5; j < partitions-1; j++) { - oj = ptes[j].offset; - ojj = ptes[j+1].offset; - if (oj > ojj) { - ptes[j].offset = ojj; - ptes[j+1].offset = oj; - pj = ptes[j].part_table; - set_start_sect(pj, get_start_sect(pj)+oj-ojj); - pjj = ptes[j+1].part_table; - set_start_sect(pjj, get_start_sect(pjj)+ojj-oj); - set_start_sect(ptes[j-1].ext_pointer, - ojj-extended_offset); - set_start_sect(ptes[j].ext_pointer, - oj-extended_offset); - goto stage1; - } - } - - /* Stage 2: sort starting sectors */ - stage2: - for (j = 4; j < partitions-1; j++) { - pj = ptes[j].part_table; - pjj = ptes[j+1].part_table; - sj = get_start_sect(pj); - sjj = get_start_sect(pjj); - oj = ptes[j].offset; - ojj = ptes[j+1].offset; - if (oj+sj > ojj+sjj) { - tmp = *pj; - *pj = *pjj; - *pjj = tmp; - set_start_sect(pj, ojj+sjj-oj); - set_start_sect(pjj, oj+sj-ojj); - goto stage2; - } - } - - /* Probably something was changed */ - for (j = 4; j < partitions; j++) - ptes[j].changed = 1; -} - -static void -fix_partition_table_order(void) { - struct pte *pei, *pek; - int i,k; - - if (!wrong_p_order(NULL)) { - printf(_("Nothing to do. Ordering is correct already.\n\n")); - return; - } - - while ((i = wrong_p_order(&k)) != 0 && i < 4) { - /* partition i should have come earlier, move it */ - /* We have to move data in the MBR */ - struct partition *pi, *pk, *pe, pbuf; - pei = &ptes[i]; - pek = &ptes[k]; - - pe = pei->ext_pointer; - pei->ext_pointer = pek->ext_pointer; - pek->ext_pointer = pe; - - pi = pei->part_table; - pk = pek->part_table; - - memmove(&pbuf, pi, sizeof(struct partition)); - memmove(pi, pk, sizeof(struct partition)); - memmove(pk, &pbuf, sizeof(struct partition)); - - pei->changed = pek->changed = 1; - } - - if (i) - fix_chain_of_logicals(); - - printf(_("Done.\n")); - -} - static void list_table(struct fdisk_context *cxt, int xtra) { if (fdisk_is_disklabel(cxt, SUN)) { @@ -1253,7 +1118,7 @@ expert_command_prompt(struct fdisk_context *cxt) break; case 'f': if (fdisk_is_disklabel(cxt, DOS)) - fix_partition_table_order(); + dos_fix_partition_table_order(); break; case 'g': fdisk_create_disklabel(cxt, "sgi"); diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h index 0217bdfd47..ae9d3a1279 100644 --- a/fdisks/fdisk.h +++ b/fdisks/fdisk.h @@ -93,8 +93,6 @@ extern unsigned int read_int_with_suffix(struct fdisk_context *cxt, unsigned int base, char *mesg, int *is_suffix_used); extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt); -extern int wrong_p_order(int *prev); - #define PLURAL 0 #define SINGULAR 1 extern const char * str_units(int); diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index da6526e3fe..d174c735ab 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -964,6 +964,39 @@ static int dos_set_parttype( return 0; } +/* + * Check whether partition entries are ordered by their starting positions. + * Return 0 if OK. Return i if partition i should have been earlier. + * Two separate checks: primary and logical partitions. + */ +static int wrong_p_order(int *prev) +{ + struct pte *pe; + struct partition *p; + unsigned int last_p_start_pos = 0, p_start_pos; + int i, last_i = 0; + + for (i = 0 ; i < partitions; i++) { + if (i == 4) { + last_i = 4; + last_p_start_pos = 0; + } + pe = &ptes[i]; + if ((p = pe->part_table)->sys_ind) { + p_start_pos = get_partition_start(pe); + + if (last_p_start_pos > p_start_pos) { + if (prev) + *prev = last_i; + return i; + } + + last_p_start_pos = p_start_pos; + last_i = i; + } + } + return 0; +} static int is_garbage_table(void) { @@ -1047,6 +1080,106 @@ int dos_list_table(struct fdisk_context *cxt, return 0; } +/* + * Fix the chain of logicals. + * extended_offset is unchanged, the set of sectors used is unchanged + * The chain is sorted so that sectors increase, and so that + * starting sectors increase. + * + * After this it may still be that cfdisk doesn't like the table. + * (This is because cfdisk considers expanded parts, from link to + * end of partition, and these may still overlap.) + * Now + * sfdisk /dev/hda > ohda; sfdisk /dev/hda < ohda + * may help. + */ +static void fix_chain_of_logicals(void) +{ + int j, oj, ojj, sj, sjj; + struct partition *pj,*pjj,tmp; + + /* Stage 1: sort sectors but leave sector of part 4 */ + /* (Its sector is the global extended_offset.) */ + stage1: + for (j = 5; j < partitions-1; j++) { + oj = ptes[j].offset; + ojj = ptes[j+1].offset; + if (oj > ojj) { + ptes[j].offset = ojj; + ptes[j+1].offset = oj; + pj = ptes[j].part_table; + set_start_sect(pj, get_start_sect(pj)+oj-ojj); + pjj = ptes[j+1].part_table; + set_start_sect(pjj, get_start_sect(pjj)+ojj-oj); + set_start_sect(ptes[j-1].ext_pointer, + ojj-extended_offset); + set_start_sect(ptes[j].ext_pointer, + oj-extended_offset); + goto stage1; + } + } + + /* Stage 2: sort starting sectors */ + stage2: + for (j = 4; j < partitions-1; j++) { + pj = ptes[j].part_table; + pjj = ptes[j+1].part_table; + sj = get_start_sect(pj); + sjj = get_start_sect(pjj); + oj = ptes[j].offset; + ojj = ptes[j+1].offset; + if (oj+sj > ojj+sjj) { + tmp = *pj; + *pj = *pjj; + *pjj = tmp; + set_start_sect(pj, ojj+sjj-oj); + set_start_sect(pjj, oj+sj-ojj); + goto stage2; + } + } + + /* Probably something was changed */ + for (j = 4; j < partitions; j++) + ptes[j].changed = 1; +} + +void dos_fix_partition_table_order(void) +{ + struct pte *pei, *pek; + int i,k; + + if (!wrong_p_order(NULL)) { + printf(_("Nothing to do. Ordering is correct already.\n\n")); + return; + } + + while ((i = wrong_p_order(&k)) != 0 && i < 4) { + /* partition i should have come earlier, move it */ + /* We have to move data in the MBR */ + struct partition *pi, *pk, *pe, pbuf; + pei = &ptes[i]; + pek = &ptes[k]; + + pe = pei->ext_pointer; + pei->ext_pointer = pek->ext_pointer; + pek->ext_pointer = pe; + + pi = pei->part_table; + pk = pek->part_table; + + memmove(&pbuf, pi, sizeof(struct partition)); + memmove(pi, pk, sizeof(struct partition)); + memmove(pk, &pbuf, sizeof(struct partition)); + + pei->changed = pek->changed = 1; + } + + if (i) + fix_chain_of_logicals(); + + printf(_("Done.\n")); + +} static const struct fdisk_label_operations dos_operations = diff --git a/fdisks/fdiskdoslabel.h b/fdisks/fdiskdoslabel.h index cf20124ca6..2737c9e689 100644 --- a/fdisks/fdiskdoslabel.h +++ b/fdisks/fdiskdoslabel.h @@ -42,6 +42,8 @@ extern void dos_init(struct fdisk_context *cxt); extern int dos_list_table(struct fdisk_context *cxt, int xtra); +extern void dos_fix_partition_table_order(void); + extern int mbr_is_valid_magic(unsigned char *b); extern void change_units(struct fdisk_context *cxt);