From 2be14d09a2191d488014dc56cad01035fe6e2f3f Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 14 Mar 2015 17:33:48 -0600 Subject: [PATCH] Fix a bug in the FAT unbind() logic. There were problems with the way certain internal list handling was implemented. The end result is that newly opened or cloned file structures were never being added to the list of open files. So when the unmount() happens, it always looked like there were not open files and a crash could ensue. --- fs/fat/fs_fat32.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/fat/fs_fat32.c b/fs/fat/fs_fat32.c index 7dd24c7337..eb64e83ee5 100644 --- a/fs/fat/fs_fat32.c +++ b/fs/fat/fs_fat32.c @@ -353,7 +353,7 @@ static int fat_open(FAR struct file *filep, const char *relpath, */ ff->ff_next = fs->fs_head; - fs->fs_head = ff->ff_next; + fs->fs_head = ff; fat_semgive(fs); @@ -391,6 +391,8 @@ static int fat_close(FAR struct file *filep) { struct inode *inode; struct fat_file_s *ff; + struct fat_file_s *currff; + struct fat_file_s *prevff; struct fat_mountpt_s *fs; int ret; @@ -412,6 +414,26 @@ static int fat_close(FAR struct file *filep) ret = fat_sync(filep); + /* Remove the file structure from the list of open files in the mountpoint + * structure. + */ + + for (prevff = NULL, currff = fs->fs_head; + currff && currff != ff; + prevff = currff, currff = currff->ff_next); + + if (currff) + { + if (prevff) + { + prevff->ff_next = ff->ff_next; + } + else + { + fs->fs_head = ff->ff_next; + } + } + /* Then deallocate the memory structures created when the open method * was called. * @@ -1408,7 +1430,7 @@ static int fat_dup(FAR const struct file *oldp, FAR struct file *newp) */ newff->ff_next = fs->fs_head; - fs->fs_head = newff->ff_next; + fs->fs_head = newff; fat_semgive(fs); return OK;