From 9f12cd0e062614e19734b2ab37842d387457c5e5 Mon Sep 17 00:00:00 2001 From: Suriyan Ramasami Date: Mon, 17 Nov 2014 14:39:36 -0800 Subject: ext4: Prepare API change for files greater than 2GB Change the internal EXT4 functions to use loff_t for offsets. Signed-off-by: Suriyan Ramasami Acked-by: Simon Glass [trini: Update common/spl/spl_ext.c] Signed-off-by: Tom Rini --- common/cmd_ext4.c | 61 +++++++-------------------------------------------- common/spl/spl_ext.c | 18 +++++++-------- fs/ext4/ext4_common.c | 24 ++++++++++---------- fs/ext4/ext4_common.h | 4 ++-- fs/ext4/ext4_write.c | 32 +++++++++++++++++++++++++++ fs/ext4/ext4fs.c | 43 +++++++++++++++++++++++------------- include/ext4fs.h | 8 ++++--- 7 files changed, 97 insertions(+), 93 deletions(-) diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c index ecfc6d3c9b..19423d1c81 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", - " [sizebytes]\n" - " - create a file in / directory"); +U_BOOT_CMD(ext4write, 7, 1, do_ext4_write, + "create a file in the root directory", + " \n" + " [sizebytes] [file offset]\n" + " - create a file in / directory"); #endif @@ -132,7 +87,7 @@ U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls, " [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", " [ [addr [filename [bytes [pos]]]]]\n" " - load binary file 'filename' from 'dev' on 'interface'\n" diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c index d9eba5aef3..5ff9bc5626 100644 --- a/common/spl/spl_ext.c +++ b/common/spl/spl_ext.c @@ -15,7 +15,7 @@ int spl_load_image_ext(block_dev_desc_t *block_dev, { s32 err; struct image_header *header; - int filelen; + loff_t filelen, actlen; disk_partition_t part_info = {}; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - @@ -37,12 +37,12 @@ int spl_load_image_ext(block_dev_desc_t *block_dev, goto end; } - filelen = err = ext4fs_open(filename); + err = ext4fs_open(filename, &filelen); if (err < 0) { puts("spl: ext4fs_open failed\n"); goto end; } - err = ext4fs_read((char *)header, sizeof(struct image_header)); + err = ext4fs_read((char *)header, sizeof(struct image_header), &actlen); if (err <= 0) { puts("spl: ext4fs_read failed\n"); goto end; @@ -50,7 +50,7 @@ int spl_load_image_ext(block_dev_desc_t *block_dev, spl_parse_image_header(header); - err = ext4fs_read((char *)spl_image.load_addr, filelen); + err = ext4fs_read((char *)spl_image.load_addr, filelen, &actlen); end: #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT @@ -66,7 +66,7 @@ end: int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition) { int err; - int filelen; + __maybe_unused loff_t filelen, actlen; disk_partition_t part_info = {}; __maybe_unused char *file; @@ -89,12 +89,12 @@ int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition) #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT) file = getenv("falcon_args_file"); if (file) { - filelen = err = ext4fs_open(file); + err = ext4fs_open(file, &filelen); if (err < 0) { puts("spl: ext4fs_open failed\n"); goto defaults; } - err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, filelen); + err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, filelen, &actlen); if (err <= 0) { printf("spl: error reading image %s, err - %d, falling back to default\n", file, err); @@ -119,11 +119,11 @@ int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition) defaults: #endif - filelen = err = ext4fs_open(CONFIG_SPL_FS_LOAD_ARGS_NAME); + err = ext4fs_open(CONFIG_SPL_FS_LOAD_ARGS_NAME, &filelen); if (err < 0) puts("spl: ext4fs_open failed\n"); - err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, filelen); + err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, filelen, &actlen); if (err <= 0) { #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT printf("%s: error reading image %s, err - %d\n", diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index cccc06a888..cab5465b9d 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 5fa1719f2e..48fd2ac51d 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 648a59672c..f7c52cc4cc 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 87d5128518..d82266f7f3 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,31 @@ 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) { - return ext4fs_open(filename); + loff_t size; + int ret; + + ret = ext4fs_open(filename, &size); + if (ret) + return ret; + else + return 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, @@ -210,16 +219,17 @@ int ext4fs_probe(block_dev_desc_t *fs_dev_desc, int ext4_read_file(const char *filename, void *buf, int offset, int len) { - int file_len; - int len_read; + loff_t file_len; + loff_t len_read; + 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,9 +237,12 @@ 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; + if (ret) + return ret; + else + return len_read; } int ext4fs_uuid(char *uuid_str) diff --git a/include/ext4fs.h b/include/ext4fs.h index 38970e4817..5c524a6d87 100644 --- a/include/ext4fs.h +++ b/include/ext4fs.h @@ -125,12 +125,14 @@ 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); -- cgit v1.2.1