📄 fdisk.c
字号:
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 voidfix_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 voidlist_table(int xtra) { struct partition *p; char *type; int i, w; if (sun_label) { sun_list_table(xtra); return; } if (sgi_label) { sgi_list_table(xtra); return; } list_disk_geometry(); if (osf_label) { xbsd_print_disklabel(xtra); return; } if (is_garbage_table()) { printf(_("This doesn't look like a partition table\n" "Probably you selected the wrong device.\n\n")); } /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3, but if the device name ends in a digit, say /dev/foo1, then the partition is called /dev/foo1p3. */ w = strlen(disk_device); if (w && isdigit(disk_device[w-1])) w++; if (w < 5) w = 5; printf(_("%*s Boot Start End Blocks Id System\n"), w+1, _("Device")); for (i = 0; i < partitions; i++) { struct pte *pe = &ptes[i]; p = pe->part_table; if (p && !is_cleared_partition(p)) { unsigned int psects = get_nr_sects(p); unsigned int pblocks = psects; unsigned int podd = 0; if (sector_size < 1024) { pblocks /= (1024 / sector_size); podd = psects % (1024 / sector_size); } if (sector_size > 1024) pblocks *= (sector_size / 1024); printf( "%s %c %11lu %11lu %11lu%c %2x %s\n", partname(disk_device, i+1, w+2),/* boot flag */ !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG ? '*' : '?',/* start */ (unsigned long) cround(get_partition_start(pe)),/* end */ (unsigned long) cround(get_partition_start(pe) + psects - (psects ? 1 : 0)),/* odd flag on end */ (unsigned long) pblocks, podd ? '+' : ' ',/* type id */ p->sys_ind,/* type name */ (type = partition_type(p->sys_ind)) ? type : _("Unknown")); check_consistency(p, i); } } /* Is partition table in disk order? It need not be, but... */ /* partition table entries are not checked for correct order if this is a sgi, sun or aix labeled disk... */ if (dos_label && wrong_p_order(NULL)) { printf(_("\nPartition table entries are not in disk order\n")); }}static voidx_list_table(int extend) { struct pte *pe; struct partition *p; int i; printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n"), disk_device, heads, sectors, cylinders); printf(_("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n")); for (i = 0 ; i < partitions; i++) { pe = &ptes[i]; p = (extend ? pe->ext_pointer : pe->part_table); if (p != NULL) { printf("%2d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n", i + 1, p->boot_ind, p->head, sector(p->sector), cylinder(p->sector, p->cyl), p->end_head, sector(p->end_sector), cylinder(p->end_sector, p->end_cyl), get_start_sect(p), get_nr_sects(p), p->sys_ind); if (p->sys_ind) check_consistency(p, i); } }}static voidfill_bounds(unsigned int *first, unsigned int *last) { int i; struct pte *pe = &ptes[0]; struct partition *p; for (i = 0; i < partitions; pe++,i++) { p = pe->part_table; if (!p->sys_ind || IS_EXTENDED (p->sys_ind)) { first[i] = 0xffffffff; last[i] = 0; } else { first[i] = get_partition_start(pe); last[i] = first[i] + get_nr_sects(p) - 1; } }}static voidcheck(int n, unsigned int h, unsigned int s, unsigned int c, unsigned int start) { unsigned int total, real_s, real_c; real_s = sector(s) - 1; real_c = cylinder(s, c); total = (real_c * sectors + real_s) * heads + h; if (!total) fprintf(stderr, _("Warning: partition %d contains sector 0\n"), n); if (h >= heads) fprintf(stderr, _("Partition %d: head %d greater than maximum %d\n"), n, h + 1, heads); if (real_s >= sectors) fprintf(stderr, _("Partition %d: sector %d greater than " "maximum %d\n"), n, s, sectors); if (real_c >= cylinders) fprintf(stderr, _("Partitions %d: cylinder %d greater than " "maximum %d\n"), n, real_c + 1, cylinders); if (cylinders <= 1024 && start != total) fprintf(stderr, _("Partition %d: previous sectors %d disagrees with " "total %d\n"), n, start, total);}static voidverify(void) { int i, j; unsigned int total = 1; unsigned int first[partitions], last[partitions]; struct partition *p; if (warn_geometry()) return; if (sun_label) { verify_sun(); return; } if (sgi_label) { verify_sgi(1); return; } fill_bounds(first, last); for (i = 0; i < partitions; i++) { struct pte *pe = &ptes[i]; p = pe->part_table; if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) { check_consistency(p, i); if (get_partition_start(pe) < first[i]) printf(_("Warning: bad start-of-data in " "partition %d\n"), i + 1); check(i + 1, p->end_head, p->end_sector, p->end_cyl, last[i]); total += last[i] + 1 - first[i]; for (j = 0; j < i; j++) if ((first[i] >= first[j] && first[i] <= last[j]) || ((last[i] <= last[j] && last[i] >= first[j]))) { printf(_("Warning: partition %d overlaps " "partition %d.\n"), j + 1, i + 1); total += first[i] >= first[j] ? first[i] : first[j]; total -= last[i] <= last[j] ? last[i] : last[j]; } } } if (extended_offset) { struct pte *pex = &ptes[ext_index]; unsigned int e_last = get_start_sect(pex->part_table) + get_nr_sects(pex->part_table) - 1; for (i = 4; i < partitions; i++) { total++; p = ptes[i].part_table; if (!p->sys_ind) { if (i != 4 || i + 1 < partitions) printf(_("Warning: partition %d " "is empty\n"), i + 1); } else if (first[i] < extended_offset || last[i] > e_last) printf(_("Logical partition %d not entirely in " "partition %d\n"), i + 1, ext_index + 1); } } if (total > total_number_of_sectors) printf(_("Total allocated sectors %d greater than the maximum " "%lld\n"), total, total_number_of_sectors); else if (total < total_number_of_sectors) printf(_("%lld unallocated sectors\n"), total_number_of_sectors - total);}static voidadd_partition(int n, int sys) { char mesg[256]; /* 48 does not suffice in Japanese */ int i, read = 0; struct partition *p = ptes[n].part_table; struct partition *q = ptes[ext_index].part_table; long long llimit; unsigned int start, stop = 0, limit, temp, first[partitions], last[partitions]; if (p && p->sys_ind) { printf(_("Partition %d is already defined. Delete " "it before re-adding it.\n"), n + 1); return; } fill_bounds(first, last); if (n < 4) { start = sector_offset; if (display_in_cyl_units || !total_number_of_sectors) llimit = heads * sectors * cylinders - 1; else llimit = total_number_of_sectors - 1; limit = llimit; if (limit != llimit) limit = 0x7fffffff; if (extended_offset) { first[ext_index] = extended_offset; last[ext_index] = get_start_sect(q) + get_nr_sects(q) - 1; } } else { start = extended_offset + sector_offset; limit = get_start_sect(q) + get_nr_sects(q) - 1; } if (display_in_cyl_units) for (i = 0; i < partitions; i++) first[i] = (cround(first[i]) - 1) * units_per_sector; snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); do { temp = start; for (i = 0; i < partitions; i++) { int lastplusoff; if (start == ptes[i].offset) start += sector_offset; lastplusoff = last[i] + ((n<4) ? 0 : sector_offset); if (start >= first[i] && start <= lastplusoff) start = lastplusoff + 1; } if (start > limit) break; if (start >= temp+units_per_sector && read) { printf(_("Sector %d is already allocated\n"), temp); temp = start; read = 0; } if (!read && start == temp) { unsigned int i = start; start = read_int(cround(i), cround(i), cround(limit), 0, mesg); if (display_in_cyl_units) { start = (start - 1) * units_per_sector; if (start < i) start = i; } read = 1; } } while (start != temp || !read); if (n > 4) { /* NOT for fifth partition */ struct pte *pe = &ptes[n]; pe->offset = start - sector_offset; if (pe->offset == extended_offset) { /* must be corrected */ pe->offset++; if (sector_offset == 1) start++; } } for (i = 0; i < partitions; i++) { struct pte *pe = &ptes[i]; if (start < pe->offset && limit >= pe->offset) limit = pe->offset - 1; if (start < first[i] && limit >= first[i]) limit = first[i] - 1; } if (start > limit) { printf(_("No free sectors available\n")); if (n > 4) partitions--; return; } if (cround(start) == cround(limit)) { stop = limit; } else { snprintf(mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"), str_units(SINGULAR)); stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg); if (display_in_cyl_units) { stop = stop * units_per_sector - 1; if (stop >limit) stop = limit; } } set_partition(n, 0, start, stop, sys); if (n > 4) set_partition(n - 1, 1, ptes[n].offset, stop, EXTENDED); if (IS_EXTENDED (sys)) { struct pte *pe4 = &ptes[4]; struct pte *pen = &ptes[n]; ext_index = n; pen->ext_pointer = p; pe4->offset = extended_offset = start; if (!(pe4->sectorbuffer = calloc(1, sector_size))) fatal(out_of_memory); pe4->part_table = pt_offset(pe4->sectorbuffer, 0); pe4->ext_pointer = pe4->part_table + 1; pe4->changed = 1; partitions = 5; }}static voidadd_logical(void) { if (partitions > 5 || ptes[4].part_table->sys_ind) { struct pte *pe = &ptes[partitions]; if (!(pe->sectorbuffer = calloc(1, sector_size))) fatal(out_of_memory); pe->part_table = pt_offset(pe->sectorbuffer, 0); pe->ext_pointer = pe->part_table + 1; pe->offset = 0; pe->changed = 1; partitions++; } add_partition(partitions - 1, LINUX_NATIVE);}static voidnew_partition(void) { int i, free_primary = 0; if (warn_geometry()) return; if (sun_label) { add_sun_partition(get_partition(0, partitions), LINUX_NATIVE); return; } if (sgi_label) { sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE); return; } if (aix_label) { printf(_("\tSorry - this fdisk cannot handle AIX disk labels." "\n\tIf you want to add DOS-type partitions, create" "\n\ta new empty DOS partition table first. (Use o.)" "\n\tWARNING: " "This will destroy the present disk contents.\n")); return; } for (i = 0; i < 4; i++) free_primary += !ptes[i].part_table->sys_ind; if (!free_primary && partitions >= MAXIMUM_PARTS) { printf(_("The maximum number of partitions has been created\n")); return; } if (!free_primary) { if (extended_offset) add_logical(); else printf(_("You must delete some partition and add " "an extended partition first\n")); } else if (partitions >= MAXIMUM_PARTS) { printf(_("All logical partitions are in use\n")); printf(_("Adding a primary partition\n")); add_partition(get_partition(0, 4), LINUX_NATIVE); } else { char c, line[LINE_LENGTH]; snprintf(line, sizeof(line), _("Command action\n %s\n p primary " "partition (1-4)\n"), extended_offset ? _("l logical (5 or over)") : _("e extended")); while (1) { if ((c = tolower(read_char(line))) == 'p') { int i = get_nonexisting_partition(0, 4); if (i >= 0) add_partition(i, LINUX_NATIVE); return; } else if (c == 'l' && extended_offset) { add_logical(); return; } else if (c == 'e' && !extended_offset) { int i = get_nonexisting_partition(0, 4); if (i >= 0) add_partition(i, EXTENDED); return; } else printf(_("Invalid partition number " "for type `%c'\n"), c); } }}static voidwrite_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++) { struct pte *pe = &ptes[i]; if (pe->changed) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -