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 <suriyan.r@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
[trini: Update common/spl/spl_ext.c]
Signed-off-by: Tom Rini <trini@ti.com>
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 @@
 
 #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 @@
 	   "<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/spl/spl_ext.c b/common/spl/spl_ext.c
index d9eba5a..5ff9bc5 100644
--- a/common/spl/spl_ext.c
+++ b/common/spl/spl_ext.c
@@ -15,7 +15,7 @@
 {
 	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 @@
 		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 @@
 
 	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 @@
 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 @@
 #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 @@
 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 cccc06a..cab5465 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -1892,6 +1892,7 @@
 {
 	unsigned int fpos = 0;
 	int status;
+	loff_t actread;
 	struct ext2fs_node *diro = (struct ext2fs_node *) dir;
 
 #ifdef DEBUG
@@ -1909,8 +1910,8 @@
 
 		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 @@
 			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 @@
 					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 @@
 	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 @@
 	} 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 @@
 	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 @@
 		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 @@
 
 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 @@
 
 	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 87d5128..d82266f 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -45,8 +45,8 @@
  * 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 @@
 		previous_block_number = -1;
 	}
 
-	return len;
+	*actread  = len;
+	return 0;
 }
 
 int ext4fs_ls(const char *dirname)
@@ -176,23 +177,31 @@
 
 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 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 @@
 	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 38970e4..5c524a6 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -125,12 +125,14 @@
 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);