diff options
-rw-r--r-- | firmware/common/file.c | 42 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 36 | ||||
-rw-r--r-- | firmware/drivers/fat.h | 3 |
3 files changed, 57 insertions, 24 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index 1dd71d98ae..b2c2644725 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -38,7 +38,7 @@ | |||
38 | struct filedesc { | 38 | struct filedesc { |
39 | unsigned char cache[SECTOR_SIZE]; | 39 | unsigned char cache[SECTOR_SIZE]; |
40 | int cacheoffset; | 40 | int cacheoffset; |
41 | int fileoffset; | 41 | unsigned int fileoffset; |
42 | int size; | 42 | int size; |
43 | struct fat_file fatfile; | 43 | struct fat_file fatfile; |
44 | bool busy; | 44 | bool busy; |
@@ -178,7 +178,7 @@ int close(int fd) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | /* tie up all loose ends */ | 180 | /* tie up all loose ends */ |
181 | fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].fileoffset); | 181 | fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size); |
182 | } | 182 | } |
183 | openfiles[fd].busy = false; | 183 | openfiles[fd].busy = false; |
184 | return rc; | 184 | return rc; |
@@ -191,7 +191,21 @@ int remove(const char* name) | |||
191 | if ( fd < 0 ) | 191 | if ( fd < 0 ) |
192 | return fd; | 192 | return fd; |
193 | 193 | ||
194 | rc = fat_truncate(&(openfiles[fd].fatfile)); | ||
195 | if ( rc < 0 ) { | ||
196 | DEBUGF("Failed truncating file\n"); | ||
197 | errno = EIO; | ||
198 | return -1; | ||
199 | } | ||
200 | |||
194 | rc = fat_remove(&(openfiles[fd].fatfile)); | 201 | rc = fat_remove(&(openfiles[fd].fatfile)); |
202 | if ( rc < 0 ) { | ||
203 | DEBUGF("Failed removing file\n"); | ||
204 | errno = EIO; | ||
205 | return -2; | ||
206 | } | ||
207 | |||
208 | openfiles[fd].size = 0; | ||
195 | 209 | ||
196 | close(fd); | 210 | close(fd); |
197 | 211 | ||
@@ -259,7 +273,7 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
259 | if ( rc < 0 ) { | 273 | if ( rc < 0 ) { |
260 | DEBUGF("Failed read/writing %d sectors\n",sectors); | 274 | DEBUGF("Failed read/writing %d sectors\n",sectors); |
261 | errno = EIO; | 275 | errno = EIO; |
262 | return -2; | 276 | return -3; |
263 | } | 277 | } |
264 | else { | 278 | else { |
265 | if ( rc > 0 ) { | 279 | if ( rc > 0 ) { |
@@ -278,10 +292,30 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
278 | openfiles[fd].cacheoffset = -1; | 292 | openfiles[fd].cacheoffset = -1; |
279 | } | 293 | } |
280 | } | 294 | } |
295 | openfiles[fd].fileoffset += nread; | ||
296 | nread = 0; | ||
281 | 297 | ||
282 | /* any tail bytes? */ | 298 | /* any tail bytes? */ |
283 | if ( count ) { | 299 | if ( count ) { |
284 | if (write) { | 300 | if (write) { |
301 | /* sector is only partially filled. copy-back from disk */ | ||
302 | int rc; | ||
303 | LDEBUGF("Copy-back tail cache\n"); | ||
304 | rc = fat_readwrite(&(openfiles[fd].fatfile), 1, | ||
305 | openfiles[fd].cache, false ); | ||
306 | if ( rc < 0 ) { | ||
307 | DEBUGF("Failed reading\n"); | ||
308 | errno = EIO; | ||
309 | return -4; | ||
310 | } | ||
311 | /* seek back one sector to put file position right */ | ||
312 | rc = fat_seek(&(openfiles[fd].fatfile), | ||
313 | openfiles[fd].fileoffset / SECTOR_SIZE); | ||
314 | if ( rc < 0 ) { | ||
315 | DEBUGF("fat_seek() failed\n"); | ||
316 | errno = EIO; | ||
317 | return -5; | ||
318 | } | ||
285 | memcpy( openfiles[fd].cache, buf + nread, count ); | 319 | memcpy( openfiles[fd].cache, buf + nread, count ); |
286 | } | 320 | } |
287 | else { | 321 | else { |
@@ -289,7 +323,7 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
289 | &(openfiles[fd].cache),false) < 1 ) { | 323 | &(openfiles[fd].cache),false) < 1 ) { |
290 | DEBUGF("Failed caching sector\n"); | 324 | DEBUGF("Failed caching sector\n"); |
291 | errno = EIO; | 325 | errno = EIO; |
292 | return -1; | 326 | return -6; |
293 | } | 327 | } |
294 | memcpy( buf + nread, openfiles[fd].cache, count ); | 328 | memcpy( buf + nread, openfiles[fd].cache, count ); |
295 | } | 329 | } |
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 47bfd1afef..74bdbd3491 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -167,7 +167,7 @@ static unsigned int getcurrdostime(unsigned short *dosdate, | |||
167 | unsigned short *dostime, | 167 | unsigned short *dostime, |
168 | unsigned char *dostenth); | 168 | unsigned char *dostenth); |
169 | static int create_dos_name(unsigned char *name, unsigned char *newname); | 169 | static int create_dos_name(unsigned char *name, unsigned char *newname); |
170 | static int find_free_cluster(int start); | 170 | static unsigned int find_free_cluster(unsigned int start); |
171 | #endif | 171 | #endif |
172 | 172 | ||
173 | #define FAT_CACHE_SIZE 0x20 | 173 | #define FAT_CACHE_SIZE 0x20 |
@@ -438,10 +438,10 @@ static void *cache_fat_sector(int fatsector) | |||
438 | return sectorbuf; | 438 | return sectorbuf; |
439 | } | 439 | } |
440 | 440 | ||
441 | static int find_free_cluster(int startcluster) | 441 | static unsigned int find_free_cluster(unsigned int startcluster) |
442 | { | 442 | { |
443 | int sector = startcluster / CLUSTERS_PER_FAT_SECTOR; | 443 | unsigned int sector = startcluster / CLUSTERS_PER_FAT_SECTOR; |
444 | int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; | 444 | unsigned int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; |
445 | int i; | 445 | int i; |
446 | 446 | ||
447 | /* don't waste time scanning if the disk is already full */ | 447 | /* don't waste time scanning if the disk is already full */ |
@@ -511,7 +511,7 @@ static int update_fat_entry(unsigned int entry, unsigned int val) | |||
511 | return 0; | 511 | return 0; |
512 | } | 512 | } |
513 | 513 | ||
514 | static int read_fat_entry(int entry) | 514 | static int read_fat_entry(unsigned int entry) |
515 | { | 515 | { |
516 | int sector = entry / CLUSTERS_PER_FAT_SECTOR; | 516 | int sector = entry / CLUSTERS_PER_FAT_SECTOR; |
517 | int offset = entry % CLUSTERS_PER_FAT_SECTOR; | 517 | int offset = entry % CLUSTERS_PER_FAT_SECTOR; |
@@ -998,24 +998,23 @@ int fat_create_file(char* name, | |||
998 | return err; | 998 | return err; |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | int fat_closewrite(struct fat_file *file, int size) | 1001 | int fat_truncate(struct fat_file *file) |
1002 | { | 1002 | { |
1003 | int next, last = file->lastcluster; | ||
1004 | int endcluster = last; | ||
1005 | |||
1006 | LDEBUGF("fat_closewrite(size=%d, last=%x)\n",size, last); | ||
1007 | |||
1008 | /* truncate trailing clusters */ | 1003 | /* truncate trailing clusters */ |
1009 | last = get_next_cluster(last); | 1004 | int next; |
1005 | int last = get_next_cluster(file->lastcluster); | ||
1010 | while ( last && last != FAT_EOF_MARK ) { | 1006 | while ( last && last != FAT_EOF_MARK ) { |
1011 | next = get_next_cluster(last); | 1007 | next = get_next_cluster(last); |
1012 | update_fat_entry(last,0); | 1008 | update_fat_entry(last,0); |
1013 | last = next; | 1009 | last = next; |
1014 | } | 1010 | } |
1015 | 1011 | ||
1016 | /* if no cluster was written, size is 0 */ | 1012 | return 0; |
1017 | if (!endcluster) | 1013 | } |
1018 | size = 0; | 1014 | |
1015 | int fat_closewrite(struct fat_file *file, int size) | ||
1016 | { | ||
1017 | LDEBUGF("fat_closewrite(size=%d)\n",size); | ||
1019 | 1018 | ||
1020 | if (!size) { | 1019 | if (!size) { |
1021 | /* empty file */ | 1020 | /* empty file */ |
@@ -1024,18 +1023,17 @@ int fat_closewrite(struct fat_file *file, int size) | |||
1024 | file->firstcluster = 0; | 1023 | file->firstcluster = 0; |
1025 | } | 1024 | } |
1026 | } | 1025 | } |
1027 | else | ||
1028 | update_fat_entry(endcluster, FAT_EOF_MARK); | ||
1029 | 1026 | ||
1030 | if (file->dirsector) | 1027 | if (file->dirsector) |
1031 | update_dir_entry(file, size); | 1028 | update_dir_entry(file, size); |
1032 | flush_fat(); | 1029 | flush_fat(); |
1033 | 1030 | ||
1034 | #ifdef TEST_FAT | 1031 | #ifdef TEST_FAT |
1035 | { | 1032 | if ( file->firstcluster ) { |
1036 | /* debug */ | 1033 | /* debug */ |
1037 | int count = 0; | 1034 | int count = 0; |
1038 | int len; | 1035 | int len; |
1036 | int next; | ||
1039 | for ( next = file->firstcluster; next; | 1037 | for ( next = file->firstcluster; next; |
1040 | next = get_next_cluster(next) ) | 1038 | next = get_next_cluster(next) ) |
1041 | LDEBUGF("cluster %d: %x\n", count++, next); | 1039 | LDEBUGF("cluster %d: %x\n", count++, next); |
@@ -1213,7 +1211,7 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
1213 | return i; | 1211 | return i; |
1214 | } | 1212 | } |
1215 | 1213 | ||
1216 | int fat_seek(struct fat_file *file, int seeksector ) | 1214 | int fat_seek(struct fat_file *file, unsigned int seeksector ) |
1217 | { | 1215 | { |
1218 | int clusternum=0, sectornum=0, sector=0; | 1216 | int clusternum=0, sectornum=0, sector=0; |
1219 | int cluster = file->firstcluster; | 1217 | int cluster = file->firstcluster; |
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h index 6ed68ad8d8..b23d8dfa08 100644 --- a/firmware/drivers/fat.h +++ b/firmware/drivers/fat.h | |||
@@ -79,8 +79,9 @@ extern int fat_create_file(char* name, | |||
79 | extern int fat_readwrite(struct fat_file *ent, int sectorcount, | 79 | extern int fat_readwrite(struct fat_file *ent, int sectorcount, |
80 | void* buf, bool write ); | 80 | void* buf, bool write ); |
81 | extern int fat_closewrite(struct fat_file *ent, int size); | 81 | extern int fat_closewrite(struct fat_file *ent, int size); |
82 | extern int fat_seek(struct fat_file *ent, int sector ); | 82 | extern int fat_seek(struct fat_file *ent, unsigned int sector ); |
83 | extern int fat_remove(struct fat_file *ent); | 83 | extern int fat_remove(struct fat_file *ent); |
84 | extern int fat_truncate(struct fat_file *ent); | ||
84 | 85 | ||
85 | extern int fat_opendir(struct fat_dir *ent, unsigned int currdir); | 86 | extern int fat_opendir(struct fat_dir *ent, unsigned int currdir); |
86 | extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); | 87 | extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); |