fs: API changes enabling extra parameter to return size of type loff_t
authorSuriyan Ramasami <suriyan.r@gmail.com>
Mon, 17 Nov 2014 22:39:38 +0000 (14:39 -0800)
committerTom Rini <trini@ti.com>
Sun, 23 Nov 2014 11:49:04 +0000 (06:49 -0500)
The sandbox/ext4/fat/generic fs commands do not gracefully deal with files
greater than 2GB. Negative values are returned in such cases.

To handle 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@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
[trini: Update board/gdsys/p1022/controlcenterd-id.c,
drivers/fpga/zynqpl.c for changes]
Signed-off-by: Tom Rini <trini@ti.com>
board/gdsys/p1022/controlcenterd-id.c
common/cmd_fs.c
drivers/fpga/zynqpl.c
fs/ext4/ext4fs.c
fs/fat/fat.c
fs/fs.c
fs/sandbox/sandboxfs.c
include/ext4fs.h
include/fat.h
include/fs.h
include/sandboxfs.h

index 317669b9ab180190207c70ec5258520f461fd2e8..11d075c38593c91d0ce588ff7c11ee56796427fd 100644 (file)
@@ -932,11 +932,12 @@ static struct key_program *load_key_chunk(const char *ifname,
        struct key_program header;
        uint32_t crc;
        uint8_t buf[12];
-       int i;
+       loff_t i;
 
        if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
                goto failure;
-       i = fs_read(path, (ulong)buf, 0, 12);
+       if (fs_read(path, (ulong)buf, 0, 12, &i) < 0)
+               goto failure;
        if (i < 12)
                goto failure;
        header.magic = get_unaligned_be32(buf);
@@ -951,8 +952,9 @@ static struct key_program *load_key_chunk(const char *ifname,
                goto failure;
        if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
                goto failure;
-       i = fs_read(path, (ulong)result, 0,
-               sizeof(struct key_program) + header.code_size);
+       if (fs_read(path, (ulong)result, 0,
+                   sizeof(struct key_program) + header.code_size, &i) < 0)
+               goto failure;
        if (i <= 0)
                goto failure;
        *result = header;
@@ -1043,7 +1045,7 @@ static int second_stage_init(void)
        const char *image_path = "/ccdm.itb";
        char *mac_path = NULL;
        ulong image_addr;
-       size_t image_size;
+       loff_t image_size;
        uint32_t err;
 
        printf("CCDM S2\n");
@@ -1085,10 +1087,11 @@ static int second_stage_init(void)
        image_addr = (ulong)get_image_location();
        if (fs_set_blk_dev("mmc", mmcdev, FS_TYPE_EXT))
                goto failure;
-       image_size = fs_read(image_path, image_addr, 0, 0);
+       if (fs_read(image_path, image_addr, 0, 0, &image_size) < 0)
+               goto failure;
        if (image_size <= 0)
                goto failure;
-       printf("CCDM image found on %s, %d bytes\n", mmcdev, image_size);
+       printf("CCDM image found on %s, %lld bytes\n", mmcdev, image_size);
 
        hmac_blob = load_key_chunk("mmc", mmcdev, FS_TYPE_EXT, mac_path);
        if (!hmac_blob) {
index 675434078633400ff85866e4c7554458412b7dc1..0d9da113bf0c1305bc64e7e67368d6eba800b5e0 100644 (file)
@@ -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(
+       save,   7,      0,      do_save_wrapper,
+       "save file to a filesystem",
+       "<interface> <dev[:part]> <addr> <filename> bytes [pos]\n"
+       "    - Save binary file 'filename' to partition 'part' on device\n"
+       "      type 'interface' instance 'dev' from addr 'addr' in memory.\n"
+       "      '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[])
 {
index 68fe0f3b03afb99085fada927806cbe7afca6407..6a74f8961063c278a4088616e0a512ff75ddbeaa 100644 (file)
@@ -406,8 +406,8 @@ static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
        unsigned long ts; /* Timestamp */
        u32 isr_status, swap;
        u32 partialbit = 0;
-       u32 blocksize;
-       u32 pos = 0;
+       loff_t blocksize, actread;
+       loff_t pos = 0;
        int fstype;
        char *interface, *dev_part, *filename;
 
@@ -420,7 +420,7 @@ static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
        if (fs_set_blk_dev(interface, dev_part, fstype))
                return FPGA_FAIL;
 
-       if (fs_read(filename, (u32) buf, pos, blocksize) < 0)
+       if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
                return FPGA_FAIL;
 
        if (zynq_validate_bitstream(desc, buf, bsize, blocksize, &swap,
@@ -443,10 +443,10 @@ static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
                        return FPGA_FAIL;
 
                if (bsize > blocksize) {
-                       if (fs_read(filename, (u32) buf, pos, blocksize) < 0)
+                       if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
                                return FPGA_FAIL;
                } else {
-                       if (fs_read(filename, (u32) buf, pos, bsize) < 0)
+                       if (fs_read(filename, (u32) buf, pos, bsize, &actread) < 0)
                                return FPGA_FAIL;
                }
        } while (bsize > blocksize);
index d82266f7f39136370ca9be7593ee3529538719f5..943b5bcf35e903382dbc7f928d6577b6874c51c4 100644 (file)
@@ -184,16 +184,9 @@ int ext4fs_exists(const char *filename)
        return ret == 0;
 }
 
-int ext4fs_size(const char *filename)
+int ext4fs_size(const char *filename, loff_t *size)
 {
-       loff_t  size;
-       int ret;
-
-       ret = ext4fs_open(filename, &size);
-       if (ret)
-               return ret;
-       else
-               return size;
+       return ext4fs_open(filename, size);
 }
 
 int ext4fs_read(char *buf, loff_t len, loff_t *actread)
@@ -217,10 +210,10 @@ 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)
 {
        loff_t file_len;
-       loff_t len_read;
        int ret;
 
        if (offset != 0) {
@@ -237,12 +230,7 @@ int ext4_read_file(const char *filename, void *buf, int offset, int len)
        if (len == 0)
                len = file_len;
 
-       ret = ext4fs_read(buf, len, &len_read);
-
-       if (ret)
-               return ret;
-       else
-               return len_read;
+       return ext4fs_read(buf, len, len_read);
 }
 
 int ext4fs_uuid(char *uuid_str)
index 83d9ce7c5776c88b5e8764579c14430a6cdf448b..04a51db6d4cd9e278cdf09959af2f86408864278 100644 (file)
@@ -1248,16 +1248,9 @@ int fat_exists(const char *filename)
        return ret == 0;
 }
 
-int fat_size(const char *filename)
+int fat_size(const char *filename, loff_t *size)
 {
-       loff_t size;
-       int ret;
-
-       ret = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, &size);
-       if (ret)
-               return ret;
-       else
-               return size;
+       return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, size);
 }
 
 int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
@@ -1280,18 +1273,16 @@ int file_fat_read(const char *filename, void *buffer, int maxsize)
                return 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 ret;
-       loff_t actread;
 
-       ret = file_fat_read_at(filename, offset, buf, len, &actread);
-       if (ret) {
+       ret = file_fat_read_at(filename, offset, buf, len, actread);
+       if (ret)
                printf("** Unable to read file %s **\n", filename);
-               return ret;
-       }
 
-       return actread;
+       return ret;
 }
 
 void fat_close(void)
diff --git a/fs/fs.c b/fs/fs.c
index e4ad6bc3308d77dab534bc1fcd969ad68d037fb8..3da78606d1281f93ebe3108b9a7bd8f6e5f31edc 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -47,19 +47,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;
 }
