fs: implement size/fatsize/ext4size
authorStephen Warren <swarren@nvidia.com>
Wed, 11 Jun 2014 18:47:26 +0000 (12:47 -0600)
committerTom Rini <trini@ti.com>
Sat, 9 Aug 2014 15:16:57 +0000 (11:16 -0400)
These commands may be used to determine the size of a file without
actually reading the whole file content into memory. This may be used
to determine if the file will fit into the memory buffer that will
contain it. In particular, the DFU code will use it for this purpose
in the next commit.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
common/cmd_ext4.c
common/cmd_fat.c
common/cmd_fs.c
fs/ext4/ext4fs.c
fs/fat/fat.c
fs/fs.c
fs/sandbox/sandboxfs.c
include/ext4fs.h
include/fat.h
include/fs.h
include/sandboxfs.h

index 68b047ba6aed1b07509b7ffd8b26fc715c139ce6..6d75dd2b89c6e3e096001fa4f4f3aba4cc22b485 100644 (file)
 #include <usb.h>
 #endif
 
+int do_ext4_size(cmd_tbl_t *cmdtp, int flag, int argc,
+                                               char *const argv[])
+{
+       return do_size(cmdtp, flag, argc, argv, FS_TYPE_EXT);
+}
+
 int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
                                                char *const argv[])
 {
@@ -113,6 +119,14 @@ U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
 
 #endif
 
+U_BOOT_CMD(
+       ext4size,       4,      0,      do_ext4_size,
+       "determine a file's size",
+       "<interface> <dev[:part]> <filename>\n"
+       "    - Find file 'filename' from 'dev' on 'interface'\n"
+       "      and determine its size."
+);
+
 U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
           "list files in a directory (default /)",
           "<interface> <dev[:part]> [directory]\n"
index a4780174480ef858a17a9d804214bc518c9b7f44..633fbf1d311391bb9aa69fd9ce905013b12e9805 100644 (file)
 #include <fat.h>
 #include <fs.h>
 
+int do_fat_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       return do_size(cmdtp, flag, argc, argv, FS_TYPE_FAT);
+}
+
+U_BOOT_CMD(
+       fatsize,        4,      0,      do_fat_size,
+       "determine a file's size",
+       "<interface> <dev[:part]> <filename>\n"
+       "    - Find file 'filename' from 'dev' on 'interface'\n"
+       "      and determine its size."
+);
+
 int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        return do_load(cmdtp, flag, argc, argv, FS_TYPE_FAT);
index 78590d2ef0da8a30179dc0a8c7d3dacb26fe45c0..675434078633400ff85866e4c7554458412b7dc1 100644 (file)
 #include <command.h>
 #include <fs.h>
 
+static int do_size_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       return do_size(cmdtp, flag, argc, argv, FS_TYPE_ANY);
+}
+
+U_BOOT_CMD(
+       size,   4,      0,      do_size_wrapper,
+       "determine a file's size",
+       "<interface> <dev[:part]> <filename>\n"
+       "    - Find file 'filename' from 'dev' on 'interface'\n"
+       "      and determine its size."
+);
+
 static int do_load_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
                                char * const argv[])
 {
index 417ce7b63bf0215122821cee7236e0062e9ee7ef..cbdc22026deb63a24968cbd3c0078407940bc5a2 100644 (file)
@@ -182,6 +182,11 @@ int ext4fs_exists(const char *filename)
        return file_len >= 0;
 }
 
+int ext4fs_size(const char *filename)
+{
+       return ext4fs_open(filename);
+}
+
 int ext4fs_read(char *buf, unsigned len)
 {
        if (ext4fs_root == NULL || ext4fs_file == NULL)
index 54f42eae0d05eec8d456bde67d2f52122d23d369..561921fa2d364e548629fe8152cb953861699b3f 100644 (file)
@@ -1243,6 +1243,11 @@ int fat_exists(const char *filename)
        return sz >= 0;
 }
 
+int fat_size(const char *filename)
+{
+       return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1);
+}
+
 long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
                      unsigned long maxsize)
 {
diff --git a/fs/fs.c b/fs/fs.c
index ea15c5f447bd3fb30ea4a5604a471b0b9a852110..dd680f39c9ca60472ea91f37a7a325f95da3b672 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -46,6 +46,11 @@ static inline int fs_exists_unsupported(const char *filename)
        return 0;
 }
 
