The blspec boot entry provider currently feeds the path into
blspec_scan_directory, which will fail to collect an boot entry when
given a regular file. In preparation for allowing to boot a specific
blspec file by path, refactor the code pertaining to a single file into
a blspec_scan_file function and move parse_nfs_url which applies equally
to files and directories into the callsite. There is one other callsite
of blspec_scan_directory in blspec_scan_cdev, but that one will never
handle NFS paths, so it's fine to skip calling parse_nfs_url there.

No functional change intended.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 common/blspec.c  | 112 ++++++++++++++++++++++++-----------------------
 include/blspec.h |   2 +
 2 files changed, 60 insertions(+), 54 deletions(-)

diff --git a/common/blspec.c b/common/blspec.c
index 158fd1e9a28c..d798f6f38a4b 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -513,6 +513,54 @@ static bool entry_is_match_machine_id(struct blspec_entry 
*entry)
        return ret;
 }
 
+int blspec_scan_file(struct bootentries *bootentries, const char *root,
+                    const char *configname)
+{
+       char *devname = NULL, *hwdevname = NULL;
+       struct blspec_entry *entry;
+
+       if (blspec_have_entry(bootentries, configname))
+               return -EEXIST;
+
+       entry = blspec_entry_open(bootentries, configname);
+       if (IS_ERR(entry))
+               return PTR_ERR(entry);
+
+       entry->rootpath = xstrdup(root);
+       entry->configpath = xstrdup(configname);
+       entry->cdev = get_cdev_by_mountpath(root);
+
+       if (!entry_is_of_compatible(entry)) {
+               blspec_entry_free(&entry->entry);
+               return -ENODEV;
+       }
+
+       if (!entry_is_match_machine_id(entry)) {
+               blspec_entry_free(&entry->entry);
+               return -ENODEV;
+       }
+
+       if (entry->cdev && entry->cdev->dev) {
+               devname = xstrdup(dev_name(entry->cdev->dev));
+               if (entry->cdev->dev->parent)
+                       hwdevname = xstrdup(dev_name(entry->cdev->dev->parent));
+       }
+
+       entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, 
"title"),
+                                      configname);
+       entry->entry.description = basprintf("blspec entry, device: %s 
hwdevice: %s",
+                                           devname ? devname : "none",
+                                           hwdevname ? hwdevname : "none");
+       free(devname);
+       free(hwdevname);
+
+       entry->entry.me.type = MENU_ENTRY_NORMAL;
+       entry->entry.release = blspec_entry_free;
+
+       bootentries_add_entry(bootentries, &entry->entry);
+       return 1;
+}
+
 /*
  * blspec_scan_directory - scan over a directory
  *
@@ -522,17 +570,11 @@ static bool entry_is_match_machine_id(struct blspec_entry 
*entry)
  */
 int blspec_scan_directory(struct bootentries *bootentries, const char *root)
 {
-       struct blspec_entry *entry;
        DIR *dir;
        struct dirent *d;
        char *abspath;
        int ret, found = 0;
        const char *dirname = "loader/entries";
-       char *nfspath = NULL;
-
-       nfspath = parse_nfs_url(root);
-       if (!IS_ERR(nfspath))
-               root = nfspath;
 
        pr_debug("%s: %s %s\n", __func__, root, dirname);
 
@@ -549,7 +591,6 @@ int blspec_scan_directory(struct bootentries *bootentries, 
const char *root)
                char *configname;
                struct stat s;
                char *dot;
-               char *devname = NULL, *hwdevname = NULL;
 
                if (*d->d_name == '.')
                        continue;
@@ -578,59 +619,15 @@ int blspec_scan_directory(struct bootentries 
*bootentries, const char *root)
                        continue;
                }
 
-               if (blspec_have_entry(bootentries, configname)) {
-                       free(configname);
-                       continue;
-               }
-
-               entry = blspec_entry_open(bootentries, configname);
-               if (IS_ERR(entry)) {
-                       free(configname);
-                       continue;
-               }
-
-               entry->rootpath = xstrdup(root);
-               entry->configpath = configname;
-               entry->cdev = get_cdev_by_mountpath(root);
-
-               if (!entry_is_of_compatible(entry)) {
-                       blspec_entry_free(&entry->entry);
-                       continue;
-               }
-
-               if (!entry_is_match_machine_id(entry)) {
-                       blspec_entry_free(&entry->entry);
-                       continue;
-               }
-
-               found++;
-
-               if (entry->cdev && entry->cdev->dev) {
-                       devname = xstrdup(dev_name(entry->cdev->dev));
-                       if (entry->cdev->dev->parent)
-                               hwdevname = 
xstrdup(dev_name(entry->cdev->dev->parent));
-               }
-
-               entry->entry.title = xasprintf("%s (%s)", 
blspec_entry_var_get(entry, "title"),
-                                              configname);
-               entry->entry.description = basprintf("blspec entry, device: %s 
hwdevice: %s",
-                                                   devname ? devname : "none",
-                                                   hwdevname ? hwdevname : 
"none");
-               free(devname);
-               free(hwdevname);
-
-               entry->entry.me.type = MENU_ENTRY_NORMAL;
-               entry->entry.release = blspec_entry_free;
-
-               bootentries_add_entry(bootentries, &entry->entry);
+               ret = blspec_scan_file(bootentries, root, configname);
+               if (ret == 1)
+                       found++;
        }
 
        ret = found;
 
        closedir(dir);
 err_out:
-       if (!IS_ERR(nfspath))
-               free(nfspath);
        free(abspath);
 
        return ret;
@@ -846,9 +843,16 @@ static int blspec_bootentry_provider(struct bootentries 
*bootentries,
                found += ret;
 
        if (*name == '/' || !strncmp(name, "nfs://", 6)) {
+               char *nfspath = parse_nfs_url(name);
+               if (!IS_ERR(nfspath))
+                       name = nfspath;
+
                ret = blspec_scan_directory(bootentries, name);
                if (ret > 0)
                        found += ret;
+
+               if (!IS_ERR(nfspath))
+                       free(nfspath);
        }
 
        return found;
diff --git a/include/blspec.h b/include/blspec.h
index 37076cd47c97..8f2556f6620e 100644
--- a/include/blspec.h
+++ b/include/blspec.h
@@ -23,5 +23,7 @@ int blspec_scan_devices(struct bootentries *bootentries);
 int blspec_scan_device(struct bootentries *bootentries, struct device_d *dev);
 int blspec_scan_devicename(struct bootentries *bootentries, const char 
*devname);
 int blspec_scan_directory(struct bootentries *bootentries, const char *root);
+int blspec_scan_file(struct bootentries *bootentries, const char *root,
+                    const char *configname);
 
 #endif /* __LOADER_H__ */
-- 
2.30.2


Reply via email to