[U-Boot] [PATCH v1 01/15] fs: add fs_readdir()
Heinrich Schuchardt
xypron.glpk at gmx.de
Fri Aug 11 16:06:23 UTC 2017
On 08/10/2017 08:29 PM, Rob Clark wrote:
> 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.
>
> Also included is an ls2 command which implements ls on top of
> fs_readdir(), to more easily test the readdir functionality.
>
> Signed-off-by: Rob Clark <robdclark at gmail.com>
> ---
> cmd/fs.c | 14 +++++++++++
> fs/fs.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/fs.h | 23 +++++++++++++++++
> 3 files changed, 117 insertions(+)
>
> diff --git a/cmd/fs.c b/cmd/fs.c
> index abfe5be172..58ddcec1a9 100644
> --- a/cmd/fs.c
> +++ b/cmd/fs.c
> @@ -75,6 +75,20 @@ U_BOOT_CMD(
> " device type 'interface' instance 'dev'."
> )
>
> +static int do_ls2_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[])
> +{
> + return do_ls2(cmdtp, flag, argc, argv, FS_TYPE_ANY);
> +}
> +
> +U_BOOT_CMD(
> + ls2, 4, 1, do_ls2_wrapper,
> + "list files in a directory using fs_readdir (default /)",
> + "<interface> [<dev[:part]> [directory]]\n"
> + " - List files in directory 'directory' of partition 'part' on\n"
> + " device type 'interface' instance 'dev'."
> +)
> +
> static int do_fstype_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
> char * const argv[])
> {
> diff --git a/fs/fs.c b/fs/fs.c
> index 595ff1fe69..5720ceec49 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -69,6 +69,12 @@ static inline int fs_uuid_unsupported(char *uuid_str)
> return -1;
> }
>
> +static inline int fs_readdir_unsupported(const char *filename, loff_t offset,
> + struct fs_dirent *dent)
> +{
> + return -ENXIO;
> +}
> +
> struct fstype_info {
> int fstype;
> char *name;
> @@ -92,6 +98,7 @@ struct fstype_info {
> loff_t len, loff_t *actwrite);
> void (*close)(void);
> int (*uuid)(char *uuid_str);
> + int (*readdir)(const char *filename, loff_t offset, struct fs_dirent *dent);
> };
>
> static struct fstype_info fstypes[] = {
> @@ -112,6 +119,7 @@ static struct fstype_info fstypes[] = {
> .write = fs_write_unsupported,
> #endif
> .uuid = fs_uuid_unsupported,
> + .readdir = fs_readdir_unsupported,
> },
> #endif
> #ifdef CONFIG_FS_EXT4
> @@ -131,6 +139,7 @@ static struct fstype_info fstypes[] = {
> .write = fs_write_unsupported,
> #endif
> .uuid = ext4fs_uuid,
> + .readdir = fs_readdir_unsupported,
> },
> #endif
> #ifdef CONFIG_SANDBOX
> @@ -146,6 +155,7 @@ static struct fstype_info fstypes[] = {
> .read = fs_read_sandbox,
> .write = fs_write_sandbox,
> .uuid = fs_uuid_unsupported,
> + .readdir = fs_readdir_unsupported,
> },
> #endif
> #ifdef CONFIG_CMD_UBIFS
> @@ -161,6 +171,7 @@ static struct fstype_info fstypes[] = {
> .read = ubifs_read,
> .write = fs_write_unsupported,
> .uuid = fs_uuid_unsupported,
> + .readdir = fs_readdir_unsupported,
> },
> #endif
> {
> @@ -175,6 +186,7 @@ static struct fstype_info fstypes[] = {
> .read = fs_read_unsupported,
> .write = fs_write_unsupported,
> .uuid = fs_uuid_unsupported,
> + .readdir = fs_readdir_unsupported,
> },
> };
>
> @@ -334,6 +346,19 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
> return ret;
> }
>
> +int fs_readdir(const char *filename, loff_t offset, struct fs_dirent *dent)
> +{
> + struct fstype_info *info = fs_get_info(fs_type);
> + int ret;
> +
> + memset(dent, 0, sizeof(*dent));
> +
> + ret = info->readdir(filename, offset, dent);
> + fs_close();
> +
> + return ret;
> +}
> +
> int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> int fstype)
> {
> @@ -440,6 +465,61 @@ int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> return 0;
> }
>
> +int do_ls2(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> + int fstype)
> +{
> + const char *filename = argc >= 4 ? argv[3] : "/";
Do we really want to update filename and dev_part_str if argc is illegal?
I would suggest to put the assignments below the argc check.
Could you, please, add comment lines above the function describing the
usage of argv[0..3].
Best regards
Heinrich
> + const char *ifname = argv[1];
> + const char *dev_part_str = (argc >= 3) ? argv[2] : NULL;
> + loff_t offset = 0;
> + int ret, files = 0, dirs = 0;
> +
> + if (argc < 2)
> + return CMD_RET_USAGE;
> + if (argc > 4)
> + return CMD_RET_USAGE;
> +
> + while (1) {
> + struct fs_dirent dent, dent2;
> + char buf[256];
> +
> + if (fs_set_blk_dev(ifname, dev_part_str, fstype))
> + return 1;
> +
> + ret = fs_readdir(filename, offset, &dent);
> + if (ret == -ENOENT) {
> + /* no more directory entries */
> + break;
> + } else if (ret) {
> + printf("command failed at offset %lld (%d)\n",
> + offset, ret);
> + return 1;
> + }
> +
> + /* figure out if the entry is a directory: */
> + ret = snprintf(buf, sizeof(buf), "%s/%s", filename, dent.name);
> + if (ret >= sizeof(buf))
> + return 1;
> +
> + fs_set_blk_dev(ifname, dev_part_str, fstype);
> + ret = fs_readdir(buf, 0, &dent2);
> +
> + if (ret == -ENOTDIR) {
> + printf(" %8lld %s\n", dent.size, dent.name);
> + files++;
> + } else {
> + printf(" %s/\n", dent.name);
> + dirs++;
> + }
> +
> + offset++;
> + }
> +
> + printf("\n%d file(s), %d dir(s)\n\n", files, dirs);
> +
> + return 0;
> +}
> +
> int file_exists(const char *dev_type, const char *dev_part, const char *file,
> int fstype)
> {
> diff --git a/include/fs.h b/include/fs.h
> index 2f2aca8378..d8be5cc9a6 100644
> --- a/include/fs.h
> +++ b/include/fs.h
> @@ -79,6 +79,27 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
> loff_t *actwrite);
>
> /*
> + * A directory entry.
> + */
> +struct fs_dirent {
> + loff_t size;
> + char name[256];
> +};
> +
> +/*
> + * fs_readdir - Read a directory.
> + *
> + * @filename: Name of file to read from
> + * @offset: The offset into the directory to read, ie. offset of N returns
> + * the N'th directory entry
> + * @dent: on success, filled in with directory entry
> + * @return 0 on success, -ENOTDIR if specified file is not a directory,
> + * or -ENOENT if offset is beyond last directory entry, or -ENXIO if
> + * operation is not supported.
> + */
> +int fs_readdir(const char *filename, loff_t offset, struct fs_dirent *dent);
> +
> +/*
> * Common implementation for various filesystem commands, optionally limited
> * to a specific filesystem type via the fstype parameter.
> */
> @@ -88,6 +109,8 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> int fstype);
> int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> int fstype);
> +int do_ls2(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> + int fstype);
> int file_exists(const char *dev_type, const char *dev_part, const char *file,
> int fstype);
> int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>
More information about the U-Boot
mailing list