]> err.no Git - util-linux/commitdiff
fdisk: offer aligned first sector
authorKarel Zak <kzak@redhat.com>
Wed, 4 Nov 2009 14:14:04 +0000 (15:14 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 18 Nov 2009 10:25:10 +0000 (11:25 +0100)
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>
fdisk/fdisk.c

index 32032a3ced6f0b09f797460ce9a4781d157e3431..19bbab5b9dbb36f4cfe7c699b6bf58743acde7a1 100644 (file)
@@ -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;