diff options
author | LaMont Jones <lamont@debian.org> | 2010-05-14 05:07:14 -0600 |
---|---|---|
committer | LaMont Jones <lamont@debian.org> | 2010-05-14 05:07:14 -0600 |
commit | 3cbdfd84fde6159d7778e70618fbbc8df219cafe (patch) | |
tree | e545f7d9e6b73426f590f3195f1d458f5c52d518 /fdisk | |
parent | 321ab951929f2ed871751ba8979d1136d036485a (diff) | |
parent | ab978962b15489b62f41a2ec0de4c44c9e25df6e (diff) | |
download | util-linux-old-3cbdfd84fde6159d7778e70618fbbc8df219cafe.tar.gz |
Merge remote branch 'origin/master' into HEAD
Conflicts:
lib/fsprobe.c
mount/lomount.c
Diffstat (limited to 'fdisk')
-rw-r--r-- | fdisk/Makefile.am | 4 | ||||
-rw-r--r-- | fdisk/cfdisk.c | 61 | ||||
-rw-r--r-- | fdisk/fdisk.8 | 14 | ||||
-rw-r--r-- | fdisk/fdisk.c | 373 | ||||
-rw-r--r-- | fdisk/fdisk.h | 2 | ||||
-rw-r--r-- | fdisk/fdiskbsdlabel.c | 4 | ||||
-rw-r--r-- | fdisk/fdisksunlabel.c | 24 | ||||
-rw-r--r-- | fdisk/sfdisk.c | 5 |
8 files changed, 316 insertions, 171 deletions
diff --git a/fdisk/Makefile.am b/fdisk/Makefile.am index 50f1dbe8..7b87d6cf 100644 --- a/fdisk/Makefile.am +++ b/fdisk/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am EXTRA_DIST = README.fdisk README.cfdisk sfdisk.examples partitiontype.c fdisk_common = i386_sys_types.c common.h gpt.c gpt.h \ - ../lib/blkdev.c ../lib/wholedisk.c + ../lib/blkdev.c ../lib/wholedisk.c ../lib/mbsalign.c if LINUX fdisk_common += ../lib/linux_version.c @@ -53,7 +53,7 @@ endif if USE_SLANG sbin_PROGRAMS += cfdisk dist_man_MANS += cfdisk.8 -cfdisk_SOURCES = cfdisk.c $(fdisk_common) +cfdisk_SOURCES = cfdisk.c $(fdisk_common) ../lib/mbsalign.c cfdisk_CFLAGS = $(cflags_blkid) cfdisk_LDADD = -lslang $(ldadd_blkid) else diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c index eaf766c8..b1eaceeb 100644 --- a/fdisk/cfdisk.c +++ b/fdisk/cfdisk.c @@ -83,11 +83,16 @@ #include <blkid.h> #endif +#ifdef HAVE_WIDECHAR +#include <wctype.h> +#endif + #include "nls.h" #include "blkdev.h" #include "xstrncpy.h" #include "common.h" #include "gpt.h" +#include "mbsalign.h" #ifdef __GNU__ #define DEFAULT_DEVICE "/dev/hd0" @@ -407,10 +412,10 @@ fdexit(int ret) { static int get_string(char *str, int len, char *def) { - unsigned char c; - int i = 0; - int x, y; + size_t cells = 0, i = 0; + int x, y, key; int use_def = FALSE; + wint_t c; getyx(stdscr, y, x); clrtoeol(); @@ -424,7 +429,13 @@ get_string(char *str, int len, char *def) { } refresh(); + +#if defined(HAVE_LIBNCURSESW) && defined(HAVE_WIDECHAR) + while ((key = get_wch(&c)) != ERR && + c != '\r' && c != '\n' && c != KEY_ENTER) { +#else while ((c = getch()) != '\n' && c != CR) { +#endif switch (c) { case ESC: move(y, x); @@ -433,10 +444,14 @@ get_string(char *str, int len, char *def) { return GS_ESCAPE; case DEL: case '\b': + case KEY_BACKSPACE: if (i > 0) { - str[--i] = 0; - mvaddch(y, x+i, ' '); - move(y, x+i); + cells--; + i = mbs_truncate(str, &cells); + if (i < 0) + return GS_ESCAPE; + mvaddch(y, x + cells, ' '); + move(y, x + cells); } else if (use_def) { clrtoeol(); use_def = FALSE; @@ -444,15 +459,39 @@ get_string(char *str, int len, char *def) { putchar(BELL); break; default: +#if defined(HAVE_LIBNCURSESW) && defined(HAVE_WIDECHAR) + if (i < len && iswprint(c)) { + wchar_t wc = (wchar_t) c; + char s[MB_CUR_MAX + 1]; + int sz = wctomb(s, wc); + + if (sz + i < len) { + s[sz] = '\0'; + mvaddnstr(y, x + cells, s, sz); + if (use_def) { + clrtoeol(); + use_def = FALSE; + } + memcpy(str + i, s, sz); + i += sz; + str[i] = '\0'; + cells += wcwidth(wc); + } else + putchar(BELL); + } +#else if (i < len && isprint(c)) { - mvaddch(y, x+i, c); + mvaddch(y, x + cells, c); if (use_def) { clrtoeol(); use_def = FALSE; } str[i++] = c; str[i] = 0; - } else + cells++; + } +#endif + else putchar(BELL); } refresh(); @@ -2584,6 +2623,7 @@ static void do_curses_fdisk(void) { int done = FALSE; char command; + int is_first_run = TRUE; static struct MenuItem menuMain[] = { { 'b', N_("Bootable"), N_("Toggle bootable flag of the current partition") }, @@ -2626,16 +2666,17 @@ do_curses_fdisk(void) { if (p_info[cur_part].id == FREE_SPACE) { s = ((opentype == O_RDWR) ? "hnpquW" : "hnpqu"); command = menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuMain, 10, - s, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, 0); + s, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, 5); } else if (p_info[cur_part].id > 0) { s = ((opentype == O_RDWR) ? "bdhmpqtuW" : "bdhmpqtu"); command = menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuMain, 10, - s, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, 0); + s, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, is_first_run ? 7 : 0); } else { s = ((opentype == O_RDWR) ? "hpquW" : "hpqu"); command = menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuMain, 10, s, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, 0); } + is_first_run = FALSE; switch ( command ) { case 'B': case 'b': diff --git a/fdisk/fdisk.8 b/fdisk/fdisk.8 index c04972f6..30dc9678 100644 --- a/fdisk/fdisk.8 +++ b/fdisk/fdisk.8 @@ -6,7 +6,7 @@ fdisk \- Partition table manipulator for Linux .SH SYNOPSIS .B fdisk -.RB [ \-u ] +.RB [ \-uc ] .RB [ \-b .IR sectorsize ] .RB [ \-C @@ -25,6 +25,8 @@ fdisk \- Partition table manipulator for Linux .IR partition ... .sp .B fdisk \-v +.sp +.B fdisk \-h .SH DESCRIPTION Hard disks can be divided into one or more logical disks called .IR partitions . @@ -180,7 +182,15 @@ program and Linux partitions with the Linux fdisk or Linux cfdisk program. .BI "\-b " sectorsize Specify the sector size of the disk. Valid values are 512, 1024, 2048 or 4096. (Recent kernels know the sector size. Use this only on old kernels or -to override the kernel's ideas.) +to override the kernel's ideas.) Since util-linux-ng 2.17 fdisk differentiates +between logical and physical sector size. This option changes both sector sizes to +.IB sectorsize . +.TP +.BI \-h +Print help and then exit. +.TP +.BI \-c +Switch off DOS-compatible mode. (Recommended) .TP .BI "\-C " cyls Specify the number of cylinders of the disk. diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index cc573646..0126e67b 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -25,6 +25,7 @@ #include "nls.h" #include "blkdev.h" #include "common.h" +#include "mbsalign.h" #include "fdisk.h" #include "wholedisk.h" @@ -222,7 +223,12 @@ unsigned int heads, display_in_cyl_units = 1; unsigned long long total_number_of_sectors; /* (!) 512-byte sectors */ -unsigned long io_size, alignment_offset; +unsigned long grain = DEFAULT_SECTOR_SIZE, + io_size = DEFAULT_SECTOR_SIZE, + min_io_size = DEFAULT_SECTOR_SIZE, + phy_sector_size = DEFAULT_SECTOR_SIZE, + alignment_offset; +int has_topology; #define dos_label (!sun_label && !sgi_label && !aix_label && !mac_label && !osf_label) int sun_label = 0; /* looking at sun disklabel */ @@ -237,6 +243,7 @@ jmp_buf listingbuf; void fatal(enum failure why) { char error[LINE_LENGTH], *message = error; + int rc = EXIT_FAILURE; if (listing) { close(fd); @@ -244,25 +251,23 @@ void fatal(enum failure why) { } switch (why) { + case help: + rc = EXIT_SUCCESS; case usage: message = _( -"Usage: fdisk [-b SSZ] [-u] DISK Change partition table\n" -" fdisk -l [-b SSZ] [-u] DISK List partition table(s)\n" -" fdisk -s PARTITION Give partition size(s) in blocks\n" -" fdisk -v Give fdisk version\n" -"Here DISK is something like /dev/hdb or /dev/sda\n" -"and PARTITION is something like /dev/hda7\n" -"-u: give Start and End in sector (instead of cylinder) units\n" -"-b 2048: (for certain MO disks) use 2048-byte sectors\n"); - break; - case usage2: - /* msg in cases where fdisk used to probe */ - message = _( -"Usage: fdisk [-l] [-b SSZ] [-u] device\n" -"E.g.: fdisk /dev/hda (for the first IDE disk)\n" -" or: fdisk /dev/sdc (for the third SCSI disk)\n" -" or: fdisk /dev/eda (for the first PS/2 ESDI drive)\n" -" or: fdisk /dev/rd/c0d0 or: fdisk /dev/ida/c0d0 (for RAID devices)\n" -" ...\n"); +"Usage:\n" +" fdisk [options] <disk> change partition table\n" +" fdisk [options] -l <disk> list partition table(s)\n" +" fdisk -s <partition> give partition size(s) in blocks\n" +"\nOptions:\n" +" -b <size> sector size (512, 1024, 2048 or 4096)\n" +" -c switch off DOS-compatible mode\n" +" -h print help\n" +" -u <size> give sizes in sectors instead of cylinders\n" +" -v print version\n" +" -C <number> specify the number of cylinders\n" +" -H <number> specify the number of heads\n" +" -S <number> specify the number of sectors per track\n" +"\n"); break; case unable_to_open: snprintf(error, sizeof(error), @@ -294,7 +299,7 @@ void fatal(enum failure why) { fputc('\n', stderr); fputs(message, stderr); - exit(1); + exit(rc); } static void @@ -564,9 +569,19 @@ void list_types(struct systypes *sys) i = done = 0; do { - printf("%c%2x %-15.15s", i ? ' ' : '\n', - sys[next].type, _(sys[next].name)); - next = last[i++] + done; + #define NAME_WIDTH 15 + char name[NAME_WIDTH * MB_LEN_MAX]; + size_t width = NAME_WIDTH; + + printf("%c%2x ", i ? ' ' : '\n', sys[next].type); + size_t ret = mbsalign(_(sys[next].name), name, sizeof(name), + &width, MBS_ALIGN_LEFT, 0); + if (ret == (size_t)-1 || ret >= sizeof(name)) + printf("%-15.15s", _(sys[next].name)); + else + fputs(name, stdout); + + next = last[i++] + done; if (i > 3 || next >= last[i]) { i = 0; next = ++done; @@ -637,17 +652,15 @@ test_c(char **m, char *mesg) { return val; } -#define alignment_required (io_size != sector_size) +#define alignment_required (grain != sector_size) static int lba_is_aligned(unsigned long long lba) { - unsigned long long bytes, phy_sectors; + unsigned int granularity = max(phy_sector_size, min_io_size); + unsigned long long offset = (lba << 9) & (granularity - 1); - bytes = lba * sector_size; - phy_sectors = bytes / io_size; - - return (alignment_offset + (phy_sectors * io_size) == bytes); + return !((granularity + alignment_offset - offset) & (granularity - 1)); } #define ALIGN_UP 1 @@ -657,39 +670,52 @@ lba_is_aligned(unsigned long long lba) static unsigned long long align_lba(unsigned long long lba, int direction) { - unsigned long long sects_in_phy, res; + unsigned long long res; if (lba_is_aligned(lba)) - return lba; + res = lba; + else { + unsigned long long sects_in_phy = grain / sector_size; - sects_in_phy = io_size / sector_size; + if (lba < sector_offset) + res = sector_offset; - if (lba < sects_in_phy) - /* align to the first physical sector */ - res = sects_in_phy; + else if (direction == ALIGN_UP) + res = ((lba + sects_in_phy) / sects_in_phy) * sects_in_phy; - else if (direction == ALIGN_UP) - res = ((lba + sects_in_phy) / sects_in_phy) * sects_in_phy; + else if (direction == ALIGN_DOWN) + res = (lba / sects_in_phy) * sects_in_phy; - else if (direction == ALIGN_DOWN) - res = (lba / sects_in_phy) * sects_in_phy; + else /* ALIGN_NEAREST */ + res = ((lba + sects_in_phy / 2) / sects_in_phy) * sects_in_phy; - else /* ALIGN_NEAREST */ - res = ((lba + sects_in_phy/2) / sects_in_phy) * sects_in_phy; + if (alignment_offset && !lba_is_aligned(res) && + res > alignment_offset / sector_size) { + /* + * apply alignment_offset + * + * On disk with alignment compensation physical blocks starts + * at LBA < 0 (usually LBA -1). It means we have to move LBA + * according the offset to be on the physical boundary. + */ + /* fprintf(stderr, "LBA: %llu apply alignment_offset\n", res); */ + res -= (max(phy_sector_size, min_io_size) - + alignment_offset) / sector_size; - if (alignment_offset) - /* - * apply alignment_offset - * - * On disk with alignment compensation physical blocks start - * at LBA < 0 (usually LBA -1). It means we have to move LBA - * according the offset to be on the physical boundary. - */ - res -= (io_size - alignment_offset) / sector_size; + if (direction == ALIGN_UP && res < lba) + res += sects_in_phy; + } + } - /* fprintf(stderr, "LBA %llu -align-> %llu (%s)\n", lba, res, - * lba_is_aligned(res) ? "OK" : "FALSE"); - */ + /*** + fprintf(stderr, "LBA %llu (%s) --align-(%s)--> %llu (%s)\n", + lba, + lba_is_aligned(lba) ? "OK" : "FALSE", + direction == ALIGN_UP ? "UP " : + direction == ALIGN_DOWN ? "DOWN " : "NEAREST", + res, + lba_is_aligned(res) ? "OK" : "FALSE"); + ***/ return res; } @@ -742,19 +768,6 @@ void update_units(void) } static void -warn_cylinders(void) { - if (dos_label && cylinders > 1024 && !nowarn) - fprintf(stderr, _("\n" -"The number of cylinders for this disk is set to %d.\n" -"There is nothing wrong with that, but this is larger than 1024,\n" -"and could in certain setups cause problems with:\n" -"1) software that runs at boot time (e.g., old versions of LILO)\n" -"2) booting and partitioning software from other OSs\n" -" (e.g., DOS FDISK, OS/2 FDISK)\n"), - cylinders); -} - -static void warn_limits(void) { if (total_number_of_sectors > UINT_MAX && !nowarn) { int giga = (total_number_of_sectors << 9) / 1000000000; @@ -774,28 +787,30 @@ warn_limits(void) { static void warn_alignment(void) { - if (nowarn || !alignment_required) + if (nowarn) return; - fprintf(stderr, _("\n" + if (sector_size != phy_sector_size) + fprintf(stderr, _("\n" "The device presents a logical sector size that is smaller than\n" -"the optimal I/O size (often physical sector size). Aligning to a optimal\n" -"I/O size boundary is recommended, or performance may be impacted.\n\n")); +"the physical sector size. Aligning to a physical sector (or optimal\n" +"I/O) size boundary is recommended, or performance may be impacted.\n")); - /* - * Print warning when sector_offset is not aligned for DOS mode - */ - if (alignment_offset == 0 && dos_compatible_flag && - !lba_is_aligned(sector_offset)) + if (dos_compatible_flag) { + fprintf(stderr, _("\n" +"WARNING: DOS-compatible mode is deprecated. It's strongly recommended to\n" +" switch off the mode (command 'c')")); - fprintf(stderr, _( -"WARNING: The device does not provide compensation (alignment_offset)\n" -"for DOS-compatible partitioning, but DOS-compatible mode is enabled.\n" -"Use command 'c' to switch-off DOS mode.\n\n")); + if (display_in_cyl_units) + fprintf(stderr, _(" and change display units to\n" +" sectors (command 'u').\n")); + else + fprintf(stderr, ".\n"); - if (display_in_cyl_units) - fprintf(stderr, _( -"It's recommended to change display units to sectors (command 'u').\n\n")); + } else if (display_in_cyl_units) + fprintf(stderr, _("\n" +"WARNING: cylinders as display units are deprecated. Use command 'u' to\n" +" change units to sectors.\n")); } @@ -961,29 +976,52 @@ get_topology(int fd) { #ifdef HAVE_LIBBLKID_INTERNAL blkid_probe pr; - if (user_set_sector_size) - return; pr = blkid_new_probe(); if (pr && blkid_probe_set_device(pr, fd, 0, 0) == 0) { blkid_topology tp = blkid_probe_get_topology(pr); if (tp) { + min_io_size = blkid_topology_get_minimum_io_size(tp); io_size = blkid_topology_get_optimal_io_size(tp); - if (!io_size) - io_size = blkid_topology_get_minimum_io_size(tp); + phy_sector_size = blkid_topology_get_physical_sector_size(tp); alignment_offset = blkid_topology_get_alignment_offset(tp); + + /* We assume that the device provides topology info if + * optimal_io_size is set or alignment_offset is set or + * minimum_io_size is not power of 2. + * + * See also update_sector_offset(). + */ + if (io_size || alignment_offset || + (min_io_size & (min_io_size - 1))) + has_topology = 1; + if (!io_size) + /* optimal IO is optional, default to minimum IO */ + io_size = min_io_size; } } blkid_free_probe(pr); #endif if (user_set_sector_size) - ; - else if (blkdev_get_sector_size(fd, &arg) == 0) + /* fdisk since 2.17 differentiate between logical and physical + * sectors size. For backward compatibility the + * fdisk -b <sectorsize> + * changes both, logical and physical sector size. + */ + phy_sector_size = sector_size; + + else if (blkdev_get_sector_size(fd, &arg) == 0) { sector_size = arg; + if (!phy_sector_size) + phy_sector_size = sector_size; + } + + if (!min_io_size) + min_io_size = phy_sector_size; if (!io_size) - io_size = sector_size; + io_size = min_io_size; if (sector_size != DEFAULT_SECTOR_SIZE) printf(_("Note: sector size is %d (not %d)\n"), @@ -1041,24 +1079,47 @@ get_partition_table_geometry(void) { void update_sector_offset(void) { - if (dos_compatible_flag) { - /* usually 63 sectors for classic geometry */ - sector_offset = sectors; + grain = io_size; - /* On the disks with alignment_offset the default geo.sectors - * has to be aligned to physical block boundary. Check it! - */ - if (sectors && alignment_offset && !lba_is_aligned(sectors)) - fprintf(stderr, _( - "\nWARNING: the device provides alignment_offset, but the offset does not\n" - "match with device geometry.\n\n")); - } else { + if (dos_compatible_flag) + sector_offset = sectors; /* usually 63 sectors */ + else { /* - * Align the begin of the first partition to the physical block + * Align the begin of partitions to: + * + * a) topology + * a2) alignment offset + * a1) or physical sector (minimal_io_size, aka "grain") + * + * b) or default to 1MiB (2048 sectrors, Windows Vista default) + * + * c) or for very small devices use 1 phy.sector */ - unsigned long long x = io_size / sector_size; + unsigned long long x = 0; + + if (has_topology) { + if (alignment_offset) + x = alignment_offset; + else if (io_size > 2048 * 512) + x = io_size; + } + /* default to 1MiB */ + if (!x) + x = 2048 * 512; + + sector_offset = x / sector_size; + + /* don't use huge offset on small devices */ + if (total_number_of_sectors <= sector_offset * 4) + sector_offset = phy_sector_size / sector_size; - sector_offset = align_lba(x, ALIGN_UP); + /* use 1MiB grain always when possible */ + if (grain < 2048 * 512) + grain = 2048 * 512; + + /* don't use huge grain on small devices */ + if (total_number_of_sectors <= (grain * 4 / sector_size)) + grain = phy_sector_size; } } @@ -1249,7 +1310,6 @@ got_dos_table: } } - warn_cylinders(); warn_geometry(); warn_limits(); warn_alignment(); @@ -1462,11 +1522,11 @@ read_int(unsigned int low, unsigned int dflt, unsigned int high, int -get_partition(int warn, int max) { +get_partition_dflt(int warn, int max, int dflt) { struct pte *pe; int i; - i = read_int(1, 0, max, 0, _("Partition number")) - 1; + i = read_int(1, dflt, max, 0, _("Partition number")) - 1; pe = &ptes[i]; if (warn) { @@ -1483,6 +1543,11 @@ get_partition(int warn, int max) { return i; } +int +get_partition(int warn, int max) { + return get_partition_dflt(warn, max, 0); +} + static int get_existing_partition(int warn, int max) { int pno = -1; @@ -1513,14 +1578,17 @@ static int get_nonexisting_partition(int warn, int max) { int pno = -1; int i; + int dflt = 0; for (i = 0; i < max; i++) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; if (p && is_cleared_partition(p)) { - if (pno >= 0) + if (pno >= 0) { + dflt = pno + 1; goto not_unique; + } pno = i; } } @@ -1532,7 +1600,7 @@ get_nonexisting_partition(int warn, int max) { return -1; not_unique: - return get_partition(warn, max); + return get_partition_dflt(warn, max, dflt); } const char * @@ -1751,6 +1819,9 @@ static void check_consistency(struct partition *p, int partition) { unsigned int lbc, lbh, lbs; /* logical beginning c, h, s */ unsigned int lec, leh, les; /* logical ending c, h, s */ + if (!dos_compatible_flag) + return; + if (!heads || !sectors || (partition >= 4)) return; /* do not check extended partitions */ @@ -1809,10 +1880,10 @@ static void check_consistency(struct partition *p, int partition) { } static void -check_alignment(struct partition *p, int partition) +check_alignment(unsigned long long lba, int partition) { - if (!lba_is_aligned(get_start_sect(p))) - printf(_("Partition %i does not start on optimal I/O size boundary.\n"), + if (!lba_is_aligned(lba)) + printf(_("Partition %i does not start on physical sector boundary.\n"), partition + 1); } @@ -1839,8 +1910,10 @@ list_disk_geometry(void) { str_units(PLURAL), units_per_sector, sector_size, units_per_sector * sector_size); - printf(_("Sector size (logical / optimal IO): %u bytes / %lu bytes\n"), - sector_size, io_size); + printf(_("Sector size (logical/physical): %u bytes / %lu bytes\n"), + sector_size, phy_sector_size); + printf(_("I/O size (minimum/optimal): %lu bytes / %lu bytes\n"), + min_io_size, io_size); if (alignment_offset) printf(_("Alignment offset: %lu bytes\n"), alignment_offset); if (dos_label) @@ -2051,7 +2124,7 @@ list_table(int xtra) { /* type name */ (type = partition_type(p->sys_ind)) ? type : _("Unknown")); check_consistency(p, i); - check_alignment(p, i); + check_alignment(get_partition_start(pe), i); } } @@ -2086,7 +2159,7 @@ x_list_table(int extend) { (unsigned long) get_nr_sects(p), p->sys_ind); if (p->sys_ind) { check_consistency(p, i); - check_alignment(p, i); + check_alignment(get_partition_start(pe), i); } } } @@ -2164,7 +2237,7 @@ verify(void) { p = pe->part_table; if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) { check_consistency(p, i); - check_alignment(p, i); + check_alignment(get_partition_start(pe), i); if (get_partition_start(pe) < first[i]) printf(_("Warning: bad start-of-data in " "partition %d\n"), i + 1); @@ -2273,17 +2346,16 @@ add_partition(int n, int sys) { snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); do { - unsigned long long dflt, dflt_tmp; + unsigned long long dflt, aligned; temp = start; - dflt = start = get_unused_start(n, start, first, last); /* the default sector should be aligned and unused */ do { - dflt_tmp = align_lba_in_range(dflt, start, limit); - dflt = get_unused_start(n, dflt_tmp, first, last); - } while (dflt != dflt_tmp && dflt > dflt_tmp && dflt < limit); + aligned = align_lba_in_range(dflt, dflt, limit); + dflt = get_unused_start(n, aligned, first, last); + } while (dflt != aligned && dflt > aligned && dflt < limit); if (dflt >= limit) dflt = start; @@ -2590,7 +2662,8 @@ static void move_begin(int i) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; - unsigned int new, first; + unsigned int new, free_start, curr_start, last; + int x; if (warn_geometry()) return; @@ -2598,13 +2671,37 @@ move_begin(int i) { printf(_("Partition %d has no data area\n"), i + 1); return; } - first = get_partition_start(pe); - new = read_int(first, first, first + get_nr_sects(p) - 1, first, + + /* the default start is at the second sector of the disk or at the + * second sector of the extended partition + */ + free_start = pe->offset ? pe->offset + 1 : 1; + + curr_start = get_partition_start(pe); + + /* look for a free space before the current start of the partition */ + for (x = 0; x < partitions; x++) { + unsigned int end; + struct pte *prev_pe = &ptes[x]; + struct partition *prev_p = prev_pe->part_table; + + if (!prev_p) + continue; + end = get_partition_start(prev_pe) + get_nr_sects(prev_p); + + if (!is_cleared_partition(prev_p) && + end > free_start && end <= curr_start) + free_start = end; + } + + last = get_partition_start(pe) + get_nr_sects(p) - 1; + + new = read_int(free_start, curr_start, last, free_start, _("New beginning of data")) - pe->offset; if (new != get_nr_sects(p)) { - first = get_nr_sects(p) + get_start_sect(p) - new; - set_nr_sects(p, first); + unsigned int sects = get_nr_sects(p) + get_start_sect(p) - new; + set_nr_sects(p, sects); set_start_sect(p, new); pe->changed = 1; } @@ -2632,8 +2729,6 @@ xselect(void) { _("Number of cylinders")); if (sun_label) sun_set_ncyl(cylinders); - if (dos_label) - warn_cylinders(); break; case 'd': print_raw(); @@ -2830,17 +2925,7 @@ main(int argc, char **argv) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - /* - * Calls: - * fdisk -v - * fdisk -l [-b sectorsize] [-u] device ... - * fdisk -s [partition] ... - * fdisk [-b sectorsize] [-u] device - * - * Options -C, -H, -S set the geometry. - * - */ - while ((c = getopt(argc, argv, "b:C:H:lsS:uvV")) != -1) { + while ((c = getopt(argc, argv, "b:cC:hH:lsS:uvV")) != -1) { switch (c) { case 'b': /* Ugly: this sector size is really per device, @@ -2857,6 +2942,12 @@ main(int argc, char **argv) { case 'C': user_cylinders = atoi(optarg); break; + case 'c': + dos_compatible_flag = 0; + break; + case 'h': + fatal(help); + break; case 'H': user_heads = atoi(optarg); if (user_heads <= 0 || user_heads > 256) @@ -2942,10 +3033,8 @@ main(int argc, char **argv) { if (argc-optind == 1) disk_device = argv[optind]; - else if (argc-optind != 0) - fatal(usage); else - fatal(usage2); + fatal(usage); gpt_warning(disk_device); get_boot(fdisk); diff --git a/fdisk/fdisk.h b/fdisk/fdisk.h index 0286ce0a..1a89beb9 100644 --- a/fdisk/fdisk.h +++ b/fdisk/fdisk.h @@ -45,7 +45,7 @@ struct partition { unsigned char size4[4]; /* nr of sectors in partition */ } PACKED; -enum failure {usage, usage2, ioctl_error, +enum failure {help, usage, ioctl_error, unable_to_open, unable_to_read, unable_to_seek, unable_to_write, out_of_memory}; diff --git a/fdisk/fdiskbsdlabel.c b/fdisk/fdiskbsdlabel.c index 2f415616..9c092524 100644 --- a/fdisk/fdiskbsdlabel.c +++ b/fdisk/fdiskbsdlabel.c @@ -540,7 +540,7 @@ xbsd_write_bootstrap (void) memmove (&dl, d, sizeof (struct xbsd_disklabel)); /* The disklabel will be overwritten by 0's from bootxx anyway */ - bzero (d, sizeof (struct xbsd_disklabel)); + memset (d, 0, sizeof (struct xbsd_disklabel)); snprintf (path, sizeof(path), "%s/boot%s", bootdir, dkbasename); if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize], @@ -656,7 +656,7 @@ xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex) { struct geom g; get_geometry (fd, &g); - bzero (d, sizeof (struct xbsd_disklabel)); + memset (d, 0, sizeof (struct xbsd_disklabel)); d -> d_magic = BSD_DISKMAGIC; diff --git a/fdisk/fdisksunlabel.c b/fdisk/fdisksunlabel.c index 670a15a5..68596eea 100644 --- a/fdisk/fdisksunlabel.c +++ b/fdisk/fdisksunlabel.c @@ -146,17 +146,17 @@ int check_sun_label(void) if (sunlabel->version != SSWAP32(SUN_LABEL_VERSION)) { fprintf(stderr,_("Detected sun disklabel with wrong version [0x%08x].\n"), - sunlabel->version); + SSWAP32(sunlabel->version)); need_fixing = 1; } if (sunlabel->sanity != SSWAP32(SUN_LABEL_SANE)) { fprintf(stderr,_("Detected sun disklabel with wrong sanity [0x%08x].\n"), - sunlabel->sanity); + SSWAP32(sunlabel->sanity)); need_fixing = 1; } if (sunlabel->num_partitions != SSWAP16(SUN_NUM_PARTITIONS)) { fprintf(stderr,_("Detected sun disklabel with wrong num_partitions [%u].\n"), - sunlabel->num_partitions); + SSWAP16(sunlabel->num_partitions)); need_fixing = 1; } if (need_fixing) { @@ -186,8 +186,8 @@ void create_sunlabel(void) { struct hd_geometry geometry; unsigned long long llsectors, llcyls; - unsigned int ndiv; - int res, sec_fac; + unsigned int ndiv, sec_fac; + int res; fprintf(stderr, _("Building a new sun disklabel. Changes will remain in memory only,\n" @@ -573,8 +573,8 @@ void sun_list_table(int xtra) w = strlen(disk_device); if (xtra) printf( - _("\nDisk %s (Sun disk label): %d heads, %llu sectors, %d rpm\n" - "%d cylinders, %d alternate cylinders, %d physical cylinders\n" + _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %d rpm\n" + "%u cylinders, %d alternate cylinders, %d physical cylinders\n" "%d extra sects/cyl, interleave %d:1\n" "Label ID: %s\n" "Volume ID: %s\n" @@ -589,7 +589,7 @@ void sun_list_table(int xtra) str_units(PLURAL), units_per_sector); else printf( - _("\nDisk %s (Sun disk label): %d heads, %llu sectors, %d cylinders\n" + _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %u cylinders\n" "Units = %s of %d * 512 bytes\n\n"), disk_device, heads, sectors, cylinders, str_units(PLURAL), units_per_sector); @@ -604,13 +604,13 @@ void sun_list_table(int xtra) uint32_t start = SSWAP32(part->start_cylinder) * heads * sectors; uint32_t len = SSWAP32(part->num_sectors); printf( - "%s %c%c %9ld %9ld %9ld%c %2x %s\n", + "%s %c%c %9lu %9lu %9lu%c %2x %s\n", /* device */ partname(disk_device, i+1, w), /* flags */ (tag->flag & SSWAP16(SUN_FLAG_UNMNT)) ? 'u' : ' ', (tag->flag & SSWAP16(SUN_FLAG_RONLY)) ? 'r' : ' ', -/* start */ (long) scround(start), -/* end */ (long) scround(start+len), -/* odd flag on end */ (long) len / 2, len & 1 ? '+' : ' ', +/* start */ (unsigned long) scround(start), +/* end */ (unsigned long) scround(start+len), +/* odd flag on end */ (unsigned long) len / 2, len & 1 ? '+' : ' ', /* type id */ SSWAP16(tag->tag), /* type name */ (type = partition_type(SSWAP16(tag->tag))) ? type : _("Unknown")); diff --git a/fdisk/sfdisk.c b/fdisk/sfdisk.c index 6ac91f07..6432b25c 100644 --- a/fdisk/sfdisk.c +++ b/fdisk/sfdisk.c @@ -1637,6 +1637,11 @@ write_partitions(char *dev, int fd, struct disk_desc *z) { error(_("Failed writing the partition on %s\n"), dev); return 0; } + if (fsync(fd)) { + perror(dev); + error(_("Failed writing the partition on %s\n"), dev); + return 0; + } return 1; } |