[Concept,05/16] fs: isofs: Treat the filesystem as starting at block 0

Message ID 20260421183511.2044469-6-sjg@u-boot.org
State New
Headers
Series efi-x86: Boot Ubuntu live ISOs via U-Boot + BLS, end to end |

Commit Message

Simon Glass April 21, 2026, 6:34 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

isofs_probe() takes a disk_partition and, when present, translates every
subsequent block address by the partition's start LBA. That matches ext4
and FAT semantics but not ISO 9660: an ISO 9660 image always places its
primary volume descriptor at absolute block 16 (byte 32768), regardless
of any surrounding GPT or MBR layout.

Hybrid Ubuntu live ISOs emitted by modern xorriso expose the ISO 9660
session as GPT partition 1, starting at LBA 64 to leave room for the
protective MBR and GPT header. Mounting such a partition through
fs_set_blk_dev_with_part() currently makes isofs_probe() read the
'primary volume descriptor' from partition_start + 16 blocks, miss the
"CD001" signature and return -EINVAL. The bootflow iterator then skips
partition 1 entirely, so Boot Loader Specification entries placed in
the ISO 9660 tree (e.g. the /loader/entry.conf written by
scripts/ubuntu-iso-to-uboot.py) are never discovered and the boot
silently falls back to an EFI direct boot or fails altogether.

Pin bd_part_start and the PVD read offset to 0 so the ISO 9660 driver
always sees absolute disk offsets. Interactive 'ls' on a CD drive with
no partition table still works because the starting LBA is already 0
in that case.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 fs/isofs/interface.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
  

Patch

diff --git a/fs/isofs/interface.c b/fs/isofs/interface.c
index 5f8cc749e08..9346ce12431 100644
--- a/fs/isofs/interface.c
+++ b/fs/isofs/interface.c
@@ -107,10 +107,17 @@  int isofs_probe(struct blk_desc *fs_dev_desc,
 		goto err_free_sb;
 	}
 
-	/* Initialise super_block fields */
+	/*
+	 * ISO 9660 images always start at absolute block 0 of the device,
+	 * even when accessed via a GPT partition whose start LBA is non-zero
+	 * (e.g. a hybrid ISO where partition 1 covers the ISO 9660 session
+	 * but begins at LBA 64 because of the protective MBR + GPT header).
+	 * Pin bd_part_start to 0 so callers that translate filesystem block
+	 * numbers through bd_part_start reach the real data.
+	 */
 	sb->s_bdev->bd_super = sb;
 	sb->s_bdev->bd_blk = fs_dev_desc->bdev;
-	sb->s_bdev->bd_part_start = fs_partition ? fs_partition->start : 0;
+	sb->s_bdev->bd_part_start = 0;
 	sb->s_blocksize = ISOFS_BLOCK_SIZE;
 	sb->s_blocksize_bits = ISOFS_BLOCK_BITS;
 	sb->s_flags = SB_RDONLY;  /* ISO 9660 is always read-only */
@@ -123,9 +130,8 @@  int isofs_probe(struct blk_desc *fs_dev_desc,
 		memset(&ifs.partition, '\0', sizeof(ifs.partition));
 	ifs.mounted = true;
 
-	/* Read first sector to verify it's an ISO filesystem */
-	part_offset = fs_partition ?
-		(loff_t)fs_partition->start * fs_dev_desc->blksz : 0;
+	/* Read the primary volume descriptor at absolute block 16 */
+	part_offset = 0;
 
 	buf = malloc(ISOFS_BLOCK_SIZE);
 	if (!buf) {