diff options
Diffstat (limited to 'nuttx/fs/nxffs/nxffs_open.c')
-rw-r--r-- | nuttx/fs/nxffs/nxffs_open.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c index 604d1a0f4..0c101b78e 100644 --- a/nuttx/fs/nxffs/nxffs_open.c +++ b/nuttx/fs/nxffs/nxffs_open.c @@ -702,15 +702,15 @@ errout: } /**************************************************************************** - * Name: nxffs_freeofile + * Name: nxffs_remofile * * Description: - * Free resources held by an open file. + * Remove an entry from the open file list. * ****************************************************************************/ -static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume, - FAR struct nxffs_ofile_s *ofile) +static inline void nxffs_remofile(FAR struct nxffs_volume_s *volume, + FAR struct nxffs_ofile_s *ofile) { FAR struct nxffs_ofile_s *prev; FAR struct nxffs_ofile_s *curr; @@ -735,25 +735,37 @@ static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume, { volume->ofiles = ofile->flink; } + } + else + { + fdbg("ERROR: Open inode %p not found\n", ofile); + } +} + +/**************************************************************************** + * Name: nxffs_freeofile + * + * Description: + * Free resources held by an open file. + * + ****************************************************************************/ - /* Release the open file entry */ +static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume, + FAR struct nxffs_ofile_s *ofile) +{ + /* Release the open file entry */ - nxffs_freeentry(&ofile->entry); + nxffs_freeentry(&ofile->entry); - /* Then free the open file container (unless this the pre-alloated - * write-only open file container) - */ + /* Then free the open file container (unless this the pre-alloated + * write-only open file container) + */ #ifdef CONFIG_NXFSS_PREALLOCATED - if ((FAR struct nxffs_wrfile_s*)ofile != &g_wrfile) + if ((FAR struct nxffs_wrfile_s*)ofile != &g_wrfile) #endif - { - kfree(ofile); - } - } - else { - fdbg("ERROR: Open inode %p not found\n", ofile); + kfree(ofile); } } @@ -797,6 +809,13 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume, } } + /* Truncation is implemented by writing the new file, then deleting the + * older version of the file. Note that we removed the entry from the + * open file list earlier in the close sequence; this will prevent the + * open file check from failing when we remove the old version of the + * file. + */ + if (wrfile->truncate && wrfile->ofile.entry.name) { fvdbg("Removing old file: %s\n", wrfile->ofile.entry.name); @@ -1059,16 +1078,22 @@ int nxffs_close(FAR struct file *filep) ret = OK; if (ofile->crefs == 1) { - /* Decrementing the reference count would take it zero. Handle - * finalization of the write operation. + /* Decrementing the reference count would take it zero. + * + * Remove the entry from the open file list. We do this early + * to avoid some chick-and-egg problems with file truncation. */ + nxffs_remofile(volume, ofile); + + /* Handle special finalization of the write operation. */ + if (ofile->mode == O_WROK) { ret = nxffs_wrclose(volume, (FAR struct nxffs_wrfile_s *)ofile); } - /* Delete the open file state structure */ + /* Release all resouces held by the open file */ nxffs_freeofile(volume, ofile); } |