[PATCH 18/26] partitions: use byte offset for first partition policy

Ahmad Fatoum a.fatoum at barebox.org
Fri Jun 26 01:42:29 PDT 2026


global.partitions.first_usable_lba was added to keep some initial free
space for the bootloader image before partitions begin.

As the name suggests, the unit is sectors, which is not so useful, the
next most common sector size after 512 is 4K, so the default 8 MiB
partition offset becomes 64M, which is quite a bit of waste.

Replace it with global.partitions.first_partition_offset, which has a
unit of bytes instead.

Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
---
 .../migration-guides/migration-master.rst     | 11 ++++++
 common/partitions.c                           | 37 +++++++++----------
 common/partitions/efi.c                       |  2 +-
 include/partitions.h                          |  2 +-
 4 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/Documentation/migration-guides/migration-master.rst b/Documentation/migration-guides/migration-master.rst
index 455863357d1d..d2499fb799bd 100644
--- a/Documentation/migration-guides/migration-master.rst
+++ b/Documentation/migration-guides/migration-master.rst
@@ -6,3 +6,14 @@ ARCH=arm64
 Use of ``ARCH=arm`` for 64-bit ARM builds is deprecated and now emits
 a warning. Users should change build scripts to use ``ARCH=arm64``
 instead when targetting ARMv8.
+
+global.partitions.first_usable_lba removed
+------------------------------------------
+
+The ``global.partitions.first_usable_lba`` variable has been removed.
+Use ``global.partitions.first_partition_offset`` instead.
+
+The new variable is a byte offset used by free-space searches for new
+partitions, for example ``parted mkpart_size``. The default is
+``8388608`` bytes (8 MiB). To keep an old configuration, multiply the
+old ``first_usable_lba`` value by 512.
diff --git a/common/partitions.c b/common/partitions.c
index ff977516aa1f..8637b54b1708 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -22,6 +22,7 @@
 #include <magicvar.h>
 
 static LIST_HEAD(partition_parser_list);
+static uint64_t first_partition_offset = SZ_8M;
 
 /**
  * Register one partition on the given block device
@@ -203,12 +204,12 @@ bool partition_is_free(struct partition_desc *pdesc, uint64_t start, uint64_t si
 int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, uint64_t *start)
 {
 	struct partition *p;
-	uint64_t min_sec = PARTITION_ALIGN_SECTORS;
+	uint64_t align = PARTITION_ALIGN_SECTORS;
+	uint64_t min_sec;
 
-	if (min_sec < partition_first_usable_lba())
-		min_sec = partition_first_usable_lba();
+	min_sec = max(align, partition_first_usable_lba(pdesc->blk));
 
-	min_sec = ALIGN(min_sec, PARTITION_ALIGN_SECTORS);
+	min_sec = ALIGN(min_sec, align);
 
 	if (partition_is_free(pdesc, min_sec, sectors)) {
 		*start = min_sec;
@@ -216,7 +217,7 @@ int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, ui
 	}
 
 	list_for_each_entry(p, &pdesc->partitions, list) {
-		uint64_t s = ALIGN(p->first_sec + p->size, PARTITION_ALIGN_SECTORS);
+		uint64_t s = ALIGN(p->first_sec + p->size, align);
 
 		if (partition_is_free(pdesc, s, sectors)) {
 			*start = s;
@@ -245,9 +246,9 @@ int partition_create(struct partition_desc *pdesc, const char *name,
 		return -EINVAL;
 	}
 
-	if (lba_start < partition_first_usable_lba()) {
+	if (lba_start < partition_first_usable_lba(pdesc->blk)) {
 		pr_err("partition starts before first usable lba: %llu < %llu\n",
-		       lba_start, partition_first_usable_lba());
+		       lba_start, partition_first_usable_lba(pdesc->blk));
 		return -EINVAL;
 	}
 
@@ -424,21 +425,19 @@ loff_t cdev_unallocated_space(struct cdev *cdev)
 	return start;
 }
 
-static uint64_t first_usable_dma = SZ_8M / SECTOR_SIZE;
-
-uint64_t partition_first_usable_lba(void)
+sector_t partition_first_usable_lba(const struct block_device *blk)
 {
-	return first_usable_dma;
+	return blockdevice_round_nblocks(blk, first_partition_offset);
 }
 
-static int set_first_usable_lba(struct param_d *p, void *priv)
+static int set_first_partition_offset(struct param_d *p, void *priv)
 {
-	if (first_usable_dma < 1) {
-		pr_err("Minimum is 1\n");
+	if (first_partition_offset < MIN_SECTOR_SIZE) {
+		pr_err("Minimum is 512 bytes\n");
 		return -EINVAL;
 	}
 
-	if (first_usable_dma % (SZ_1M / SECTOR_SIZE))
+	if (first_partition_offset % SZ_1M)
 		pr_warn("recommended to align to 1MiB\n");
 
 	return 0;
@@ -449,12 +448,12 @@ static int partitions_init(void)
 	struct param_d *p = NULL;
 
 	if (IS_ENABLED(CONFIG_GLOBALVAR))
-		p = dev_add_param_uint64(&global_device, "partitions.first_usable_lba",
-					 set_first_usable_lba, NULL,
-					 &first_usable_dma, "%llu", NULL);
+		p = dev_add_param_uint64(&global_device, "partitions.first_partition_offset",
+					 set_first_partition_offset, NULL,
+					 &first_partition_offset, "%llu", NULL);
 
 	return PTR_ERR_OR_ZERO(p);
 }
 core_initcall(partitions_init);
 
-BAREBOX_MAGICVAR(global.partitions.first_usable_lba, "first usable LBA used for creating partitions");
+BAREBOX_MAGICVAR(global.partitions.first_partition_offset, "byte offset used by free-space searches for new partitions");
diff --git a/common/partitions/efi.c b/common/partitions/efi.c
index 4847f88fa551..295c26a5a491 100644
--- a/common/partitions/efi.c
+++ b/common/partitions/efi.c
@@ -690,7 +690,7 @@ static __maybe_unused struct partition_desc *efi_partition_create_table(struct b
 	gpt_header *gpt;
 	unsigned int num_partition_entries = 128;
 	unsigned int gpt_size = (sizeof(gpt_entry) * num_partition_entries) / SECTOR_SIZE;
-	unsigned int first_usable_lba = partition_first_usable_lba();
+	unsigned int first_usable_lba = partition_first_usable_lba(blk);
 
 	partition_desc_init(&epd->pd, blk);
 
diff --git a/include/partitions.h b/include/partitions.h
index f73d028e2951..398813eca58c 100644
--- a/include/partitions.h
+++ b/include/partitions.h
@@ -71,6 +71,6 @@ int partition_remove(struct partition_desc *pdesc, int num);
 void partition_table_free(struct partition_desc *pdesc);
 bool partition_is_free(struct partition_desc *pdesc, uint64_t start, uint64_t size);
 int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, uint64_t *start);
-uint64_t partition_first_usable_lba(void);
+sector_t partition_first_usable_lba(const struct block_device *blk);
 
 #endif /* __PARTITIONS_PARSER_H__ */
-- 
2.47.3




More information about the barebox mailing list