summaryrefslogtreecommitdiffstats
path: root/fdisk/fdisk.c
diff options
context:
space:
mode:
authorKarel Zak2009-11-04 15:14:04 +0100
committerKarel Zak2009-11-18 11:25:10 +0100
commit81dc64f8c0e101ea9389d17df03b4a4e208b92e7 (patch)
treeacdd6c67b510f6570b7f234ad8d62e5c17013dd4 /fdisk/fdisk.c
parentfdisk: align end of partition when defined by +size{K,M,G} (diff)
downloadkernel-qcow2-util-linux-81dc64f8c0e101ea9389d17df03b4a4e208b92e7.tar.gz
kernel-qcow2-util-linux-81dc64f8c0e101ea9389d17df03b4a4e208b92e7.tar.xz
kernel-qcow2-util-linux-81dc64f8c0e101ea9389d17df03b4a4e208b92e7.zip
fdisk: offer aligned first sector
Typical "new partition" dialog looks like: Partition number (1-4): 1 First sector (4-818687, default 4): ^^^^^^^^^ The range (e.g. 4-818687) depends on fdisk mode (DOS/non-DOS), but the default value should be always aligned. For example RAID5 device in the DOS mode: Disk /dev/md0: 419 MB, 419168256 bytes 2 heads, 4 sectors/track, 102336 cylinders, total 818688 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 65536 bytes Disk identifier: 0x081479c3 .... Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First sector (4-818687, default 128): <---- !!! Using default value 128 Last sector, +sectors or +size{K,M,G} (128-818687, default 818687): +10M Command (m for help): p .... Device Boot Start End Blocks Id System /dev/md0p1 128 20607 10240 83 Linux For non-DOS mode the range will be: First sector (128-818687, default 128): Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'fdisk/fdisk.c')
-rw-r--r--fdisk/fdisk.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c
index 32032a3ce..19bbab5b9 100644
--- a/fdisk/fdisk.c
+++ b/fdisk/fdisk.c
@@ -2210,6 +2210,27 @@ verify(void) {
n_sectors - total, sector_size);
}
+static unsigned long long
+get_unused_start(int part_n,
+ unsigned long long start,
+ unsigned long long first[],
+ unsigned long long last[])
+{
+ int i;
+
+ for (i = 0; i < partitions; i++) {
+ unsigned long long lastplusoff;
+
+ if (start == ptes[i].offset)
+ start += sector_offset;
+ lastplusoff = last[i] + ((part_n < 4) ? 0 : sector_offset);
+ if (start >= first[i] && start <= lastplusoff)
+ start = lastplusoff + 1;
+ }
+
+ return start;
+}
+
static void
add_partition(int n, int sys) {
char mesg[256]; /* 48 does not suffice in Japanese */
@@ -2250,16 +2271,20 @@ add_partition(int n, int sys) {
snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
do {
+ unsigned long long dflt, dflt_tmp;
+
temp = start;
- for (i = 0; i < partitions; i++) {
- unsigned long long 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;
- }
+
+ 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);
+
+ if (dflt >= limit)
+ dflt = start;
if (start > limit)
break;
if (start >= temp+units_per_sector && read) {
@@ -2270,7 +2295,7 @@ add_partition(int n, int sys) {
if (!read && start == temp) {
unsigned long long i = start;
- start = read_int(cround(i), cround(i), cround(limit),
+ start = read_int(cround(i), cround(dflt), cround(limit),
0, mesg);
if (display_in_cyl_units) {
start = (start - 1) * units_per_sector;