@@ -88,9 +90,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);
        int (*uuid)(char *uuid_str);
 };
@@ -106,7 +110,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
                .uuid = fs_uuid_unsupported,
        },
 #endif
@@ -120,7 +128,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
                .uuid = ext4fs_uuid,
        },
 #endif
@@ -251,20 +263,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;
@@ -275,11 +288,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;
        }
@@ -288,17 +301,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;
        }
@@ -310,7 +324,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;
@@ -318,8 +332,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);
@@ -333,9 +346,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;
 
@@ -377,12 +391,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");
@@ -426,9 +440,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)
@@ -437,8 +452,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);
@@ -446,12 +461,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");
index d11c087cc169c6db7b23adb784b3d3f08df8961a..a920bc087712ff289c65eec948f0f234229f9f5c 100644 (file)
@@ -103,46 +103,35 @@ int sandbox_fs_exists(const char *filename)
        return ret == 0;
 }
 
-int sandbox_fs_size(const char *filename)
+int sandbox_fs_size(const char *filename, loff_t *size)
 {
-       loff_t size;
-       int ret;
-
-       ret = os_get_filesize(filename, &size);
-       if (ret)
-               return ret;
-       else
-               return size;
+       return os_get_filesize(filename, size);
 }
 
 void sandbox_fs_close(void)
 {
 }
 
