From: Rob Clark <robdclark@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 4/8] fs: add fs_readdir()
Date: Sat, 2 Sep 2017 12:37:59 -0400 [thread overview]
Message-ID: <20170902163806.27265-5-robdclark@gmail.com> (raw)
In-Reply-To: <20170902163806.27265-1-robdclark@gmail.com>
Needed to support efi file protocol. The fallback.efi loader wants
to be able to read the contents of the /EFI directory to find an OS
to boot.
Modelled after POSIX opendir()/readdir()/closedir(). Unlike the other
fs APIs, this is stateful (ie. state is held in the FS_DIR "directory
stream"), to avoid re-traversing of the directory structure at each
step. The directory stream must be released with closedir() when it
is no longer needed.
Signed-off-by: Rob Clark <robdclark@gmail.com>
---
disk/part.c | 31 ++++++++++++--------
fs/fs.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/fs.h | 55 +++++++++++++++++++++++++++++++++++
include/part.h | 4 +++
4 files changed, 169 insertions(+), 12 deletions(-)
diff --git a/disk/part.c b/disk/part.c
index c67fdacc79..aa9183d696 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int part,
return -1;
}
+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
+{
+ info->start = 0;
+ info->size = dev_desc->lba;
+ info->blksz = dev_desc->blksz;
+ info->bootable = 0;
+ strcpy((char *)info->type, BOOT_PART_TYPE);
+ strcpy((char *)info->name, "Whole Disk");
+#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
+ info->uuid[0] = 0;
+#endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+ info->type_guid[0] = 0;
+#endif
+
+ return 0;
+}
+
int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
struct blk_desc **dev_desc)
{
@@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
- info->start = 0;
- info->size = (*dev_desc)->lba;
- info->blksz = (*dev_desc)->blksz;
- info->bootable = 0;
- strcpy((char *)info->type, BOOT_PART_TYPE);
- strcpy((char *)info->name, "Whole Disk");
-#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
- info->uuid[0] = 0;
-#endif
-#ifdef CONFIG_PARTITION_TYPE_GUID
- info->type_guid[0] = 0;
-#endif
+ part_get_info_whole_disk(*dev_desc, info);
ret = 0;
goto cleanup;
diff --git a/fs/fs.c b/fs/fs.c
index 13cd3626c6..441c880654 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -21,6 +21,7 @@
DECLARE_GLOBAL_DATA_PTR;
static struct blk_desc *fs_dev_desc;
+static int fs_dev_part;
static disk_partition_t fs_partition;
static int fs_type = FS_TYPE_ANY;
@@ -69,6 +70,11 @@ static inline int fs_uuid_unsupported(char *uuid_str)
return -1;
}
+static inline int fs_opendir_unsupported(const char *filename, FS_DIR **dirp)
+{
+ return -EACCES;
+}
+
struct fstype_info {
int fstype;
char *name;
@@ -92,6 +98,9 @@ struct fstype_info {
loff_t len, loff_t *actwrite);
void (*close)(void);
int (*uuid)(char *uuid_str);
+ int (*opendir)(const char *filename, FS_DIR **dirp);
+ int (*readdir)(FS_DIR *dirp);
+ void (*closedir)(FS_DIR *dirp);
};
static struct fstype_info fstypes[] = {
@@ -112,6 +121,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
#endif
.uuid = fs_uuid_unsupported,
+ .opendir = fs_opendir_unsupported,
},
#endif
#ifdef CONFIG_FS_EXT4
@@ -131,6 +141,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
#endif
.uuid = ext4fs_uuid,
+ .opendir = fs_opendir_unsupported,
},
#endif
#ifdef CONFIG_SANDBOX
@@ -146,6 +157,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_sandbox,
.write = fs_write_sandbox,
.uuid = fs_uuid_unsupported,
+ .opendir = fs_opendir_unsupported,
},
#endif
#ifdef CONFIG_CMD_UBIFS
@@ -161,6 +173,7 @@ static struct fstype_info fstypes[] = {
.read = ubifs_read,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+ .opendir = fs_opendir_unsupported,
},
#endif
{
@@ -175,6 +188,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_unsupported,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+ .opendir = fs_opendir_unsupported,
},
};
@@ -228,6 +242,31 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
if (!info->probe(fs_dev_desc, &fs_partition)) {
fs_type = info->fstype;
+ fs_dev_part = part;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/* set current blk device w/ blk_desc + partition # */
+int fs_set_blk_dev2(struct blk_desc *desc, int part)
+{
+ struct fstype_info *info;
+ int ret, i;
+
+ if (part >= 1)
+ ret = part_get_info(desc, part, &fs_partition);
+ else
+ ret = part_get_info_whole_disk(desc, &fs_partition);
+ if (ret)
+ return ret;
+ fs_dev_desc = desc;
+
+ for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
+ if (!info->probe(fs_dev_desc, &fs_partition)) {
+ fs_type = info->fstype;
return 0;
}
}
@@ -334,6 +373,58 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
return ret;
}
+FS_DIR *fs_opendir(const char *filename)
+{
+ struct fstype_info *info = fs_get_info(fs_type);
+ FS_DIR *dirp = NULL;
+ int ret;
+
+ ret = info->opendir(filename, &dirp);
+ fs_close();
+ if (ret) {
+ errno = -ret;
+ return NULL;
+ }
+
+ dirp->desc = fs_dev_desc;
+ dirp->part = fs_dev_part;
+
+ return dirp;
+}
+
+struct fs_dirent *fs_readdir(FS_DIR *dirp)
+{
+ struct fstype_info *info;
+ int ret;
+
+ fs_set_blk_dev2(dirp->desc, dirp->part);
+ info = fs_get_info(fs_type);
+
+ memset(&dirp->dirent, 0, sizeof(dirp->dirent));
+
+ ret = info->readdir(dirp);
+ fs_close();
+ if (ret)
+ return NULL;
+
+ return &dirp->dirent;;
+}
+
+void fs_closedir(FS_DIR *dirp)
+{
+ struct fstype_info *info;
+
+ if (!dirp)
+ return;
+
+ fs_set_blk_dev2(dirp->desc, dirp->part);
+ info = fs_get_info(fs_type);
+
+ info->closedir(dirp);
+ fs_close();
+}
+
+
int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
int fstype)
{
diff --git a/include/fs.h b/include/fs.h
index 2f2aca8378..0a6a366078 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -26,6 +26,8 @@
*/
int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype);
+int fs_set_blk_dev2(struct blk_desc *desc, int part);
+
/*
* Print the list of files on the partition previously set by fs_set_blk_dev(),
* in directory "dirname".
@@ -78,6 +80,59 @@ int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
loff_t *actwrite);
+/* Add additional FS_DT_* as supported by additional filesystems:*/
+#define FS_DT_DIR 0x4 /* directory */
+#define FS_DT_REG 0x8 /* regular file */
+
+/*
+ * A directory entry.
+ */
+struct fs_dirent {
+ unsigned type; /* one of FS_DT_* */
+ loff_t size;
+ char name[256];
+};
+
+typedef struct _FS_DIR FS_DIR;
+
+/*
+ * fs_opendir - Open a directory
+ *
+ * @filename: the path to directory to open
+ * @return a pointer to the directory stream or NULL on error and errno
+ * set appropriately
+ */
+FS_DIR *fs_opendir(const char *filename);
+
+/*
+ * fs_readdir - Read the next directory entry in the directory stream.
+ *
+ * @dirp: the directory stream
+ * @return the next directory entry (only valid until next fs_readdir() or
+ * fs_closedir() call, do not attempt to free()) or NULL if the end of
+ * the directory is reached.
+ */
+struct fs_dirent *fs_readdir(FS_DIR *dirp);
+
+/*
+ * fs_closedir - close a directory stream
+ *
+ * @dirp: the directory stream
+ */
+void fs_closedir(FS_DIR *dirp);
+
+/*
+ * private to fs implementations, would be in fs.c but we need to let
+ * implementations subclass:
+ */
+
+struct _FS_DIR {
+ struct fs_dirent dirent;
+ /* private to fs layer: */
+ struct blk_desc *desc;
+ int part;
+};
+
/*
* Common implementation for various filesystem commands, optionally limited
* to a specific filesystem type via the fstype parameter.
diff --git a/include/part.h b/include/part.h
index 0cd803a933..48e8ff6d8a 100644
--- a/include/part.h
+++ b/include/part.h
@@ -98,6 +98,7 @@ int host_get_dev_err(int dev, struct blk_desc **blk_devp);
/* disk/part.c */
int part_get_info(struct blk_desc *dev_desc, int part, disk_partition_t *info);
+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info);
void part_print(struct blk_desc *dev_desc);
void part_init(struct blk_desc *dev_desc);
void dev_print(struct blk_desc *dev_desc);
@@ -203,6 +204,9 @@ static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; }
static inline int part_get_info(struct blk_desc *dev_desc, int part,
disk_partition_t *info) { return -1; }
+static inline int part_get_info_whole_disk(struct blk_desc *dev_desc,
+ disk_partition_t *info)
+{ return -1; }
static inline void part_print(struct blk_desc *dev_desc) {}
static inline void part_init(struct blk_desc *dev_desc) {}
static inline void dev_print(struct blk_desc *dev_desc) {}
--
2.13.5
next prev parent reply other threads:[~2017-09-02 16:37 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-02 16:37 [U-Boot] [PATCH v2 0/8] fs/fat: cleanups + readdir implementation Rob Clark
2017-09-02 16:37 ` [U-Boot] [PATCH v2 1/8] fs/fat: split out helper to init fsdata Rob Clark
2017-09-03 14:52 ` Łukasz Majewski
2017-09-03 15:47 ` Rob Clark
2017-09-03 16:16 ` Łukasz Majewski
2017-09-05 8:55 ` Simon Glass
2017-09-02 16:37 ` [U-Boot] [PATCH v2 2/8] fs/fat: introduce new director iterators Rob Clark
2017-09-03 15:08 ` Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
2017-09-05 9:54 ` Rob Clark
2017-09-09 4:55 ` Simon Glass
2017-09-09 10:34 ` Rob Clark
2017-09-02 16:37 ` [U-Boot] [PATCH v2 3/8] fat/fs: convert to directory iterators Rob Clark
2017-09-03 15:08 ` Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
2017-09-06 2:18 ` Rob Clark
2017-09-02 16:37 ` Rob Clark [this message]
2017-09-03 15:16 ` [U-Boot] [PATCH v2 4/8] fs: add fs_readdir() Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
2017-09-05 10:48 ` Rob Clark
2017-09-02 16:38 ` [U-Boot] [PATCH v2 5/8] fs/fat: implement opendir/readdir/closedir Rob Clark
2017-09-03 15:17 ` Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
2017-09-02 16:38 ` [U-Boot] [PATCH v2 6/8] fat/fs: remove a bunch of dead code Rob Clark
2017-09-05 8:56 ` Simon Glass
2017-09-02 16:38 ` [U-Boot] [PATCH v2 7/8] fat/fs: move ls to generic implementation Rob Clark
2017-09-03 15:19 ` Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
2017-09-06 2:12 ` Rob Clark
2017-09-02 16:38 ` [U-Boot] [PATCH v2 8/8] fs/fat: fix case for FAT shortnames Rob Clark
2017-09-03 15:22 ` Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
-- strict thread matches above, loose matches on Subject: below --
2017-08-14 13:16 [U-Boot] [PATCH v2 0/8] fs/fat: cleanups + readdir implementation Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 4/8] fs: add fs_readdir() Rob Clark
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170902163806.27265-5-robdclark@gmail.com \
--to=robdclark@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.