Hello Simon, On Thu, Oct 30, 2014 at 7:01 PM, Simon Glass <s...@chromium.org> wrote: > Hi Suriyan, > > On 28 October 2014 17:00, Suriyan Ramasami <suriya...@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 <suriya...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot