Skip to content

Commit

Permalink
libfdisk: (gpt) don't offer first sector before the first partion
Browse files Browse the repository at this point in the history
The GPT first usable LBA is usually aligned to grain (1MiB), but for small
(<=4MiB) devices we strictly follow sector sizes.

In this case there is a small space in front of the aligned begin of
the first partition. This useless space should not be offered for the
next partitions.

	Sector size (logical/physical): 512 bytes / 4096 bytes
	I/O size (minimum/optimal): 4096 bytes / 32768 bytes
	Disklabel type: gpt
	Disk identifier: 041E2D54-AD0C-4C7E-A50D-363D23058D47

	Device    Start          End Size Type
	/dev/sdb1    40         2087   1M Linux filesystem

	Command (m for help): n
	Partition number (2-128, default 2):
	First sector (34-8158, default 2088):
                      ^^

first usable LBA is 34, but first aligned (recommended) LBA is 40, we
use it for the first partition. All this is correct, but the space
before the first partition should be ignored. Fixed version:

        Command (m for help): n
	Partition number (2-128, default 2):
	First sector (2088-8158, default 2088):
                      ^^^^

Note this problem does not exist for "normal" (large) devices where
first usable LBA is aligned to grain.

Reported-by: Boaz Harrosh <boaz@plexistor.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
  • Loading branch information
karelzak committed Nov 10, 2014
1 parent 8ccfcf7 commit 4a4616b
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion libfdisk/src/gpt.c
Expand Up @@ -1945,7 +1945,31 @@ static int gpt_add_partition(
pa->type->typestr:
GPT_DEFAULT_ENTRY_TYPE, &typeid);

disk_f = find_first_available(pheader, ents, 0);
disk_f = find_first_available(pheader, ents, pheader->first_usable_lba);

/* if first sector no explicitly defined then ignore small gaps before
* the first partition */
if ((!pa || !fdisk_partition_has_start(pa))
&& !partition_unused(&ents[0])
&& disk_f < gpt_partition_start(&ents[0])) {

do {
uint64_t x;
DBG(LABEL, ul_debug("testing first sector %ju", disk_f));
disk_f = find_first_available(pheader, ents, disk_f);
if (!disk_f)
break;
x = find_last_free(pheader, ents, disk_f);
if (x - disk_f >= cxt->grain / cxt->sector_size)
break;
DBG(LABEL, ul_debug("first sector %ju addresses to small space, continue...", disk_f));
disk_f = x + 1;
} while(1);

if (disk_f == 0)
disk_f = find_first_available(pheader, ents, pheader->first_usable_lba);
}

disk_l = find_last_free_sector(pheader, ents);

/* the default is the largest free space */
Expand Down

0 comments on commit 4a4616b

Please sign in to comment.