[U-Boot] [PATCH v5] fs: fat/ext4/sandbox - Deal with files greater than 2GB
Suriyan Ramasami
suriyan.r at gmail.com
Fri Oct 31 23:40:36 CET 2014
Hello Simon,
On Thu, Oct 30, 2014 at 7:01 PM, Simon Glass <sjg at chromium.org> wrote:
> Hi Suriyan,
>
> On 28 October 2014 17:00, Suriyan Ramasami <suriyan.r at gmail.com> wrote:
>> The commands fatls/ext4ls give negative values when dealing with files
>> greater than 2GB.
>> The commands fatsize/ext4size do not update the variable filesize for
>> these files.
>>
>> To deal with this, the fs functions have been modified to take an additional
>> parameter of type "* loff_t" which is then populated. The return value of the
>> fs functions are used only for error conditions.
>>
>> Signed-off-by: Suriyan Ramasami <suriyan.r at gmail.com>
>>
>> ---
>>
>> Changes in v5:
>> * Simon - update fs.h with comments for fs_read/fs_write/fs_size
>> * Simon - test/fs/fs-test.sh. Many changes as listed under
>> * Add README file to document how to run it
>> * Generate output in a sandbox environment
>> * Add one line comments on shell variables used
>> * Avoid camel case through out
>> * Path to UBOOT is variable at top
>> * Print PASSED or FAILED at end, and set return code, 0 if OK, 1 otherwise
>>
>> Changes in v4:
>> * Support generic fs write commands
>> * Sync up behavior of fs load vs fatload and ext4load
>> * Albert - change -ve to negative in commit message
>>
>> Changes in v3:
>> * Added testcase to test writes
>> * Correct function set_contents() in fs/fat/fat_write.c
>>
>> Changes in v2:
>> * Added test case for fat/ext4 in test/fs/testfs.sh
>> * md5sum: call map_sysmem() for buffer that md5_wd will work on
>>
>> Changes in v1:
>> * First try.
>>
>> arch/sandbox/cpu/os.c | 11 +-
>> arch/sandbox/cpu/state.c | 6 +-
>> common/board_f.c | 6 +-
>> common/cmd_ext4.c | 61 +-----
>> common/cmd_fat.c | 9 +-
>> common/cmd_fs.c | 17 ++
>> common/cmd_md5sum.c | 12 +-
>> common/env_fat.c | 4 +-
>> fs/ext4/ext4_common.c | 24 +--
>> fs/ext4/ext4_common.h | 4 +-
>> fs/ext4/ext4_write.c | 32 ++++
>> fs/ext4/ext4fs.c | 37 ++--
>> fs/fat/fat.c | 124 +++++++------
>> fs/fat/fat_write.c | 59 +++---
>> fs/fat/file.c | 7 +-
>> fs/fs.c | 77 ++++----
>> fs/sandbox/sandboxfs.c | 25 ++-
>> include/configs/sandbox.h | 2 +
>> include/ext4fs.h | 13 +-
>> include/fat.h | 19 +-
>> include/fs.h | 41 ++--
>> include/os.h | 2 +-
>> include/sandboxfs.h | 8 +-
>> test/fs/README | 4 +
>> test/fs/fs-test.sh | 462 ++++++++++++++++++++++++++++++++++++++++++++++
>> 25 files changed, 807 insertions(+), 259 deletions(-)
>> create mode 100644 test/fs/README
>> create mode 100755 test/fs/fs-test.sh
>
> I think you close with this patch. So please can you break it up into
> several patches? It's too had for people to review as is. My thoughts
> are you could have these patches:
>
> - cmd_ms5sum.c is a change to enable md5 for sandbox
> - change fs layer to return size in a paramter and fix up return value
> - if not too much trouble, put the business of returning the number of
> bytes read/written into a separate patch. Otherwise, just leave it in
> the one above
> - any other changes that remain if any (could be first patch in series)
> - patch to add add the test
>
> So that would be 3 to 5 patches depending on how you go.
>
> I've made some comments below anyway. Hopefully this is everything but
> it's hard to tell with so much changing!
>
> Thanks again for your efforts.
OK, Sure thing! I shall split the patches as suggested.
>
>>
>> diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
>> index 1c4aa3f..43872e8 100644
>> --- a/arch/sandbox/cpu/os.c
>> +++ b/arch/sandbox/cpu/os.c
>> @@ -385,7 +385,7 @@ const char *os_dirent_get_typename(enum os_dirent_t type)
>> return os_dirent_typename[OS_FILET_UNKNOWN];
>> }
>>
>> -ssize_t os_get_filesize(const char *fname)
>> +int os_get_filesize(const char *fname, loff_t *size)
>> {
>> struct stat buf;
>> int ret;
>> @@ -393,7 +393,8 @@ ssize_t os_get_filesize(const char *fname)
>> ret = stat(fname, &buf);
>> if (ret)
>> return ret;
>> - return buf.st_size;
>> + *size = buf.st_size;
>> + return 0;
>> }
>>
>> void os_putc(int ch)
>> @@ -427,10 +428,10 @@ int os_read_ram_buf(const char *fname)
>> {
>> struct sandbox_state *state = state_get_current();
>> int fd, ret;
>> - int size;
>> + loff_t size;
>>
>> - size = os_get_filesize(fname);
>> - if (size < 0)
>> + ret = os_get_filesize(fname, &size);
>> + if (ret < 0)
>> return -ENOENT;
>
> return ret here I think, since you actually have the proper error.
OK, will do.
>
>> if (size != state->ram_size)
>> return -ENOSPC;
>> diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
>> index 59adad6..07d2aea 100644
>> --- a/arch/sandbox/cpu/state.c
>> +++ b/arch/sandbox/cpu/state.c
>> @@ -49,12 +49,12 @@ static int state_ensure_space(int extra_size)
>>
>> static int state_read_file(struct sandbox_state *state, const char *fname)
>> {
>> - int size;
>> + loff_t size;
>> int ret;
>> int fd;
>>
>> - size = os_get_filesize(fname);
>> - if (size < 0) {
>> + ret = os_get_filesize(fname, &size);
>> + if (ret < 0) {
>> printf("Cannot find sandbox state file '%s'\n", fname);
>> return -ENOENT;
>
> and here
>
OK.
>> }
>> diff --git a/common/board_f.c b/common/board_f.c
>> index b5bebc9..1fae112 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -285,7 +285,7 @@ static int read_fdt_from_file(void)
>> struct sandbox_state *state = state_get_current();
>> const char *fname = state->fdt_fname;
>> void *blob;
>> - ssize_t size;
>> + loff_t size;
>> int err;
>> int fd;
>>
>> @@ -298,8 +298,8 @@ static int read_fdt_from_file(void)
>> return -EINVAL;
>> }
>>
>> - size = os_get_filesize(fname);
>> - if (size < 0) {
>> + err = os_get_filesize(fname, &size);
>> + if (err < 0) {
>> printf("Failed to file FDT file '%s'\n", fname);
>> return -ENOENT;
>
> and here
>
OK
>> }
>> diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c
>> index ecfc6d3..19423d1 100644
>> --- a/common/cmd_ext4.c
>> +++ b/common/cmd_ext4.c
>> @@ -61,61 +61,16 @@ int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
>>
>> #if defined(CONFIG_CMD_EXT4_WRITE)
>> int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
>> - char *const argv[])
>> + char *const argv[])
>> {
>> - const char *filename = "/";
>> - int dev, part;
>> - unsigned long ram_address;
>> - unsigned long file_size;
>> - disk_partition_t info;
>> - block_dev_desc_t *dev_desc;
>> -
>> - if (argc < 6)
>> - return cmd_usage(cmdtp);
>> -
>> - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
>> - if (part < 0)
>> - return 1;
>> -
>> - dev = dev_desc->dev;
>> -
>> - /* get the filename */
>> - filename = argv[4];
>> -
>> - /* get the address in hexadecimal format (string to int) */
>> - ram_address = simple_strtoul(argv[3], NULL, 16);
>> -
>> - /* get the filesize in hexadecimal format */
>> - file_size = simple_strtoul(argv[5], NULL, 16);
>> -
>> - /* set the device as block device */
>> - ext4fs_set_blk_dev(dev_desc, &info);
>> -
>> - /* mount the filesystem */
>> - if (!ext4fs_mount(info.size)) {
>> - printf("Bad ext4 partition %s %d:%d\n", argv[1], dev, part);
>> - goto fail;
>> - }
>> -
>> - /* start write */
>> - if (ext4fs_write(filename, (unsigned char *)ram_address, file_size)) {
>> - printf("** Error ext4fs_write() **\n");
>> - goto fail;
>> - }
>> - ext4fs_close();
>> -
>> - return 0;
>> -
>> -fail:
>> - ext4fs_close();
>> -
>> - return 1;
>> + return do_save(cmdtp, flag, argc, argv, FS_TYPE_EXT);
>> }
>>
>> -U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
>> - "create a file in the root directory",
>> - "<interface> <dev[:part]> <addr> <absolute filename path> [sizebytes]\n"
>> - " - create a file in / directory");
>> +U_BOOT_CMD(ext4write, 7, 1, do_ext4_write,
>> + "create a file in the root directory",
>> + "<interface> <dev[:part]> <addr> <absolute filename path>\n"
>> + " [sizebytes] [file offset]\n"
>> + " - create a file in / directory");
>>
>> #endif
>>
>> @@ -132,7 +87,7 @@ U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
>> "<interface> <dev[:part]> [directory]\n"
>> " - list files from 'dev' on 'interface' in a 'directory'");
>>
>> -U_BOOT_CMD(ext4load, 6, 0, do_ext4_load,
>> +U_BOOT_CMD(ext4load, 7, 0, do_ext4_load,
>> "load binary file from a Ext4 filesystem",
>> "<interface> [<dev[:part]> [addr [filename [bytes [pos]]]]]\n"
>> " - load binary file 'filename' from 'dev' on 'interface'\n"
>> diff --git a/common/cmd_fat.c b/common/cmd_fat.c
>> index 633fbf1..186835a 100644
>> --- a/common/cmd_fat.c
>> +++ b/common/cmd_fat.c
>> @@ -100,7 +100,8 @@ U_BOOT_CMD(
>> static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
>> int argc, char * const argv[])
>> {
>> - long size;
>> + loff_t size;
>> + int ret;
>> unsigned long addr;
>> unsigned long count;
>> block_dev_desc_t *dev_desc = NULL;
>> @@ -127,15 +128,15 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
>> count = simple_strtoul(argv[5], NULL, 16);
>>
>> buf = map_sysmem(addr, count);
>> - size = file_fat_write(argv[4], buf, count);
>> + ret = file_fat_write(argv[4], buf, 0, count, &size);
>> unmap_sysmem(buf);
>> - if (size == -1) {
>> + if (ret == -1) {
>
> I think this should probably be
>
> if (ret < 0)
>
OK.
>> printf("\n** Unable to write \"%s\" from %s %d:%d **\n",
>> argv[4], argv[1], dev, part);
>> return 1;
>> }
>>
>> - printf("%ld bytes written\n", size);
>> + printf("%llu bytes written\n", size);
>>
>> return 0;
>> }
>> diff --git a/common/cmd_fs.c b/common/cmd_fs.c
>> index 6754340..56e4b3c 100644
>> --- a/common/cmd_fs.c
>> +++ b/common/cmd_fs.c
>> @@ -51,6 +51,23 @@ U_BOOT_CMD(
>> " If 'pos' is 0 or omitted, the file is read from the start."
>> )
>>
>> +static int do_save_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
>> + char * const argv[])
>> +{
>> + return do_save(cmdtp, flag, argc, argv, FS_TYPE_ANY);
>> +}
>> +
>> +U_BOOT_CMD(
>> + write, 7, 0, do_save_wrapper,
>> + "write file to a filesystem",
>> + "<interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]\n"
>> + " - Write binary file 'filename' to partition 'part' on device\n"
>> + " type 'interface' instance 'dev' from addr 'addr' in memory.\n"
>
> To my eye the word 'type' needs to go back one space. But do we really
> want a write command? Can we just use 'fs save' instead?
>
>> + " 'bytes' gives the size to save in bytes and is mandatory.\n"
>> + " 'pos' gives the file byte position to start writing to.\n"
>> + " If 'pos' is 0 or omitted, the file is written from the start."
>> +)
>> +
>> static int do_ls_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
>> char * const argv[])
>> {
>> diff --git a/common/cmd_md5sum.c b/common/cmd_md5sum.c
>> index 3ac8cc4..d22ace5 100644
>> --- a/common/cmd_md5sum.c
>> +++ b/common/cmd_md5sum.c
>> @@ -11,6 +11,7 @@
>> #include <common.h>
>> #include <command.h>
>> #include <u-boot/md5.h>
>> +#include <asm/io.h>
>>
>> /*
>> * Store the resulting sum to an address or variable
>> @@ -79,6 +80,7 @@ int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> int verify = 0;
>> int ac;
>> char * const *av;
>> + void *buf;
>>
>> if (argc < 3)
>> return CMD_RET_USAGE;
>> @@ -96,7 +98,9 @@ int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> addr = simple_strtoul(*av++, NULL, 16);
>> len = simple_strtoul(*av++, NULL, 16);
>>
>> - md5_wd((unsigned char *) addr, len, output, CHUNKSZ_MD5);
>> + buf = map_sysmem(addr, len);
>> + md5_wd(buf, len, output, CHUNKSZ_MD5);
>> + unmap_sysmem(buf);
>>
>> if (!verify) {
>> printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1);
>> @@ -135,6 +139,7 @@ static int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> unsigned long addr, len;
>> unsigned int i;
>> u8 output[16];
>> + void *buf;
>>
>> if (argc < 3)
>> return CMD_RET_USAGE;
>> @@ -142,7 +147,10 @@ static int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> addr = simple_strtoul(argv[1], NULL, 16);
>> len = simple_strtoul(argv[2], NULL, 16);
>>
>> - md5_wd((unsigned char *) addr, len, output, CHUNKSZ_MD5);
>> + buf = map_sysmem(addr, len);
>> + md5_wd(buf, len, output, CHUNKSZ_MD5);
>> + unmap_sysmem(buf);
>> +
>> printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1);
>> for (i = 0; i < 16; i++)
>> printf("%02x", output[i]);
>> diff --git a/common/env_fat.c b/common/env_fat.c
>> index 8db0160..9a6ce63 100644
>> --- a/common/env_fat.c
>> +++ b/common/env_fat.c
>> @@ -41,6 +41,7 @@ int saveenv(void)
>> disk_partition_t info;
>> int dev, part;
>> int err;
>> + loff_t size;
>>
>> err = env_export(&env_new);
>> if (err)
>> @@ -59,7 +60,8 @@ int saveenv(void)
>> return 1;
>> }
>>
>> - err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t));
>> + err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t),
>> + &size);
>> if (err == -1) {
>> printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
>> FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);
>> diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
>> index cccc06a..cab5465 100644
>> --- a/fs/ext4/ext4_common.c
>> +++ b/fs/ext4/ext4_common.c
>> @@ -1892,6 +1892,7 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
>> {
>> unsigned int fpos = 0;
>> int status;
>> + loff_t actread;
>> struct ext2fs_node *diro = (struct ext2fs_node *) dir;
>>
>> #ifdef DEBUG
>> @@ -1909,8 +1910,8 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
>>
>> status = ext4fs_read_file(diro, fpos,
>> sizeof(struct ext2_dirent),
>> - (char *) &dirent);
>> - if (status < 1)
>> + (char *)&dirent, &actread);
>> + if (status < 0)
>> return 0;
>>
>> if (dirent.namelen != 0) {
>> @@ -1921,8 +1922,9 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
>> status = ext4fs_read_file(diro,
>> fpos +
>> sizeof(struct ext2_dirent),
>> - dirent.namelen, filename);
>> - if (status < 1)
>> + dirent.namelen, filename,
>> + &actread);
>> + if (status < 0)
>> return 0;
>>
>> fdiro = zalloc(sizeof(struct ext2fs_node));
>> @@ -2004,8 +2006,8 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
>> printf("< ? > ");
>> break;
>> }
>> - printf("%10d %s\n",
>> - __le32_to_cpu(fdiro->inode.size),
>> + printf("%10u %s\n",
>> + __le32_to_cpu(fdiro->inode.size),
>> filename);
>> }
>> free(fdiro);
>> @@ -2020,6 +2022,7 @@ static char *ext4fs_read_symlink(struct ext2fs_node *node)
>> char *symlink;
>> struct ext2fs_node *diro = node;
>> int status;
>> + loff_t actread;
>>
>> if (!diro->inode_read) {
>> status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
>> @@ -2036,7 +2039,7 @@ static char *ext4fs_read_symlink(struct ext2fs_node *node)
>> } else {
>> status = ext4fs_read_file(diro, 0,
>> __le32_to_cpu(diro->inode.size),
>> - symlink);
>> + symlink, &actread);
>> if (status == 0) {
>> free(symlink);
>> return 0;
>> @@ -2170,11 +2173,10 @@ int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
>> return 1;
>> }
>>
>> -int ext4fs_open(const char *filename)
>> +int ext4fs_open(const char *filename, loff_t *len)
>> {
>> struct ext2fs_node *fdiro = NULL;
>> int status;
>> - int len;
>>
>> if (ext4fs_root == NULL)
>> return -1;
>> @@ -2191,10 +2193,10 @@ int ext4fs_open(const char *filename)
>> if (status == 0)
>> goto fail;
>> }
>> - len = __le32_to_cpu(fdiro->inode.size);
>> + *len = __le32_to_cpu(fdiro->inode.size);
>> ext4fs_file = fdiro;
>>
>> - return len;
>> + return 0;
>> fail:
>> ext4fs_free_node(fdiro, &ext4fs_root->diropen);
>>
>> diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h
>> index 5fa1719..48fd2ac 100644
>> --- a/fs/ext4/ext4_common.h
>> +++ b/fs/ext4/ext4_common.h
>> @@ -50,8 +50,8 @@ static inline void *zalloc(size_t size)
>>
>> int ext4fs_read_inode(struct ext2_data *data, int ino,
>> struct ext2_inode *inode);
>> -int ext4fs_read_file(struct ext2fs_node *node, int pos,
>> - unsigned int len, char *buf);
>> +int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, loff_t len,
>> + char *buf, loff_t *actread);
>> int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
>> struct ext2fs_node **foundnode, int expecttype);
>> int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
>> diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
>> index 648a596..f7c52cc 100644
>> --- a/fs/ext4/ext4_write.c
>> +++ b/fs/ext4/ext4_write.c
>> @@ -975,3 +975,35 @@ fail:
>>
>> return -1;
>> }
>> +
>> +int ext4_write_file(const char *filename, void *buf, loff_t offset,
>> + loff_t len, loff_t *actwrite)
>> +{
>> + int ret;
>> +
>> + if (offset != 0) {
>> + printf("** Cannot support non-zero offset **\n");
>> + return -1;
>> + }
>> +
>> + /* mount the filesystem */
>> + if (!ext4fs_mount(0)) {
>> + printf("** Error Bad ext4 partition **\n");
>> + goto fail;
>> + }
>> +
>> + ret = ext4fs_write(filename, buf, len);
>> +
>> + if (ret) {
>> + printf("** Error ext4fs_write() **\n");
>> + goto fail;
>> + }
>> + ext4fs_close();
>> +
>> + return 0;
>> +
>> +fail:
>> + ext4fs_close();
>> +
>> + return -1;
>> +}
>> diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
>> index cbdc220..ae1c47d 100644
>> --- a/fs/ext4/ext4fs.c
>> +++ b/fs/ext4/ext4fs.c
>> @@ -45,8 +45,8 @@ void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
>> * Optimized read file API : collects and defers contiguous sector
>> * reads into one potentially more efficient larger sequential read action
>> */
>> -int ext4fs_read_file(struct ext2fs_node *node, int pos,
>> - unsigned int len, char *buf)
>> +int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
>> + loff_t len, char *buf, loff_t *actread)
>> {
>> struct ext_filesystem *fs = get_fs();
>> int i;
>> @@ -150,7 +150,8 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
>> previous_block_number = -1;
>> }
>>
>> - return len;
>> + *actread = len;
>> + return 0;
>> }
>>
>> int ext4fs_ls(const char *dirname)
>> @@ -176,23 +177,24 @@ int ext4fs_ls(const char *dirname)
>>
>> int ext4fs_exists(const char *filename)
>> {
>> - int file_len;
>> + loff_t file_len;
>> + int ret;
>>
>> - file_len = ext4fs_open(filename);
>> - return file_len >= 0;
>> + ret = ext4fs_open(filename, &file_len);
>> + return ret == 0;
>> }
>>
>> -int ext4fs_size(const char *filename)
>> +int ext4fs_size(const char *filename, loff_t *size)
>> {
>> - return ext4fs_open(filename);
>> + return ext4fs_open(filename, size);
>> }
>>
>> -int ext4fs_read(char *buf, unsigned len)
>> +int ext4fs_read(char *buf, loff_t len, loff_t *actread)
>> {
>> if (ext4fs_root == NULL || ext4fs_file == NULL)
>> return 0;
>>
>> - return ext4fs_read_file(ext4fs_file, 0, len, buf);
>> + return ext4fs_read_file(ext4fs_file, 0, len, buf, actread);
>> }
>>
>> int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
>> @@ -208,18 +210,19 @@ int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
>> return 0;
>> }
>>
>> -int ext4_read_file(const char *filename, void *buf, int offset, int len)
>> +int ext4_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *len_read)
>> {
>> - int file_len;
>> - int len_read;
>> + loff_t file_len;
>> + int ret;
>>
>> if (offset != 0) {
>> printf("** Cannot support non-zero offset **\n");
>> return -1;
>> }
>>
>> - file_len = ext4fs_open(filename);
>> - if (file_len < 0) {
>> + ret = ext4fs_open(filename, &file_len);
>> + if (ret < 0) {
>> printf("** File not found %s **\n", filename);
>> return -1;
>> }
>> @@ -227,7 +230,7 @@ int ext4_read_file(const char *filename, void *buf, int offset, int len)
>> if (len == 0)
>> len = file_len;
>>
>> - len_read = ext4fs_read(buf, len);
>> + ret = ext4fs_read(buf, len, len_read);
>>
>> - return len_read;
>> + return ret;
>> }
>> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
>> index 561921f..df8705f 100644
>> --- a/fs/fat/fat.c
>> +++ b/fs/fat/fat.c
>> @@ -317,32 +317,33 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)
>> /*
>> * Read at most 'maxsize' bytes from 'pos' in the file associated with 'dentptr'
>> * into 'buffer'.
>> - * Return the number of bytes read or -1 on fatal errors.
>> + * Update the number of bytes read in *gotsize or return -1 on fatal errors.
>> */
>> __u8 get_contents_vfatname_block[MAX_CLUSTSIZE]
>> __aligned(ARCH_DMA_MINALIGN);
>>
>> -static long
>> -get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
>> - __u8 *buffer, unsigned long maxsize)
>> +static int
>> +get_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos,
>> + __u8 *buffer, loff_t maxsize, loff_t *gotsize)
>> {
>> - unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
>> + loff_t filesize = FAT2CPU32(dentptr->size);
>> unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
>> __u32 curclust = START(dentptr);
>> __u32 endclust, newclust;
>> - unsigned long actsize;
>> + loff_t actsize;
>>
>> - debug("Filesize: %ld bytes\n", filesize);
>> + *gotsize = 0;
>> + debug("Filesize: %llu bytes\n", filesize);
>>
>> if (pos >= filesize) {
>> - debug("Read position past EOF: %lu\n", pos);
>> - return gotsize;
>> + debug("Read position past EOF: %llu\n", pos);
>> + return 0;
>> }
>>
>> if (maxsize > 0 && filesize > pos + maxsize)
>> filesize = pos + maxsize;
>>
>> - debug("%ld bytes\n", filesize);
>> + debug("%llu bytes\n", filesize);
>>
>> actsize = bytesperclust;
>>
>> @@ -352,7 +353,7 @@ get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
>> if (CHECK_CLUST(curclust, mydata->fatsize)) {
>> debug("curclust: 0x%x\n", curclust);
>> debug("Invalid FAT entry\n");
>> - return gotsize;
>> + return 0;
>> }
>> actsize += bytesperclust;
>> }
>> @@ -373,16 +374,16 @@ get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
>> filesize -= actsize;
>> actsize -= pos;
>> memcpy(buffer, get_contents_vfatname_block + pos, actsize);
>> - gotsize += actsize;
>> + *gotsize += actsize;
>> if (!filesize)
>> - return gotsize;
>> + return 0;
>> buffer += actsize;
>>
>> curclust = get_fatent(mydata, curclust);
>> if (CHECK_CLUST(curclust, mydata->fatsize)) {
>> debug("curclust: 0x%x\n", curclust);
>> debug("Invalid FAT entry\n");
>> - return gotsize;
>> + return 0;
>> }
>> }
>>
>> @@ -398,7 +399,7 @@ get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
>> if (CHECK_CLUST(newclust, mydata->fatsize)) {
>> debug("curclust: 0x%x\n", newclust);
>> debug("Invalid FAT entry\n");
>> - return gotsize;
>> + return 0;
>> }
>> endclust = newclust;
>> actsize += bytesperclust;
>> @@ -410,14 +411,14 @@ get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
>> printf("Error reading cluster\n");
>> return -1;
>> }
>> - gotsize += actsize;
>> - return gotsize;
>> + *gotsize += actsize;
>> + return 0;
>> getit:
>> if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
>> printf("Error reading cluster\n");
>> return -1;
>> }
>> - gotsize += (int)actsize;
>> + *gotsize += (int)actsize;
>> filesize -= actsize;
>> buffer += actsize;
>>
>> @@ -425,7 +426,7 @@ getit:
>> if (CHECK_CLUST(curclust, mydata->fatsize)) {
>> debug("curclust: 0x%x\n", curclust);
>> printf("Invalid FAT entry\n");
>> - return gotsize;
>> + return 0;
>> }
>> actsize = bytesperclust;
>> endclust = curclust;
>> @@ -633,8 +634,8 @@ static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
>> }
>> if (doit) {
>> if (dirc == ' ') {
>> - printf(" %8ld %s%c\n",
>> - (long)FAT2CPU32(dentptr->size),
>> + printf(" %8u %s%c\n",
>> + FAT2CPU32(dentptr->size),
>> l_name,
>> dirc);
>> } else {
>> @@ -690,8 +691,8 @@ static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
>>
>> if (doit) {
>> if (dirc == ' ') {
>> - printf(" %8ld %s%c\n",
>> - (long)FAT2CPU32(dentptr->size),
>> + printf(" %8u %s%c\n",
>> + FAT2CPU32(dentptr->size),
>
> Please check this does not introduce a warning on 32-bit boards like ARM.
>
I compiled for odroid, and didn't see any warnings.
BTW, I was trying to compile sandbox_config on ARM32, and it gave a
slew of warnings, and it had issues doing sb commands for files > 2GB.
I guess, this can be taken up separately.
>> s_name, dirc);
>> } else {
>> printf(" %s%c\n",
>> @@ -806,9 +807,9 @@ exit:
>> __u8 do_fat_read_at_block[MAX_CLUSTSIZE]
>> __aligned(ARCH_DMA_MINALIGN);
>>
>> -long
>> -do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
>> - unsigned long maxsize, int dols, int dogetsize)
>> +int
>
> Let's put 'int' on the same line as do_fat_read_at()
>
OK
>> +do_fat_read_at(const char *filename, loff_t pos, void *buffer, loff_t maxsize,
>> + int dols, int dogetsize, loff_t *size)
>> {
>> char fnamecopy[2048];
>> boot_sector bs;
>> @@ -821,7 +822,7 @@ do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
>> __u32 cursect;
>> int idx, isdir = 0;
>> int files = 0, dirs = 0;
>> - long ret = -1;
>> + int ret = -1;
>> int firsttime;
>> __u32 root_cluster = 0;
>> int rootdir_size = 0;
>> @@ -974,8 +975,8 @@ do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
>> }
>> if (doit) {
>> if (dirc == ' ') {
>> - printf(" %8ld %s%c\n",
>> - (long)FAT2CPU32(dentptr->size),
>> + printf(" %8u %s%c\n",
>> + FAT2CPU32(dentptr->size),
>> l_name,
>> dirc);
>> } else {
>> @@ -1032,8 +1033,8 @@ do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
>> }
>> if (doit) {
>> if (dirc == ' ') {
>> - printf(" %8ld %s%c\n",
>> - (long)FAT2CPU32(dentptr->size),
>> + printf(" %8u %s%c\n",
>> + FAT2CPU32(dentptr->size),
>> s_name, dirc);
>> } else {
>> printf(" %s%c\n",
>> @@ -1102,7 +1103,7 @@ do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
>> if (dols == LS_ROOT) {
>> printf("\n%d file(s), %d dir(s)\n\n",
>> files, dirs);
>> - ret = 0;
>> + *size = 0;
>> }
>> goto exit;
>> }
>> @@ -1141,7 +1142,7 @@ rootdir_done:
>> if (get_dentfromdir(mydata, startsect, subname, dentptr,
>> isdir ? 0 : dols) == NULL) {
>> if (dols && !isdir)
>> - ret = 0;
>> + *size = 0;
>> goto exit;
>> }
>>
>> @@ -1152,21 +1153,24 @@ rootdir_done:
>> subname = nextname;
>> }
>>
>> - if (dogetsize)
>> - ret = FAT2CPU32(dentptr->size);
>> - else
>> - ret = get_contents(mydata, dentptr, pos, buffer, maxsize);
>> - debug("Size: %d, got: %ld\n", FAT2CPU32(dentptr->size), ret);
>> + if (dogetsize) {
>> + *size = FAT2CPU32(dentptr->size);
>> + ret = 0;
>> + } else {
>> + ret = get_contents(mydata, dentptr, pos, buffer, maxsize, size);
>> + }
>> + debug("Size: %u, got: %llu\n", FAT2CPU32(dentptr->size), *size);
>>
>> exit:
>> free(mydata->fatbuf);
>> return ret;
>> }
>>
>> -long
>> -do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols)
>> +int
>
> Put the above on next tline
>
OK
>> +do_fat_read(const char *filename, void *buffer, loff_t maxsize, int dols,
>> + loff_t *actread)
>> {
>> - return do_fat_read_at(filename, 0, buffer, maxsize, dols, 0);
>> + return do_fat_read_at(filename, 0, buffer, maxsize, dols, 0, actread);
>> }
>>
>> int file_fat_detectfs(void)
>> @@ -1233,44 +1237,50 @@ int file_fat_detectfs(void)
>>
>> int file_fat_ls(const char *dir)
>> {
>> - return do_fat_read(dir, NULL, 0, LS_YES);
>> + loff_t size;
>> +
>> + return do_fat_read(dir, NULL, 0, LS_YES, &size);
>> }
>>
>> int fat_exists(const char *filename)
>> {
>> - int sz;
>> - sz = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1);
>> - return sz >= 0;
>> + int ret;
>> + loff_t size;
>> + ret = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, &size);
>> + return ret == 0;
>> }
>>
>> -int fat_size(const char *filename)
>> +int fat_size(const char *filename, loff_t *size)
>> {
>> - return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1);
>> + return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, size);
>> }
>>
>> -long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
>> - unsigned long maxsize)
>> +int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
>> + loff_t maxsize, loff_t *actread)
>> {
>> printf("reading %s\n", filename);
>> - return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0);
>> + return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0,
>> + actread);
>> }
>>
>> -long file_fat_read(const char *filename, void *buffer, unsigned long maxsize)
>> +int file_fat_read(const char *filename, void *buffer, loff_t maxsize,
>> + loff_t *actread)
>> {
>> - return file_fat_read_at(filename, 0, buffer, maxsize);
>> + return file_fat_read_at(filename, 0, buffer, maxsize, actread);
>> }
>>
>> -int fat_read_file(const char *filename, void *buf, int offset, int len)
>> +int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *actread)
>> {
>> - int len_read;
>> + int ret;
>>
>> - len_read = file_fat_read_at(filename, offset, buf, len);
>> - if (len_read == -1) {
>> + ret = file_fat_read_at(filename, offset, buf, len, actread);
>> + if (ret < 0) {
>> printf("** Unable to read file %s **\n", filename);
>> return -1;
>> }
>>
>> - return len_read;
>> + return 0;
>> }
>>
>> void fat_close(void)
>> diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
>> index 24ed5d3..b0c4611 100644
>> --- a/fs/fat/fat_write.c
>> +++ b/fs/fat/fat_write.c
>> @@ -660,24 +660,26 @@ static int clear_fatent(fsdata *mydata, __u32 entry)
>> /*
>> * Write at most 'maxsize' bytes from 'buffer' into
>> * the file associated with 'dentptr'
>> - * Return the number of bytes read or -1 on fatal errors.
>> + * Update the number of bytes written in *gotsize and return 0
>> + * or return -1 on fatal errors.
>> */
>> static int
>> set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
>> - unsigned long maxsize)
>> + loff_t maxsize, loff_t *gotsize)
>> {
>> - unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
>> + loff_t filesize = FAT2CPU32(dentptr->size);
>> unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
>> __u32 curclust = START(dentptr);
>> __u32 endclust = 0, newclust = 0;
>> - unsigned long actsize;
>> + loff_t actsize;
>>
>> - debug("Filesize: %ld bytes\n", filesize);
>> + *gotsize = 0;
>> + debug("Filesize: %llu bytes\n", filesize);
>>
>> if (maxsize > 0 && filesize > maxsize)
>> filesize = maxsize;
>>
>> - debug("%ld bytes\n", filesize);
>> + debug("%llu bytes\n", filesize);
>>
>> actsize = bytesperclust;
>> endclust = curclust;
>> @@ -692,7 +694,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
>> if (CHECK_CLUST(newclust, mydata->fatsize)) {
>> debug("curclust: 0x%x\n", newclust);
>> debug("Invalid FAT entry\n");
>> - return gotsize;
>> + return 0;
>> }
>> endclust = newclust;
>> actsize += bytesperclust;
>> @@ -706,7 +708,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
>> }
>>
>> /* set remaining bytes */
>> - gotsize += (int)actsize;
>> + *gotsize += actsize;
>> filesize -= actsize;
>> buffer += actsize;
>> actsize = filesize;
>> @@ -715,7 +717,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
>> debug("error: writing cluster\n");
>> return -1;
>> }
>> - gotsize += actsize;
>> + *gotsize += actsize;
>>
>> /* Mark end of file in FAT */
>> if (mydata->fatsize == 16)
>> @@ -724,20 +726,20 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
>> newclust = 0xfffffff;
>> set_fatent_value(mydata, endclust, newclust);
>>
>> - return gotsize;
>> + return 0;
>> getit:
>> if (set_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
>> debug("error: writing cluster\n");
>> return -1;
>> }
>> - gotsize += (int)actsize;
>> + *gotsize += actsize;
>> filesize -= actsize;
>> buffer += actsize;
>>
>> if (CHECK_CLUST(curclust, mydata->fatsize)) {
>> debug("curclust: 0x%x\n", curclust);
>> debug("Invalid FAT entry\n");
>> - return gotsize;
>> + return 0;
>> }
>> actsize = bytesperclust;
>> curclust = endclust = newclust;
>> @@ -766,7 +768,7 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
>> * exceed the size of the block device
>> * Return -1 when overflow occurs, otherwise return 0
>> */
>> -static int check_overflow(fsdata *mydata, __u32 clustnum, unsigned long size)
>> +static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size)
>> {
>> __u32 startsect, sect_num;
>>
>> @@ -924,7 +926,7 @@ static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
>> }
>>
>> static int do_fat_write(const char *filename, void *buffer,
>> - unsigned long size)
>> + loff_t size, loff_t *actwrite)
>
> Can you fit a few more args on the previous line?
>
OK
>> {
>> dir_entry *dentptr, *retdent;
>> __u32 startsect;
>> @@ -936,8 +938,8 @@ static int do_fat_write(const char *filename, void *buffer,
>> int cursect;
>> int ret = -1, name_len;
>> char l_filename[VFAT_MAXLEN_BYTES];
>> - int write_size = size;
>>
>> + *actwrite = size;
>> dir_curclust = 0;
>>
>> if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) {
>> @@ -1015,7 +1017,7 @@ static int do_fat_write(const char *filename, void *buffer,
>>
>> ret = check_overflow(mydata, start_cluster, size);
>> if (ret) {
>> - printf("Error: %ld overflow\n", size);
>> + printf("Error: %llu overflow\n", size);
>> goto exit;
>> }
>>
>> @@ -1025,13 +1027,12 @@ static int do_fat_write(const char *filename, void *buffer,
>> goto exit;
>> }
>>
>> - ret = set_contents(mydata, retdent, buffer, size);
>> + ret = set_contents(mydata, retdent, buffer, size, actwrite);
>> if (ret < 0) {
>> printf("Error: writing contents\n");
>> goto exit;
>> }
>> - write_size = ret;
>> - debug("attempt to write 0x%x bytes\n", write_size);
>> + debug("attempt to write 0x%llx bytes\n", *actwrite);
>>
>> /* Flush fat buffer */
>> ret = flush_fat_buffer(mydata);
>> @@ -1061,7 +1062,7 @@ static int do_fat_write(const char *filename, void *buffer,
>>
>> ret = check_overflow(mydata, start_cluster, size);
>> if (ret) {
>> - printf("Error: %ld overflow\n", size);
>> + printf("Error: %llu overflow\n", size);
>> goto exit;
>> }
>>
>> @@ -1069,13 +1070,13 @@ static int do_fat_write(const char *filename, void *buffer,
>> fill_dentry(mydata, empty_dentptr, filename,
>> start_cluster, size, 0x20);
>>
>> - ret = set_contents(mydata, empty_dentptr, buffer, size);
>> + ret = set_contents(mydata, empty_dentptr, buffer, size,
>> + actwrite);
>> if (ret < 0) {
>> printf("Error: writing contents\n");
>> goto exit;
>> }
>> - write_size = ret;
>> - debug("attempt to write 0x%x bytes\n", write_size);
>> + debug("attempt to write 0x%llx bytes\n", *actwrite);
>>
>> /* Flush fat buffer */
>> ret = flush_fat_buffer(mydata);
>> @@ -1096,11 +1097,17 @@ static int do_fat_write(const char *filename, void *buffer,
>>
>> exit:
>> free(mydata->fatbuf);
>> - return ret < 0 ? ret : write_size;
>> + return ret;
>> }
>>
>> -int file_fat_write(const char *filename, void *buffer, unsigned long maxsize)
>> +int file_fat_write(const char *filename, void *buffer, loff_t offset,
>> + loff_t maxsize, loff_t *actwrite)
>> {
>> + if (offset != 0) {
>> + printf("Error: non zero offset is currently not suported.\n");
>> + return -1;
>> + }
>> +
>> printf("writing %s\n", filename);
>> - return do_fat_write(filename, buffer, maxsize);
>> + return do_fat_write(filename, buffer, maxsize, actwrite);
>> }
>> diff --git a/fs/fat/file.c b/fs/fat/file.c
>> index d910c46..b608883 100644
>> --- a/fs/fat/file.c
>> +++ b/fs/fat/file.c
>> @@ -162,8 +162,8 @@ file_ls(const char *dir)
>> return filesystems[current_filesystem].ls(arg);
>> }
>>
>> -long
>> -file_read(const char *filename, void *buffer, unsigned long maxsize)
>> +int
>> +file_read(const char *filename, void *buffer, loff_t maxsize, loff_t *actread)
>> {
>> char fullpath[1024];
>> const char *arg;
>> @@ -180,5 +180,6 @@ file_read(const char *filename, void *buffer, unsigned long maxsize)
>> arg = fullpath;
>> }
>>
>> - return filesystems[current_filesystem].read(arg, buffer, maxsize);
>> + return filesystems[current_filesystem].read(arg, buffer, maxsize,
>> + actread);
>> }
>> diff --git a/fs/fs.c b/fs/fs.c
>> index dd680f3..0f5a1f4 100644
>> --- a/fs/fs.c
>> +++ b/fs/fs.c
>> @@ -46,19 +46,21 @@ static inline int fs_exists_unsupported(const char *filename)
>> return 0;
>> }
>>
>> -static inline int fs_size_unsupported(const char *filename)
>> +static inline int fs_size_unsupported(const char *filename, loff_t *size)
>> {
>> return -1;
>> }
>>
>> static inline int fs_read_unsupported(const char *filename, void *buf,
>> - int offset, int len)
>> + loff_t offset, loff_t len,
>> + loff_t *actread)
>> {
>> return -1;
>> }
>>
>> static inline int fs_write_unsupported(const char *filename, void *buf,
>> - int offset, int len)
>> + loff_t offset, loff_t len,
>> + loff_t *actwrite)
>> {
>> return -1;
>> }
>> @@ -82,9 +84,11 @@ 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);
>> + int (*size)(const char *filename, loff_t *size);
>> + int (*read)(const char *filename, void *buf, loff_t offset,
>> + loff_t len, loff_t *actread);
>> + int (*write)(const char *filename, void *buf, loff_t offset,
>> + loff_t len, loff_t *actwrite);
>> void (*close)(void);
>> };
>>
>> @@ -99,7 +103,11 @@ static struct fstype_info fstypes[] = {
>> .exists = fat_exists,
>> .size = fat_size,
>> .read = fat_read_file,
>> +#ifdef CONFIG_FAT_WRITE
>> + .write = file_fat_write,
>> +#else
>> .write = fs_write_unsupported,
>> +#endif
>> },
>> #endif
>> #ifdef CONFIG_FS_EXT4
>> @@ -112,7 +120,11 @@ static struct fstype_info fstypes[] = {
>> .exists = ext4fs_exists,
>> .size = ext4fs_size,
>> .read = ext4_read_file,
>> +#ifdef CONFIG_CMD_EXT4_WRITE
>> + .write = ext4_write_file,
>> +#else
>> .write = fs_write_unsupported,
>> +#endif
>> },
>> #endif
>> #ifdef CONFIG_SANDBOX
>> @@ -233,20 +245,21 @@ int fs_exists(const char *filename)
>> return ret;
>> }
>>
>> -int fs_size(const char *filename)
>> +int fs_size(const char *filename, loff_t *size)
>> {
>> int ret;
>>
>> struct fstype_info *info = fs_get_info(fs_type);
>>
>> - ret = info->size(filename);
>> + ret = info->size(filename, size);
>>
>> fs_close();
>>
>> return ret;
>> }
>>
>> -int fs_read(const char *filename, ulong addr, int offset, int len)
>> +int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
>> + loff_t *actread)
>> {
>> struct fstype_info *info = fs_get_info(fs_type);
>> void *buf;
>> @@ -257,11 +270,11 @@ int fs_read(const char *filename, ulong addr, int offset, int len)
>> * means read the whole file.
>> */
>> buf = map_sysmem(addr, len);
>> - ret = info->read(filename, buf, offset, len);
>> + ret = info->read(filename, buf, offset, len, actread);
>> unmap_sysmem(buf);
>>
>> /* If we requested a specific number of bytes, check we got it */
>> - if (ret >= 0 && len && ret != len) {
>> + if (ret == 0 && len && *actread != len) {
>> printf("** Unable to read file %s **\n", filename);
>> ret = -1;
>> }
>> @@ -270,17 +283,18 @@ int fs_read(const char *filename, ulong addr, int offset, int len)
>> return ret;
>> }
>>
>> -int fs_write(const char *filename, ulong addr, int offset, int len)
>> +int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
>> + loff_t *actwrite)
>> {
>> struct fstype_info *info = fs_get_info(fs_type);
>> void *buf;
>> int ret;
>>
>> buf = map_sysmem(addr, len);
>> - ret = info->write(filename, buf, offset, len);
>> + ret = info->write(filename, buf, offset, len, actwrite);
>> unmap_sysmem(buf);
>>
>> - if (ret >= 0 && ret != len) {
>> + if (ret < 0 && len != *actwrite) {
>> printf("** Unable to write file %s **\n", filename);
>> ret = -1;
>> }
>> @@ -292,7 +306,7 @@ int fs_write(const char *filename, ulong addr, int offset, int len)
>> int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> int fstype)
>> {
>> - int size;
>> + loff_t size;
>>
>> if (argc != 4)
>> return CMD_RET_USAGE;
>> @@ -300,8 +314,7 @@ int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> if (fs_set_blk_dev(argv[1], argv[2], fstype))
>> return 1;
>>
>> - size = fs_size(argv[3]);
>> - if (size < 0)
>> + if (fs_size(argv[3], &size) < 0)
>> return CMD_RET_FAILURE;
>>
>> setenv_hex("filesize", size);
>> @@ -315,9 +328,10 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> unsigned long addr;
>> const char *addr_str;
>> const char *filename;
>> - unsigned long bytes;
>> - unsigned long pos;
>> - int len_read;
>> + loff_t bytes;
>> + loff_t pos;
>> + loff_t len_read;
>> + int ret;
>> unsigned long time;
>> char *ep;
>>
>> @@ -359,12 +373,12 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> pos = 0;
>>
>> time = get_timer(0);
>> - len_read = fs_read(filename, addr, pos, bytes);
>> + ret = fs_read(filename, addr, pos, bytes, &len_read);
>> time = get_timer(time);
>> - if (len_read <= 0)
>> + if (ret < 0)
>> return 1;
>>
>> - printf("%d bytes read in %lu ms", len_read, time);
>> + printf("%llu bytes read in %lu ms", len_read, time);
>> if (time > 0) {
>> puts(" (");
>> print_size(len_read / time * 1000, "/s");
>> @@ -408,9 +422,10 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> {
>> unsigned long addr;
>> const char *filename;
>> - unsigned long bytes;
>> - unsigned long pos;
>> - int len;
>> + loff_t bytes;
>> + loff_t pos;
>> + loff_t len;
>> + int ret;
>> unsigned long time;
>>
>> if (argc < 6 || argc > 7)
>> @@ -419,8 +434,8 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> if (fs_set_blk_dev(argv[1], argv[2], fstype))
>> return 1;
>>
>> - filename = argv[3];
>> - addr = simple_strtoul(argv[4], NULL, 16);
>> + addr = simple_strtoul(argv[3], NULL, 16);
>> + filename = argv[4];
>> bytes = simple_strtoul(argv[5], NULL, 16);
>> if (argc >= 7)
>> pos = simple_strtoul(argv[6], NULL, 16);
>> @@ -428,12 +443,12 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
>> pos = 0;
>>
>> time = get_timer(0);
>> - len = fs_write(filename, addr, pos, bytes);
>> + ret = fs_write(filename, addr, pos, bytes, &len);
>> time = get_timer(time);
>> - if (len <= 0)
>> + if (ret < 0)
>> return 1;
>>
>> - printf("%d bytes written in %lu ms", len, time);
>> + printf("%llu bytes written in %lu ms", len, time);
>> if (time > 0) {
>> puts(" (");
>> print_size(len / time * 1000, "/s");
>> diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c
>> index ba6402c..d4d8378 100644
>> --- a/fs/sandbox/sandboxfs.c
>> +++ b/fs/sandbox/sandboxfs.c
>> @@ -16,7 +16,7 @@ int sandbox_fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
>> long sandbox_fs_read_at(const char *filename, unsigned long pos,
>> void *buffer, unsigned long maxsize)
>> {
>> - ssize_t size;
>> + loff_t size;
>> int fd, ret;
>>
>> fd = os_open(filename, OS_O_RDONLY);
>> @@ -27,8 +27,16 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,
>> os_close(fd);
>> return ret;
>> }
>> - if (!maxsize)
>> - maxsize = os_get_filesize(filename);
>> + if (!maxsize) {
>> + ret = os_get_filesize(filename, &size);
>> + if (ret) {
>> + os_close(fd);
>> + return ret;
>> + }
>> +
>> + maxsize = size;
>> + }
>> +
>> size = os_read(fd, buffer, maxsize);
>> os_close(fd);
>>
>> @@ -74,15 +82,16 @@ int sandbox_fs_ls(const char *dirname)
>>
>> int sandbox_fs_exists(const char *filename)
>> {
>> - ssize_t sz;
>> + loff_t sz;
>> + int ret;
>>
>> - sz = os_get_filesize(filename);
>> - return sz >= 0;
>> + ret = os_get_filesize(filename, &sz);
>> + return ret == 0;
>> }
>>
>> -int sandbox_fs_size(const char *filename)
>> +int sandbox_fs_size(const char *filename, loff_t *size)
>> {
>> - return os_get_filesize(filename);
>> + return os_get_filesize(filename, size);
>> }
>>
>> void sandbox_fs_close(void)
>> diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
>> index ee4b244..2b03841 100644
>> --- a/include/configs/sandbox.h
>> +++ b/include/configs/sandbox.h
>> @@ -48,6 +48,7 @@
>> #define CONFIG_ANDROID_BOOT_IMAGE
>>
>> #define CONFIG_FS_FAT
>> +#define CONFIG_FAT_WRITE
>> #define CONFIG_FS_EXT4
>> #define CONFIG_EXT4_WRITE
>> #define CONFIG_CMD_FAT
>> @@ -57,6 +58,7 @@
>> #define CONFIG_DOS_PARTITION
>> #define CONFIG_HOST_MAX_DEVICES 4
>> #define CONFIG_CMD_FS_GENERIC
>> +#define CONFIG_CMD_MD5SUM
>>
>> #define CONFIG_SYS_VSNPRINTF
>>
>> diff --git a/include/ext4fs.h b/include/ext4fs.h
>> index 6c419f3..7630057 100644
>> --- a/include/ext4fs.h
>> +++ b/include/ext4fs.h
>> @@ -125,24 +125,27 @@ int ext4fs_init(void);
>> void ext4fs_deinit(void);
>> int ext4fs_filename_check(char *filename);
>> int ext4fs_write(const char *fname, unsigned char *buffer,
>> - unsigned long sizebytes);
>> + unsigned long sizebytes);
>> +int ext4_write_file(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *actwrite);
>> #endif
>>
>> struct ext_filesystem *get_fs(void);
>> -int ext4fs_open(const char *filename);
>> -int ext4fs_read(char *buf, unsigned len);
>> +int ext4fs_open(const char *filename, loff_t *len);
>> +int ext4fs_read(char *buf, loff_t len, loff_t *actread);
>> int ext4fs_mount(unsigned part_length);
>> 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);
>> +int ext4fs_size(const char *filename, loff_t *size);
>> 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);
>> long int read_allocated_block(struct ext2_inode *inode, int fileblock);
>> int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
>> disk_partition_t *fs_partition);
>> -int ext4_read_file(const char *filename, void *buf, int offset, int len);
>> +int ext4_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *actread);
>> int ext4_read_superblock(char *buffer);
>> #endif
>> diff --git a/include/fat.h b/include/fat.h
>> index 20ca3f3..7a57533 100644
>> --- a/include/fat.h
>> +++ b/include/fat.h
>> @@ -178,8 +178,8 @@ typedef struct {
>>
>> typedef int (file_detectfs_func)(void);
>> typedef int (file_ls_func)(const char *dir);
>> -typedef long (file_read_func)(const char *filename, void *buffer,
>> - unsigned long maxsize);
>> +typedef int (file_read_func)(const char *filename, void *buffer,
>> + loff_t maxsize, loff_t *actread);
>>
>> struct filesystem {
>> file_detectfs_func *detect;
>> @@ -198,15 +198,18 @@ 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);
>> +int fat_size(const char *filename, loff_t *size);
>> +int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
>> + loff_t maxsize, loff_t *actread);
>> +int file_fat_read(const char *filename, void *buffer, loff_t maxsize,
>> + loff_t *actread);
>> const char *file_getfsname(int idx);
>> int fat_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
>> int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
>>
>> -int file_fat_write(const char *filename, void *buffer, unsigned long maxsize);
>> -int fat_read_file(const char *filename, void *buf, int offset, int len);
>> +int file_fat_write(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *actwrite);
>> +int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *actread);
>> void fat_close(void);
>> #endif /* _FAT_H_ */
>> diff --git a/include/fs.h b/include/fs.h
>> index 06a45f2..6bd17c8 100644
>> --- a/include/fs.h
>> +++ b/include/fs.h
>> @@ -51,32 +51,41 @@ int fs_ls(const char *dirname);
>> int fs_exists(const char *filename);
>>
>> /*
>> - * Determine a file's size
>> + * fs_size - Determine a file's size
>> *
>> - * Returns the file's size in bytes, or a negative value if it doesn't exist.
>> + * @filename: Name of the file
>> + * @size: Size of file
>> + * @return 0 if ok with valid *size, negative on error
>> */
>> -int fs_size(const char *filename);
>> +int fs_size(const char *filename, loff_t *size);
>>
>> /*
>> - * Read file "filename" from the partition previously set by fs_set_blk_dev(),
>> - * to address "addr", starting at byte offset "offset", and reading "len"
>> - * bytes. "offset" may be 0 to read from the start of the file. "len" may be
>> - * 0 to read the entire file. Note that not all filesystem types support
>> - * either/both offset!=0 or len!=0.
>> + * fs_read - Read file from the partition previously set by fs_set_blk_dev()
>> + * Note that not all filesystem types support either/both offset!=0 or len!=0.
>> *
>> - * Returns number of bytes read on success. Returns <= 0 on error.
>> + * @filename: Name of file to read from
>> + * @addr: The address to read into
>> + * @offset: The offset in file to read from
>> + * @len: The number of bytes to read. Maybe 0 to read entire file
>> + * @actread: The actual number of bytes read
>> + * @return 0 if ok with valid *actread, -1 on error conditions
>> */
>> -int fs_read(const char *filename, ulong addr, int offset, int len);
>> +int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
>> + loff_t *actread);
>>
>> /*
>> - * Write file "filename" to the partition previously set by fs_set_blk_dev(),
>> - * from address "addr", starting at byte offset "offset", and writing "len"
>> - * bytes. "offset" may be 0 to write to the start of the file. Note that not
>> - * all filesystem types support offset!=0.
>> + * fs_write - Write file to the partition previously set by fs_set_blk_dev()
>> + * Note that not all filesystem types support offset!=0.
>> *
>> - * Returns number of bytes read on success. Returns <= 0 on error.
>> + * @filename: Name of file to read from
>> + * @addr: The address to read into
>> + * @offset: The offset in file to read from. Maybe 0 to write to start of file
>> + * @len: The number of bytes to write
>> + * @actwrite: The actual number of bytes written
>> + * @return 0 if ok with valid *actwrite, -1 on error conditions
>> */
>> -int fs_write(const char *filename, ulong addr, int offset, int len);
>> +int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
>> + loff_t *actwrite);
>>
>> /*
>> * Common implementation for various filesystem commands, optionally limited
>> diff --git a/include/os.h b/include/os.h
>> index 0230a7f..cfefc8c 100644
>> --- a/include/os.h
>> +++ b/include/os.h
>> @@ -219,7 +219,7 @@ const char *os_dirent_get_typename(enum os_dirent_t type);
>> * @param fname Filename to check
>> * @return size of file, or -1 if an error ocurred
>
> Should update this comment as you have changed the return value.
>
OK
>> */
>> -ssize_t os_get_filesize(const char *fname);
>> +int os_get_filesize(const char *fname, loff_t *size);
>>
>> /**
>> * Write a character to the controlling OS terminal
>> diff --git a/include/sandboxfs.h b/include/sandboxfs.h
>> index e7c3262..ea11168 100644
>> --- a/include/sandboxfs.h
>> +++ b/include/sandboxfs.h
>> @@ -26,8 +26,10 @@ 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);
>> +int sandbox_fs_size(const char *filename, loff_t *size);
>> +int fs_read_sandbox(const char *filename, void *buf, loff_t offset, loff_t len,
>> + loff_t *size);
>> +int fs_write_sandbox(const char *filename, void *buf, loff_t offset,
>> + loff_t len, loff_t *actwrite);
>>
>> #endif
>> diff --git a/test/fs/README b/test/fs/README
>> new file mode 100644
>> index 0000000..6d900ef
>> --- /dev/null
>> +++ b/test/fs/README
>> @@ -0,0 +1,4 @@
>> +How to run the test-fs.sh script.
>> +---------------------------------
>> +
>> +1. Invoke script as: test/fs/test-fs.sh from the u-boot base directory.
>
> I don't think it is worth having a README, you can just put this in
> the comments at the top of your script.
>
OK. Shall get rid of it and add comment in script.
>> diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh
>> new file mode 100755
>> index 0000000..506dbd6
>> --- /dev/null
>> +++ b/test/fs/fs-test.sh
>> @@ -0,0 +1,462 @@
>> +#!/bin/bash
>> +# (C) Copyright 2014 Suriyan Ramasami
>> +#
>> +# SPDX-License-Identifier: GPL-2.0+
>> +#
>> +
>> +# Check if the pre-requisite binaries exist. If not inform and exit.
>> +PREREQ_BINS="md5sum mkfs.ext4 mkfs.vfat mount umount dd fallocate mkdir"
>> +
>> +for prereq in $PREREQ_BINS; do
>> + if [ ! -x `which $prereq` ]; then
>> + echo "Missing $prereq binary. Exiting!"
>> + exit
>> + fi
>> + if [ ! -c /dev/urandom ]; then
>> + echo "Missing character special /dev/urandom. Exiting!"
>> + exit
>> + fi
>> +done
>
> Could go in check_prereqs() function
>
OK
>> +
>> +# All generated output files from this test will be in $OUT_DIR
>> +# Hence everything is sandboxed.
>> +OUT_DIR="sandbox/test/fs"
>> +mkdir -p $OUT_DIR
>> +
>> +# If 1st param is "clean", then clean out the generated files and exit
>> +if [ "$1" = "clean" ]; then
>> + rm -rf "$OUT_DIR"
>> + echo "Cleaned up generated files. Exiting"
>> + exit
>> +fi
>> +
>> +# Generate sandbox u-boot - gleaned from /test/dm/test-dm.sh
>> +unset CROSS_COMPILE
>> +NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor)
>> +make O=sandbox sandbox_config
>> +make O=sandbox -s -j${NUM_CPUS}
>> +
>> +# Location of generated sandbox u-boot
>> +UBOOT="./sandbox/u-boot"
>> +
>> +# Check if UBOOT exists
>> +if [ ! -x "$UBOOT" ]; then
>> + echo "$UBOOT does not exist or is not executable"
>> + echo "Build error?"
>> + echo "Please run this script as ./test/fs/`basename $0`"
>> + exit
>> +fi
>> +
>> +# Our mount directory will be in the sandbox as ./sandbox/mnt
>> +MOUNT_DIR="${OUT_DIR}/mnt"
>
> Can you put all the settings at the top of the file and all the code
> at the bottom (or in functions)?
>
OK.
>> +
>> +# The file system image we create will have the $IMG prefix.
>> +IMG="${OUT_DIR}/3GB"
>> +
>> +# $SMALL_FILE is the name of the 1MB file in the file system image
>> +SMALL_FILE="1MB.file"
>> +
>> +# $BIG_FILE is the name of the 2.5GB file in the file system image
>> +BIG_FILE="2.5GB.file"
>> +
>> +# $MD5_FILE will have the expected md5s when we do the test
>> +# They shall have a suffix which represents their file system (ext4/vfat)
>> +MD5_FILE="${OUT_DIR}/md5s.list"
>> +
>> +# $OUT shall be the prefix of the test output. Their suffix will be .out
>> +OUT="${OUT_DIR}/fs-test"
>> +
>> +# Initialize TESTS and TESTS_INDEX for results
>> +TESTS=""
>> +TESTS_INDEX=0
>> +
>> +# Clean out all generated files other than the file system images
>> +# We save time by not deleting and recreating the file system images
>> +rm -f ${MD5_FILE}.* ${OUT}.*
>> +
>> +# Full Path of the 1 MB file that shall be created in the fs image.
>> +MB1="${MOUNT_DIR}/${SMALL_FILE}"
>> +GB2p5="${MOUNT_DIR}/${BIG_FILE}"
>> +
>> +# ************************
>> +# * Functions start here *
>> +# ************************
>> +
>> +# 1st parameter is the name of the image file to be created
>> +# 2nd parameter is the filesystem - vfat ext4 etc
>> +function create_image() {
>> +
>> + # Create image if not already present - saves time, while debugging
>> + if [ ! -f "$1" ]; then
>> + fallocate -l 3G "$1" &> /dev/null
>> + if [ "$2" = "ext4" ]; then
>> + mkfs."$2" "$1" &> /dev/null <<EOF
>
> Does something like this work?
>
> mkfs -t "$2" -F "$1" ...
>
Will check it out. Thanks for the suggestion.
>> +y
>> +EOF
>> + else
>> + mkfs."$2" "$1" &> /dev/null
>> + fi
>> + fi
>> +}
>> +
>> +# 1st parameter is the FS type: vfat/ext4
>> +# 2nd parameter is the name of small file
>> +# Returns filename which can be used for vfat or ext4 for writing
>> +function fname_for_write() {
>> +
>> + case $1 in
>> + ext4)
>> + # ext4 needs absolute path name of file
>> + echo /$2
>> + ;;
>> +
>> + *)
>> + echo $2
>> + ;;
>> + esac
>> +}
>> +
>> +# 1st parameter is image file
>> +# 2nd parameter is file system type - vfat/ext4
>> +# 3rd parameter is name of small file
>> +# 4th parameter is name of big file
>> +# 5th parameter is fs or nonfs - to dictate generic fs commands or
>> +# otherwise
>> +# UBOOT is set in env
>> +function test_image() {
>> +
>> + # Convert vfat to fat so that commands issued are correct.
>> + if [ "$2" = "vfat" ]; then
>> + PREFIX="fat"
>> + else
>> + PREFIX="$2"
>> + fi
>> +
>> + if [ "$5" = "fs" ]; then
>> + PREFIX=""
>> + fi
>> +
>> + WRITE_FILE=`fname_for_write $2 $3`
>> +
>> + # In u-boot commands, <interface> stands for host or hostfs
>
> U-Boot
>
OK
>> + # hostfs maps to the host fs.
>> + # host maps to the "sb bind" that we do
>> +
>> + $UBOOT << EOF
>> +
>> +sb bind 0 "$1"
>> +${PREFIX}ls host 0:0 /
>> +#
>> +# 1MB is 0x0010 0000
>> +${PREFIX}size host 0:0 $3
>> +printenv filesize
>> +setenv filesize
>> +
>> +# 2.5GB (1024*1024*2500) is 0x9C40 0000
>> +${PREFIX}size host 0:0 $4
>> +printenv filesize
>> +setenv filesize
>> +
>> +# Notes about load operation
>> +# If I use 0x01000000 I get DMA misaligned error message
>> +# Last two parameters are size and offset.
>> +
>> +# Read full 1MB of small file
>> +${PREFIX}load host 0:0 0x01000008 $3
>> +printenv filesize
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +
>> +# First 1MB of big file
>> +${PREFIX}load host 0:0 0x01000008 $4 0x00100000 0x0
>
> Can we put these repeating constants in lower-case variables like:
>
> ${addr}
> ${offset}
>
> or similar? Just those few that you use a lot.
>
OK
>> +printenv filesize
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +
>> +# Last 1MB of big file - fails for ext as no offset support
>> +${PREFIX}load host 0:0 0x01000008 $4 0x00100000 0x9C300000
>> +printenv filesize
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +
>> +# One from the last 1MB chunk of 2GB - fails for ext
>> +${PREFIX}load host 0:0 0x01000008 $4 0x00100000 0x7FF00000
>> +printenv filesize
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +
>> +# One from the start 1MB chunk from 2GB - fails for ext
>> +${PREFIX}load host 0:0 0x01000008 $4 0x00100000 0x80000000
>> +printenv filesize
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +
>> +# One 1MB chunk crossing the 2GB boundary - fails for ext
>> +${PREFIX}load host 0:0 0x01000008 $4 0x00100000 0x7FF80000
>> +printenv filesize
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +
>> +# 2MB chunk from the last 1MB of big file - Generic failure case
>> +${PREFIX}load host 0:0 0x01000008 $4 0x00200000 0x9C300000
>> +printenv filesize
>> +#
>> +
>> +# Read 1MB from small file
>> +${PREFIX}load host 0:0 0x01000008 $3
>> +# Write it back to test the writes
>> +${PREFIX}write host 0:0 0x01000008 $WRITE_FILE \$filesize
>> +mw.b 0x01000008 00 100
>> +${PREFIX}load host 0:0 0x01000008 $WRITE_FILE
>> +md5sum 0x01000008 \$filesize
>> +setenv filesize
>> +#
>> +reset
>> +
>> +EOF
>> +}
>> +
>> +# 1st argument is the name of the image file.
>> +# 2nd argument is the file where we generate the md5s of the files
>> +# generated with the appropriate start and length that we use to test.
>> +# It creates the necessary files in the image to test.
>> +# $GB2p5 is the path of the big file (2.5 GB)
>> +# $MB1 is the path of the small file (1 MB)
>> +# $MOUNT_DIR is the path we can use to mount the image file.
>> +function create_files() {
>> +
>
> Drop these blank lines at top of functions.
>
OK
>> + # Mount the image so we can populate it.
>> + mkdir -p "$MOUNT_DIR"
>> + sudo mount -o loop "$1" "$MOUNT_DIR"
>> +
>> + # Create big file in this image.
>> + # Note that we work only on the start 1MB, couple MBs in the 2GB range
>> + # and the last 1 MB of the huge 2.5GB file.
>> + # So, just put random values only in those areas.
>> + if [ ! -f "${GB2p5}" ]; then
>> + sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=1 \
>> + &> /dev/null
>> + sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=2 seek=2047 \
>> + &> /dev/null
>> + sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=1 seek=2499 \
>> + &> /dev/null
>> + fi
>> +
>> + # Create a small file in this image.
>> + if [ ! -f "${MB1}" ]; then
>> + sudo dd if=/dev/urandom of="${MB1}" bs=1M count=1 \
>> + &> /dev/null
>> + fi
>> +
>> + # Delete the small file which possibly is written as part of a
>> + # previous test.
>> + sudo rm -f "${MOUNT_DIR}/*.w"
>> +
>> + # Generate the md5sums of reads that we will test against small file
>> + dd if="${MB1}" bs=1M skip=0 count=1 2> /dev/null | md5sum > "$2"
>> +
>> + # Generate the md5sums of reads that we will test against big file
>> + # One from beginning of file.
>> + dd if="${GB2p5}" bs=1M skip=0 count=1 \
>> + 2> /dev/null | md5sum >> "$2"
>> +
>> + # One from end of file.
>> + dd if="${GB2p5}" bs=1M skip=2499 count=1 \
>> + 2> /dev/null | md5sum >> "$2"
>> +
>> + # One from the last 1MB chunk of 2GB
>> + dd if="${GB2p5}" bs=1M skip=2047 count=1 \
>> + 2> /dev/null | md5sum >> "$2"
>> +
>> + # One from the start 1MB chunk from 2GB
>> + dd if="${GB2p5}" bs=1M skip=2048 count=1 \
>> + 2> /dev/null | md5sum >> "$2"
>> +
>> + # One 1MB chunk crossing the 2GB boundary
>> + dd if="${GB2p5}" bs=512K skip=4095 count=2 \
>> + 2> /dev/null | md5sum >> "$2"
>> +
>> + sync
>> + sudo umount "$MOUNT_DIR"
>> + rmdir "$MOUNT_DIR"
>> +}
>> +
>> +# 1st parameter is the text to print
>> +# if $? is 0 its a pass, else a fail
>> +# As a side effect it shall update env variable PASS and FAIL
>> +function pass_fail() {
>> +
>> + if [ $? -eq 0 ]; then
>> + echo pass - "$1"
>> + PASS=$((PASS + 1))
>> + else
>> + echo FAIL - "$1"
>> + FAIL=$((FAIL + 1))
>> + fi
>> +}
>> +
>> +# 1st parameter is the string which leads to an md5 generation
>> +# 2nd parameter is the file we grep, for that string
>> +# 3rd parameter is the name of the file which has md5s in it
>> +# 4th parameter is the line # in the md5 file that we match it against
>> +# This function checks if the md5 of the file in the sandbox matches
>> +# that calculated while generating the file
>> +check_md5() {
>> +
>> + # md5sum in u-boot has output of form:
>> + # md5 for 01000008 ... 01100007 ==> <md5>
>> + # the 7th field is the actual md5
>> + md5_src=`grep -A6 "$1" "$2" | grep "md5 for"`
>> + md5_src=($md5_src)
>> + md5_src=${md5_src[6]}
>> +
>> + # The md5 list, each line is of the form:
>> + # - <md5>
>> + # the 2nd field is the actual md5
>> + md5_dst=`sed -n $4p $3`
>> + md5_dst=($md5_dst)
>> + md5_dst=${md5_dst[0]}
>> +
>> + # For a pass they should match.
>> + [ "$md5_src" = "$md5_dst" ]
>> + pass_fail "$1"
>> +}
>> +
>> +# 1st parameter is the name of the output file to check
>> +# 2nd parameter is the name of the file containing the md5 expected
>> +# 3rd parameter is the name of the small file
>> +# 4th parameter is the name of the big file
>> +# 5th paramter is the name of the written file
>> +# This function checks the output file for correct results.
>> +function check_results() {
>> +
>> + echo "** Start $1"
>> +
>> + PASS=0
>> + FAIL=0
>> +
>> + # Check if the ls is showing correct results for 2.5 gb file
>> + grep -A6 "ls host 0:0" "$1" | grep 2621440000 | grep -iq "$4"
>> + pass_fail "ls host 0:0 of $4"
>> +
>> + # Check if the ls is showing correct results for 1 mb file
>> + grep -A6 "ls host 0:0" "$1" | grep 1048576 | grep -iq "$3"
>> + pass_fail "ls host 0:0 of $3"
>> +
>> + # Check size command on 1MB.file
>> + grep -A3 "size host 0:0 $3" "$1" | grep -q "filesize=100000"
>> + pass_fail "size host 0:0 $3"
>> +
>> + # Check size command on 2.5GB.file
>> + grep -A3 "size host 0:0 $4" "$1" \
>> + | grep -q "filesize=9c400000"
>> + pass_fail "size host 0:0 $4"
>> +
>> + # Check read full mb of 1MB.file
>> + grep -A6 "load host 0:0 0x01000008 $3" "$1" | \
>> + grep -q "filesize=100000"
>> + pass_fail "load host 0:0 0x01000008 $3 size"
>> + check_md5 "load host 0:0 0x01000008 $3" "$1" "$2" 1
>> +
>> + # Check first mb of 2.5GB.file
>> + grep -A6 "load host 0:0 0x01000008 $4 0x00100000 0x0" \
>> + "$1" | grep -q "filesize=100000"
>> + pass_fail "load host 0:0 0x01000008 $4 0x00100000 0x0 size"
>> + check_md5 "load host 0:0 0x01000008 $4 0x00100000 0x0" \
>> + "$1" "$2" 2
>> +
>> + # Check last mb of 2.5GB.file
>> + grep -A6 "load host 0:0 0x01000008 $4 0x00100000 0x9C300000" \
>> + "$1" | grep -q "filesize=100000"
>> + pass_fail "load host 0:0 0x01000008 $4 0x00100000 0x9C300000 size"
>> + check_md5 "load host 0:0 0x01000008 $4 0x00100000 0x9C300000" \
>> + "$1" "$2" 3
>> +
>> + # Check last 1mb chunk of 2gb from 2.5GB file
>> + grep -A6 "load host 0:0 0x01000008 $4 0x00100000 0x7FF00000" \
>> + "$1" | grep -q "filesize=100000"
>> + pass_fail "load host 0:0 0x01000008 $4 0x00100000 0x7FF00000 size"
>> + check_md5 "load host 0:0 0x01000008 $4 0x00100000 0x7FF00000" \
>> + "$1" "$2" 4
>> +
>> + # Check first 1mb chunk after 2gb from 2.5GB file
>> + grep -A6 "load host 0:0 0x01000008 $4 0x00100000 0x80000000" \
>> + "$1" | grep -q "filesize=100000"
>> + pass_fail "load host 0:0 0x01000008 $4 0x00100000 0x80000000 size"
>> + check_md5 "load host 0:0 0x01000008 $4 0x00100000 0x80000000" \
>> + "$1" "$2" 5
>> +
>> + # Check 1mb chunk crossing the 2gb boundary from 2.5GB file
>> + grep -A6 "load host 0:0 0x01000008 $4 0x00100000 0x7FF80000" \
>> + "$1" | grep -q "filesize=100000"
>> + pass_fail "load host 0:0 0x01000008 $4 0x00100000 0x7FF80000 size"
>> + check_md5 "load host 0:0 0x01000008 $4 0x00100000 0x7FF80000" \
>> + "$1" "$2" 6
>> +
>> + # Check 2mb chunk from the last 1MB of 2.5GB file - generic failure case
>> + grep -A6 "load host 0:0 0x01000008 $4 0x00200000 0x9C300000" \
>> + "$1" | grep -q 'Error: "filesize" not defined'
>> + pass_fail "load host 0:0 0x01000008 $4 0x00200000 0x9C300000 size"
>> +
>> + # Check 1mb chunk write
>> + grep -A3 "write host 0:0 0x01000008 $5" \
>> + "$1" | egrep -q '1048576 bytes written|update journal'
>> + pass_fail "write host 0:0 0x01000008 $5"
>> + check_md5 "load host 0:0 0x01000008 $5" \
>> + "$1" "$2" 1
>> + echo "** End $1"
>> +}
>> +
>> +# ********************
>> +# * End of functions *
>> +# ********************
>> +
>> +# Track TOTAL_FAIL and TOTAL_PASS
>> +TOTAL_FAIL=0
>> +TOTAL_PASS=0
>> +
>> +# In each loop, for a given file system image, we test both the
>> +# fs command, like load/size/write and the file system specific command
>> +# like: ext4load/ext4size/ext4write
>> +for fs in ext4 vfat; do
>> +
>> + echo "Creating $fs image if not already present."
>> + IMAGE=${IMG}.${fs}.img
>> + create_image $IMAGE $fs
>> +
>> + echo "Creating files in $fs image if not already present."
>> + MD5_FILE_FS="${MD5_FILE}.${fs}"
>> + create_files $IMAGE $MD5_FILE_FS
>> +
>> + OUT_FILE="${OUT}.${fs}.out"
>> + test_image $IMAGE $fs $SMALL_FILE $BIG_FILE nonfs \
>> + > $OUT_FILE
>> + check_results $OUT_FILE $MD5_FILE_FS $SMALL_FILE $BIG_FILE \
>> + $WRITE_FILE
>> + echo "Summary: PASS: $PASS FAIL: $FAIL"
>> + TOTAL_FAIL=$((TOTAL_FAIL + FAIL))
>> + TOTAL_PASS=$((TOTAL_PASS + PASS))
>> +
>> + echo "Creating files in $fs image if not already present."
>> + create_files $IMAGE $MD5_FILE_FS
>> +
>> + OUT_FILE="${OUT}.fs.${fs}.out"
>> + test_image $IMAGE $fs $SMALL_FILE $BIG_FILE fs \
>> + > ${OUT_FILE}
>> + check_results $OUT_FILE $MD5_FILE_FS $SMALL_FILE $BIG_FILE \
>> + $WRITE_FILE
>> + echo "Summary: PASS: $PASS FAIL: $FAIL"
>> + echo "--------------------------------------------"
>> + TOTAL_FAIL=$((TOTAL_FAIL + FAIL))
>> + TOTAL_PASS=$((TOTAL_PASS + PASS))
>> +done
>> +
>> +echo "Total Summary: TOTAL PASS: $TOTAL_PASS TOTAL FAIL: $TOTAL_FAIL"
>> +echo "--------------------------------------------"
>> +if [ $TOTAL_FAIL -eq 0 ]; then
>> + echo "PASSED"
>> + exit 0
>> +else
>> + echo "FAILED"
>> + exit 1
>> +fi
>> --
>> 1.9.1
>>
>
> Regards,
> Simon
More information about the U-Boot
mailing list