[PATCH v3 1/3] fs: dispatch null_dev_desc_ok filesystems before lookup
Vincent Jardin
vjardin at free.fr
Mon Jun 1 15:12:02 CEST 2026
Filesystems that are null_dev_desc_ok (semihosting, ubifs) have
no UCLASS_BLK device under their ifname, so on real hardware
fs_set_blk_dev() always fails at the partition lookup.
The workaround was to add a per-filesystem
command (example cmd/ubifs.c), which duplicates the plumbing of
fstype_info.
Probe such entries with block_desc=NULL up front, so
load semihosting <addr> <file>
works without a new command.
Sandbox boards that exercise the existing fallback through "host
bind" stay unchanged.
Signed-off-by: Vincent Jardin <vjardin at free.fr>
---
Changes in v3:
- Apply Simon Glass's v1 review:
* Fix typo "thue" -> "the" in the commit body
* Refactor the dispatch loop with a fs_lookup_null_dev_info()
helper
- Add doc/usage/cmd/load.rst "Null-block-device interfaces"
- Add pytest regression tests for the `semihosting` and
sandbox ifnames, verified passing on qemu_arm64 (with
CONFIG_SEMIHOSTING=y) and on a sandbox build respectively. A
ubifs test is intentionally not done.
Changes in v2:
- (v2 is my local iteration, not good for the list; the changes
since v1 are captured in the v3 changelog below.)
fs/fs.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/fs/fs.c b/fs/fs.c
index 8ea50a6c13c..56f3e0c9204 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -459,11 +459,53 @@ const char *fs_get_type_name(void)
return fs_get_info(fs_type)->name;
}
+/*
+ * Some fstypes (semihosting, ubifs) have no underlying block device
+ * and ignore the block_desc argument of their probe hook. The legacy
+ * commands (ubifsload, semihosting via env macros) just pass NULL;
+ * for "load <iface> ..." to behave the same, the dispatcher opts
+ * those fstypes in by name here, before any block-device lookup is
+ * attempted.
+ *
+ * Returns the matching fstype_info if @ifname names a fstype that
+ * opts into null_dev_desc_ok dispatch and the caller's @fstype filter
+ * permits it. Returns NULL otherwise.
+ */
+static struct fstype_info *fs_lookup_null_dev_info(const char *ifname,
+ int fstype)
+{
+ struct fstype_info *info;
+ int i;
+
+ for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
+ if (fstype != FS_TYPE_ANY && info->fstype != FS_TYPE_ANY &&
+ fstype != info->fstype)
+ continue;
+ if (!info->null_dev_desc_ok || !info->name)
+ continue;
+ if (!strcmp(info->name, ifname))
+ return info;
+ }
+
+ return NULL;
+}
+
int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
{
struct fstype_info *info;
int part, i;
+ info = fs_lookup_null_dev_info(ifname, fstype);
+ if (info) {
+ fs_dev_desc = NULL;
+ memset(&fs_partition, 0, sizeof(fs_partition));
+ if (!info->probe(NULL, &fs_partition)) {
+ fs_type = info->fstype;
+ fs_dev_part = 0;
+ return 0;
+ }
+ }
+
part = part_get_info_by_dev_and_name_or_num(ifname, dev_part_str, &fs_dev_desc,
&fs_partition, 1);
if (part < 0)
--
2.43.0
More information about the U-Boot
mailing list