+static inline int fs_size_unsupported(const char *filename)
+{
+       return -1;
+}
+
 static inline int fs_read_unsupported(const char *filename, void *buf,
                                      int offset, int len)
 {
@@ -77,6 +82,7 @@ struct fstype_info {
                     disk_partition_t *fs_partition);
        int (*ls)(const char *dirname);
        int (*exists)(const char *filename);
+       int (*size)(const char *filename);
        int (*read)(const char *filename, void *buf, int offset, int len);
        int (*write)(const char *filename, void *buf, int offset, int len);
        void (*close)(void);
@@ -91,6 +97,7 @@ static struct fstype_info fstypes[] = {
                .close = fat_close,
                .ls = file_fat_ls,
                .exists = fat_exists,
+               .size = fat_size,
                .read = fat_read_file,
                .write = fs_write_unsupported,
        },
@@ -103,6 +110,7 @@ static struct fstype_info fstypes[] = {
                .close = ext4fs_close,
                .ls = ext4fs_ls,
                .exists = ext4fs_exists,
+               .size = ext4fs_size,
                .read = ext4_read_file,
                .write = fs_write_unsupported,
        },
@@ -115,6 +123,7 @@ static struct fstype_info fstypes[] = {
                .close = sandbox_fs_close,
                .ls = sandbox_fs_ls,
                .exists = sandbox_fs_exists,
+               .size = sandbox_fs_size,
                .read = fs_read_sandbox,
                .write = fs_write_sandbox,
        },
@@ -126,6 +135,7 @@ static struct fstype_info fstypes[] = {
                .close = fs_close_unsupported,
                .ls = fs_ls_unsupported,
                .exists = fs_exists_unsupported,
+               .size = fs_size_unsupported,
                .read = fs_read_unsupported,
                .write = fs_write_unsupported,
        },
@@ -223,6 +233,19 @@ int fs_exists(const char *filename)
        return ret;
 }
 
+int fs_size(const char *filename)
+{
+       int ret;
+
+       struct fstype_info *info = fs_get_info(fs_type);
+
+       ret = info->size(filename);
+
+       fs_close();
+
+       return ret;
+}
+
 int fs_read(const char *filename, ulong addr, int offset, int len)
 {
        struct fstype_info *info = fs_get_info(fs_type);
@@ -266,6 +289,26 @@ int fs_write(const char *filename, ulong addr, int offset, int len)
        return ret;
 }
 
+int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+               int fstype)
+{
+       int size;
+
+       if (argc != 4)
+               return CMD_RET_USAGE;
+
+       if (fs_set_blk_dev(argv[1], argv[2], fstype))
+               return 1;
+
+       size = fs_size(argv[3]);
+       if (size < 0)
+               return CMD_RET_FAILURE;
+
+       setenv_hex("filesize", size);
+
+       return 0;
+}
+
 int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                int fstype)
 {
index 85079788c990f712f8711b947539e2886d8684e9..ba6402c81c0a5a16ac10838cf0c5981331e9031c 100644 (file)
@@ -80,6 +80,11 @@ int sandbox_fs_exists(const char *filename)
        return sz >= 0;
 }
 
+int sandbox_fs_size(const char *filename)
+{
+       return os_get_filesize(filename);
+}
+
 void sandbox_fs_close(void)
 {
 }
index fbbb002b16735725e9440cd2a7920139076e9beb..6c419f3a233759c7e0998a1e5a25d7792a00bcfe 100644 (file)
@@ -136,6 +136,7 @@ void ext4fs_close(void);
 void ext4fs_reinit_global(void);
 int ext4fs_ls(const char *dirname);
 int ext4fs_exists(const char *filename);
+int ext4fs_size(const char *filename);
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
 int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
 void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
index 63cf78779bd585d18516519593f4e86455bdf68c..20ca3f3dca7df4476c5e94b9925815ba08bb6378 100644 (file)
@@ -198,6 +198,7 @@ int file_cd(const char *path);
 int file_fat_detectfs(void);
 int file_fat_ls(const char *dir);
 int fat_exists(const char *filename);
+int fat_size(const char *filename);
 long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
                      unsigned long maxsize);
 long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);
index 26de0539f7d9d9f47e4250b46af92417dd5c9d26..06a45f2788323b5d0fef4debf677bcf942cebe4d 100644 (file)
@@ -50,6 +50,13 @@ int fs_ls(const char *dirname);
  */
 int fs_exists(const char *filename);
 
+/*
+ * Determine a file's size
+ *
+ * Returns the file's size in bytes, or a negative value if it doesn't exist.
+ */
+int fs_size(const char *filename);
+
 /*
  * Read file "filename" from the partition previously set by fs_set_blk_dev(),
  * to address "addr", starting at byte offset "offset", and reading "len"
@@ -75,6 +82,8 @@ int fs_write(const char *filename, ulong addr, int offset, int len);
  * Common implementation for various filesystem commands, optionally limited
  * to a specific filesystem type via the fstype parameter.
  */
+int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+               int fstype);
 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[],
index a51ad13044e174440fff9c1f69c7f2cebe16bf23..e7c32623e101e31dde107d94468090dc3f041d4d 100644 (file)
@@ -26,6 +26,7 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,
 void sandbox_fs_close(void);
 int sandbox_fs_ls(const char *dirname);
 int sandbox_fs_exists(const char *filename);
+int sandbox_fs_size(const char *filename);
 int fs_read_sandbox(const char *filename, void *buf, int offset, int len);
 int fs_write_sandbox(const char *filename, void *buf, int offset, int len);