Skip to content

drivers/usbhost: Register the partitions on a mass storage device. - #19750

Merged
acassis merged 1 commit into
apache:masterfrom
Fishwaldo:upstream-usbhost-msc-partitions
Aug 8, 2026
Merged

drivers/usbhost: Register the partitions on a mass storage device.#19750
acassis merged 1 commit into
apache:masterfrom
Fishwaldo:upstream-usbhost-msc-partitions

Conversation

@Fishwaldo

Copy link
Copy Markdown
Contributor

Summary

A drive that has been anywhere near another operating system almost always carries a partition table rather than a filesystem starting at sector zero. The mass storage class driver registers only one block device for the whole drive, so on such a drive that node is the one thing nobody can mount: sector zero holds the partition table, not a filesystem.

This reads the table and registers a block device for each partition beside the whole drive, /dev/sda1 next to /dev/sda, named the way other systems name them. The parsing already exists in the tree and understands both MBR and GPT; this only calls it and registers what it finds.

The whole-drive node stays exactly where it was, for anyone who wants the raw device or whose drive really does hold a bare filesystem.

Impact

  • User visible: a partitioned USB drive becomes mountable. New /dev/sdaN nodes appear alongside the existing /dev/sda; nothing is removed or renamed.
  • Default: y, but gated on USBHOST_MSC && !DISABLE_MOUNTPOINT and on MBR_PARTITION || GPT_PARTITION. It therefore only activates where partition parsing is already built in, which is a deliberate choice: a configuration that has gone to the trouble of enabling partition support and then attaches a partitioned drive almost certainly wants to reach the partitions. Set it to n to keep the previous behaviour.
  • Cost: one table read at device connect, and an inode per partition found.
  • Host controller independent: this is in the shared class driver, not in any HCD, so it applies equally to every USB host controller in the tree.
  • Compatibility, hardware, documentation, security: unaffected.

Testing

Host: macOS 15.5 (Apple Silicon). qemu: 10.1.5 with KVM on Fedora 43 x86_64.

A 32 MB image with an MBR and a single FAT32 partition at LBA 2048, holding one known file:

dd if=/dev/zero of=partdisk.img bs=1M count=32
echo 'label: dos
start=2048, size=61440, type=c' | sfdisk partdisk.img
# mkfs.vfat a 30 MB image, write PART.TXT into it, dd it to seek=2048

Booted on qemu-intel64:jumbo with CONFIG_MBR_PARTITION=y, attached over qemu-xhci as usb-storage. The two runs are the same tree and the same image, differing only in CONFIG_USBHOST_MSC_PARTITIONS.

Without the option:

/dev:
 console  null  oneshot  pci  random  sda  telnet  ttyS0  zero

nsh> mount -t vfat /dev/sda1 /mnt
nsh: mount: mount failed: 15
nsh> cat /mnt/PART.TXT
nsh: cat: open failed: 2

With the option:

/dev:
 console  null  oneshot  pci  random  sda  sda1  telnet  ttyS0  zero

nsh> mount -t vfat /dev/sda1 /mnt
nsh> cat /mnt/PART.TXT
partition-hello

sda1 appears, mounts, and the file inside the partition reads back correctly. sda is still present in both.

A note on how this was tested

These runs were made with #19745 applied underneath, because qemu-intel64:jumbo is the only in-tree configuration with a USB host controller and on current master that controller does not initialise, so no USB device enumerates at all and there is nothing to partition.

The problem this fixes is independent of that PR. It is in usbhost_storage.c, the shared mass storage class driver, which knows nothing about any host controller: a partitioned drive on an EHCI or OHCI board is equally unmountable today. #19745 was needed only to obtain a working controller to test against, and anyone with USB host hardware that already works can reproduce this on its own.

A drive that has been anywhere near another operating system almost
always carries a partition table rather than a filesystem starting at
sector zero, so the single block device this driver registers is usually
the one thing nobody can mount.  A USB stick written with an installer
image is a good example: sector zero holds a protective MBR, and what
somebody wants is the EFI system partition several gigabytes in.

Read the table and give each partition a block device of its own beside
the whole drive, named the way every other system names them.  The
parsing is already in the tree and understands both MBR and GPT; this
only calls it and registers what it finds.

The whole-drive node stays exactly where it was, for anyone who wants
the raw thing or whose drive really does hold a bare filesystem.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
@github-actions github-actions Bot added Size: S The size of the change in this PR is small Area: USB labels Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@acassis
acassis merged commit 50f93a9 into apache:master Aug 8, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: USB Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants