summaryrefslogtreecommitdiffstats
path: root/fdisks
diff options
context:
space:
mode:
authorKarel Zak2012-12-04 17:54:15 +0100
committerKarel Zak2012-12-04 17:54:15 +0100
commit512a430fe7acf705880eaddb887653b79f8dc223 (patch)
treea3e1a0b7935bd6d06df6a27af995c8fc599d8f58 /fdisks
parentfdisk: (gpt) fix {last,first}_usable_lba usage (diff)
downloadkernel-qcow2-util-linux-512a430fe7acf705880eaddb887653b79f8dc223.tar.gz
kernel-qcow2-util-linux-512a430fe7acf705880eaddb887653b79f8dc223.tar.xz
kernel-qcow2-util-linux-512a430fe7acf705880eaddb887653b79f8dc223.zip
fdisk: (gpt) align newly created partitions
- default "First sector" has to be aligned - "Last sector" has to be aligned if specified by +<size><suffix> convention Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'fdisks')
-rw-r--r--fdisks/fdisk.c16
-rw-r--r--fdisks/fdisk.h1
-rw-r--r--fdisks/fdiskdoslabel.c15
-rw-r--r--fdisks/gpt.c64
4 files changed, 61 insertions, 35 deletions
diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c
index 7c3fee4b8..dd06b9b22 100644
--- a/fdisks/fdisk.c
+++ b/fdisks/fdisk.c
@@ -352,6 +352,22 @@ sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction)
return res;
}
+
+sector_t align_lba_in_range(struct fdisk_context *cxt,
+ sector_t lba, sector_t start, sector_t stop)
+{
+ start = align_lba(cxt, start, ALIGN_UP);
+ stop = align_lba(cxt, stop, ALIGN_DOWN);
+
+ lba = align_lba(cxt, lba, ALIGN_NEAREST);
+
+ if (lba < start)
+ return start;
+ else if (lba > stop)
+ return stop;
+ return lba;
+}
+
int warn_geometry(struct fdisk_context *cxt)
{
char *m = NULL;
diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h
index 15cae812b..3cb04993e 100644
--- a/fdisks/fdisk.h
+++ b/fdisks/fdisk.h
@@ -282,6 +282,7 @@ extern unsigned int read_int_with_suffix(struct fdisk_context *cxt,
unsigned int low, unsigned int dflt, unsigned int high,
unsigned int base, char *mesg, int *is_suffix_used);
extern sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction);
+extern sector_t align_lba_in_range(struct fdisk_context *cxt, sector_t lba, sector_t start, sector_t stop);
extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt);
#define PLURAL 0
diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c
index 897bc0e1b..ab940a010 100644
--- a/fdisks/fdiskdoslabel.c
+++ b/fdisks/fdiskdoslabel.c
@@ -541,21 +541,6 @@ static sector_t get_unused_start(struct fdisk_context *cxt,
return start;
}
-static sector_t align_lba_in_range(struct fdisk_context *cxt,
- sector_t lba, sector_t start, sector_t stop)
-{
- start = align_lba(cxt, start, ALIGN_UP);
- stop = align_lba(cxt, stop, ALIGN_DOWN);
-
- lba = align_lba(cxt, lba, ALIGN_NEAREST);
-
- if (lba < start)
- return start;
- else if (lba > stop)
- return stop;
- return lba;
-}
-
static int add_partition(struct fdisk_context *cxt, int n, struct fdisk_parttype *t)
{
char mesg[256]; /* 48 does not suffice in Japanese */
diff --git a/fdisks/gpt.c b/fdisks/gpt.c
index 2a6498361..a22200272 100644
--- a/fdisks/gpt.c
+++ b/fdisks/gpt.c
@@ -984,8 +984,10 @@ static uint64_t get_free_sectors(struct fdisk_context *cxt, struct gpt_header *h
} while (first_sect);
done:
- *nsegments = num;
- *largest_segment = largest_seg;
+ if (nsegments)
+ *nsegments = num;
+ if (largest_segment)
+ *largest_segment = largest_seg;
return totfound;
}
@@ -1481,10 +1483,9 @@ static int gpt_create_new_partition(int partnum, uint64_t fsect, uint64_t lsect,
static int gpt_add_partition(struct fdisk_context *cxt, int partnum,
struct fdisk_parttype *t)
{
- char msg[256];
- uint32_t tmp;
- uint64_t f0, f1; /* user input ranges for first and last sectors */
- uint64_t def_sect, first_sect, last_sect; /* first and last available sector ranges */
+ uint64_t user_f, user_l; /* user input ranges for first and last sectors */
+ uint64_t disk_f, disk_l; /* first and last available sector ranges on device*/
+ uint64_t dflt_f, dflt_l; /* largest segment (default) */
struct gpt_guid uuid = GPT_DEFAULT_ENTRY_GUID;
/* check basic tests before even considering adding a new partition */
@@ -1500,32 +1501,55 @@ static int gpt_add_partition(struct fdisk_context *cxt, int partnum,
return -EINVAL;
}
- if (!get_free_sectors(cxt, pheader, ents, &tmp, &f0)) {
+ if (!get_free_sectors(cxt, pheader, ents, NULL, NULL)) {
printf(_("No free sectors available.\n"));
return -ENOSPC;
}
- first_sect = find_first_available(pheader, ents, 0);
- last_sect = find_last_free_sector(pheader, ents);
- def_sect = find_first_in_largest(pheader, ents);
+ disk_f = find_first_available(pheader, ents, 0);
+ disk_l = find_last_free_sector(pheader, ents);
+
+ /* the default is the largest free space */
+ dflt_f = find_first_in_largest(pheader, ents);
+ dflt_l = find_last_free(pheader, ents, dflt_f);
+
+ /* align the default in range <dflt_f,dflt_l>*/
+ dflt_f = align_lba_in_range(cxt, dflt_f, dflt_f, dflt_l);
if (t && t->typestr)
string_to_uuid(t->typestr, &uuid);
/* get user input for first and last sectors of the new partition */
- snprintf(msg, sizeof(msg), _("First %s"), str_units(SINGULAR));
for (;;) {
- f0 = read_int(cxt, first_sect, def_sect, last_sect, 0, msg);
- if (f0 >= first_sect && f0 <= last_sect) {
- last_sect = find_last_free(pheader, ents, f0);
- snprintf(msg, sizeof(msg), _("Last %s"), str_units(SINGULAR));
- f1 = read_int(cxt, f0, last_sect, last_sect, 0, msg);
- if (f1 >= f0 && f1 <= last_sect)
- break;
- }
+ int is_suffix_used = 0;
+
+ /* first sector */
+ user_f = read_int(cxt, disk_f, /* minimal */
+ dflt_f, /* default */
+ disk_l, /* maximal */
+ 0, _("First sector"));
+
+ if (user_f < disk_f || user_f > disk_l)
+ continue;
+
+ /* Last sector */
+ dflt_l = find_last_free(pheader, ents, user_f);
+ user_l = read_int_with_suffix(cxt,
+ user_f, /* minimal */
+ dflt_l, /* default */
+ dflt_l, /* maximal */
+ user_f, /* base for relative input */
+ _("Last sector, +sectors or +size{K,M,G}"),
+ &is_suffix_used);
+
+ if (is_suffix_used)
+ user_l = align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1;
+
+ if (user_l > user_f && user_l <= disk_l)
+ break;
}
- if (gpt_create_new_partition(partnum, f0, f1, &uuid, ents) != 0)
+ if (gpt_create_new_partition(partnum, user_f, user_l, &uuid, ents) != 0)
printf(_("Could not create partition %d\n"), partnum + 1);
else
printf(_("Created partition %d\n"), partnum + 1);