From: Vincent Jardin Date: Wed, 15 Jul 2026 16:57:15 +0000 (+0200) Subject: fs: dispatch null_dev_desc_ok filesystems before lookup X-Git-Tag: v2026.10-rc1~3^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b1dac9ee2029c6aa9fe4f8554f2250b94b89da2;p=thirdparty%2Fu-boot.git fs: dispatch null_dev_desc_ok filesystems before lookup 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 - works without a new command. Sandbox boards that exercise the existing fallback through "host bind" stay unchanged. Signed-off-by: Vincent Jardin Reviewed-by: Simon Glass --- 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 ..." 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)