-int fs_read_sandbox(const char *filename, void *buf, int offset, int len)
+int fs_read_sandbox(const char *filename, void *buf, loff_t offset, loff_t len,
+                   loff_t *actread)
 {
        int ret;
-       loff_t actread;
 
-       ret = sandbox_fs_read_at(filename, offset, buf, len, &actread);
-       if (ret) {
+       ret = sandbox_fs_read_at(filename, offset, buf, len, actread);
+       if (ret)
                printf("** Unable to read file %s **\n", filename);
-               return ret;
-       }
 
-       return actread;
+       return ret;
 }
 
-int fs_write_sandbox(const char *filename, void *buf, int offset, int len)
+int fs_write_sandbox(const char *filename, void *buf, loff_t offset,
+                    loff_t len, loff_t *actwrite)
 {
        int ret;
-       loff_t actwrite;
 
-       ret = sandbox_fs_write_at(filename, offset, buf, len, &actwrite);
-       if (ret) {
+       ret = sandbox_fs_write_at(filename, offset, buf, len, actwrite);
+       if (ret)
                printf("** Unable to write file %s **\n", filename);
-               return ret;
-       }
 
-       return actwrite;
+       return ret;
 }
index 5c524a6d87c2173bf1d57dbda3e7409c6d3572ee..6888adc56f406d1c40049e240f8dc727e4e97009 100644 (file)
@@ -138,14 +138,15 @@ 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);
 int ext4fs_uuid(char *uuid_str);
 #endif
index 99c64291b0664c6ef54f23e68054937774aa610e..3038bd7e4f6e7133af0c5149395438a810dc719a 100644 (file)
@@ -198,7 +198,7 @@ int file_cd(const char *path);
 int file_fat_detectfs(void);
 int file_fat_ls(const char *dir);
 int fat_exists(const char *filename);
-int fat_size(const char *filename);
+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, int maxsize);
@@ -208,6 +208,7 @@ int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
 
 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, int offset, int len);
+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_ */
index 491c60a7cb909114f5b63064157d1cde400dd02b..ffb6ce7ada64f0498b46eac89d6a335bea83c488 100644 (file)
@@ -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: Returns 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: Returns 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
index 8e5da6bc6b0242a654c8bbae5e447a98f14e63fc..4c7745de91002d503640631f234d470c00ada0ee 100644 (file)
@@ -28,8 +28,10 @@ int sandbox_fs_write_at(const char *filename, loff_t pos, void *buffer,
 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 *actread);
+int fs_write_sandbox(const char *filename, void *buf, loff_t offset,
+                    loff_t len, loff_t *actwrite);
 
 #endif