When unmounting FAT volumes, close all open file handles and flush buffers to disk Return accurate counts of closed/released file handles and directories in close_files, release_files, and release_dirs --- firmware/common/dir_uncached.c | 7 +++++-- firmware/common/disk.c | 22 ++++++++++++++-------- firmware/common/file.c | 31 +++++++++++++++++++++++++++++-- firmware/include/file.h | 1 + 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c index 00123c1..fd5df41 100644 --- a/firmware/common/dir_uncached.c +++ b/firmware/common/dir_uncached.c @@ -50,8 +50,11 @@ int release_dirs(int volume) (void)volume; #endif { - pdir->busy = false; /* mark as available, no further action */ - closed++; + if (pdir->busy) + { + pdir->busy = false; /* mark as available, no further action */ + closed++; + } } } return closed; /* return how many we did */ diff --git a/firmware/common/disk.c b/firmware/common/disk.c index a23d51d..397b21b 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c @@ -263,19 +263,25 @@ int disk_unmount(int drive) int disk_unmount_all(void) { -#ifndef HAVE_MULTIDRIVE - return disk_unmount(0); -#else /* HAVE_MULTIDRIVE */ int unmounted = 0; int i; - for (i = 0; i < NUM_DRIVES; i++) - { #ifdef HAVE_HOTSWAP - if (storage_present(i)) + mutex_lock(&disk_mutex); #endif - unmounted += disk_unmount(i); + for (i=0; i= 0) + { + vol_drive[i] = -1; /* mark unused */ + unmounted++; + close_files(i); + release_dirs(i); + fat_unmount(i, true); + } } +#ifdef HAVE_HOTSWAP + mutex_unlock(&disk_mutex); +#endif return unmounted; -#endif /* HAVE_MULTIDRIVE */ } diff --git a/firmware/common/file.c b/firmware/common/file.c index 3477c10..9096587 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -807,8 +807,35 @@ int release_files(int volume) (void)volume; #endif { - pfile->busy = false; /* mark as available, no further action */ - closed++; + if (pfile->busy) + { + pfile->busy = false; /* mark as available, no further action */ + closed++; + } + } + } + return closed; /* return how many we did */ +} + +/* close all file handles on volume, flush dirty data */ +int close_files(int volume) +{ + struct filedesc* pfile = openfiles; + int fd; + int closed = 0; + for ( fd=0; fdfatfile.volume == volume) +#else + (void)volume; +#endif + { + if (pfile->busy) + { + close(fd); + closed++; + } } } return closed; /* return how many we did */ diff --git a/firmware/include/file.h b/firmware/include/file.h index ee52c3f..fc9aa32 100644 --- a/firmware/include/file.h +++ b/firmware/include/file.h @@ -101,6 +101,7 @@ extern int rename(const char* path, const char* newname); extern int ftruncate(int fd, off_t length); extern off_t filesize(int fd); extern int release_files(int volume); +extern int close_files(int volume); int fdprintf (int fd, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); #endif /* !CODEC && !PLUGIN */ #endif -- 1.7.1