
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@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[],