fat: Prepare API change for files greater than 2GB
Change the internal FAT functions to use loff_t for offsets.
Signed-off-by: Suriyan Ramasami <suriyan.r@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
[trini: Fix fs/fat/fat.c for min3 updates]
Signed-off-by: Tom Rini <trini@ti.com>
diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c
index 76fe857..f3f70ff 100644
--- a/board/esd/common/auto_update.c
+++ b/board/esd/common/auto_update.c
@@ -31,9 +31,6 @@
#define MAX_LOADSZ 0x1c00000
/* externals */
-extern int fat_register_device(block_dev_desc_t *, int);
-extern int file_fat_detectfs(void);
-extern long file_fat_read(const char *, void *, unsigned long);
long do_fat_read (const char *filename, void *buffer,
unsigned long maxsize, int dols);
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index 633fbf1..c00fb28 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -100,7 +100,8 @@
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 @@
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 < 0) {
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/env_fat.c b/common/env_fat.c
index 8db0160..e4c8489 100644
--- a/common/env_fat.c
+++ b/common/env_fat.c
@@ -41,6 +41,7 @@
disk_partition_t info;
int dev, part;
int err;
+ loff_t size;
err = env_export(&env_new);
if (err)
@@ -59,7 +60,8 @@
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, 0, 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/fat/fat.c b/fs/fat/fat.c
index 0481de3..83d9ce7 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -317,32 +317,32 @@
/*
* 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 +352,7 @@
if (CHECK_CLUST(curclust, mydata->fatsize)) {
debug("curclust: 0x%x\n", curclust);
debug("Invalid FAT entry\n");
- return gotsize;
+ return 0;
}
actsize += bytesperclust;
}
@@ -364,7 +364,7 @@
/* align to beginning of next cluster if any */
if (pos) {
- actsize = min(filesize, (unsigned long)bytesperclust);
+ actsize = min(filesize, (loff_t)bytesperclust);
if (get_cluster(mydata, curclust, get_contents_vfatname_block,
(int)actsize) != 0) {
printf("Error reading cluster\n");
@@ -373,16 +373,16 @@
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 +398,7 @@
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 +410,14 @@
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 +425,7 @@
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 +633,8 @@
}
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 +690,8 @@
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",
@@ -806,9 +806,8 @@
__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 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 +820,7 @@
__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 +973,8 @@
}
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 +1031,8 @@
}
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 +1101,7 @@
if (dols == LS_ROOT) {
printf("\n%d file(s), %d dir(s)\n\n",
files, dirs);
- ret = 0;
+ *size = 0;
}
goto exit;
}
@@ -1141,7 +1140,7 @@
if (get_dentfromdir(mydata, startsect, subname, dentptr,
isdir ? 0 : dols) == NULL) {
if (dols && !isdir)
- ret = 0;
+ *size = 0;
goto exit;
}
@@ -1152,21 +1151,23 @@
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 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 +1234,64 @@
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)
{
- return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1);
+ 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;
}
-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, int maxsize)
{
- return file_fat_read_at(filename, 0, buffer, maxsize);
+ loff_t actread;
+ int ret;
+
+ ret = file_fat_read_at(filename, 0, buffer, maxsize, &actread);
+ if (ret)
+ return ret;
+ else
+ return actread;
}
int fat_read_file(const char *filename, void *buf, int offset, int len)
{
- int len_read;
+ int ret;
+ loff_t actread;
- 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) {
printf("** Unable to read file %s **\n", filename);
- return -1;
+ return ret;
}
- return len_read;
+ return actread;
}
void fat_close(void)
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 24ed5d3..88dd495 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -660,24 +660,26 @@
/*
* 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 @@
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 remaining bytes */
- gotsize += (int)actsize;
+ *gotsize += actsize;
filesize -= actsize;
buffer += actsize;
actsize = filesize;
@@ -715,7 +717,7 @@
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 @@
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 @@
* 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;
@@ -923,8 +925,8 @@
return NULL;
}
-static int do_fat_write(const char *filename, void *buffer,
- unsigned long size)
+static int do_fat_write(const char *filename, void *buffer, loff_t size,
+ loff_t *actwrite)
{
dir_entry *dentptr, *retdent;
__u32 startsect;
@@ -936,8 +938,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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..8970611 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -162,8 +162,7 @@
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, int maxsize)
{
char fullpath[1024];
const char *arg;
diff --git a/include/fat.h b/include/fat.h
index 20ca3f3..99c6429 100644
--- a/include/fat.h
+++ b/include/fat.h
@@ -178,8 +178,8 @@
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,
+ int maxsize);
struct filesystem {
file_detectfs_func *detect;
@@ -199,14 +199,15 @@
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 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);
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 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);
void fat_close(void);
#endif /* _FAT_H_ */