forked from nuttx/nuttx-update
Add support for close and fsync
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@242 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
c567505d21
commit
624b98e244
6 changed files with 296 additions and 68 deletions
|
@ -77,7 +77,7 @@ int close(int fd)
|
|||
* may have been opened numerous times (for different file
|
||||
* descriptors) and must also handle being closed numerous times.
|
||||
* (3) for the case of the mountpoint, we depend on the close
|
||||
* methods bing identical in signal and position in the operations
|
||||
* methods bing identical in signature and position in the operations
|
||||
* vtable.
|
||||
*/
|
||||
|
||||
|
|
141
fs/fs_fat32.c
141
fs/fs_fat32.c
|
@ -75,6 +75,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer,
|
|||
size_t buflen);
|
||||
static off_t fat_seek(FAR struct file *filp, off_t offset, int whence);
|
||||
static int fat_ioctl(FAR struct file *filp, int cmd, unsigned long arg);
|
||||
static int fat_sync(FAR struct file *filp);
|
||||
static int fat_bind(FAR struct inode *blkdriver, const void *data,
|
||||
void **handle);
|
||||
static int fat_unbind(void *handle);
|
||||
|
@ -100,6 +101,7 @@ const struct mountpt_operations fat_operations =
|
|||
fat_write,
|
||||
fat_seek,
|
||||
fat_ioctl,
|
||||
fat_sync,
|
||||
fat_bind,
|
||||
fat_unbind
|
||||
};
|
||||
|
@ -326,12 +328,13 @@ static int fat_close(FAR struct file *filp)
|
|||
struct inode *inode;
|
||||
struct fat_mountpt_s *fs;
|
||||
struct fat_file_s *ff;
|
||||
int ret = OK;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(filp->f_priv != NULL && filp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from struct file instance */
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
ff = filp->f_priv;
|
||||
inode = filp->f_inode;
|
||||
|
@ -343,7 +346,26 @@ static int fat_close(FAR struct file *filp)
|
|||
* the file even when there is healthy mount.
|
||||
*/
|
||||
|
||||
return -ENOSYS;
|
||||
/* Synchronize the file buffers and disk content; update times */
|
||||
|
||||
ret = fat_sync(filp);
|
||||
|
||||
/* Then deallocate the memory structures created when the open method
|
||||
* was called.
|
||||
*
|
||||
* Free the sector buffer that was used to manage partial sector accesses.
|
||||
*/
|
||||
|
||||
if (ff->ff_buffer)
|
||||
{
|
||||
free(ff->ff_buffer);
|
||||
}
|
||||
|
||||
/* Then free the file structure itself. */
|
||||
|
||||
free(ff);
|
||||
filp->f_priv = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -361,14 +383,14 @@ static ssize_t fat_read(FAR struct file *filp, char *buffer, size_t buflen)
|
|||
unsigned int nsectors;
|
||||
size_t readsector;
|
||||
size_t bytesleft;
|
||||
char *userbuffer = buffer;
|
||||
ubyte *userbuffer = (ubyte*)buffer;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(filp->f_priv != NULL && filp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from struct file instance */
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
ff = filp->f_priv;
|
||||
inode = filp->f_inode;
|
||||
|
@ -564,7 +586,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer,
|
|||
|
||||
DEBUGASSERT(filp->f_priv != NULL && filp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from struct file instance */
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
ff = filp->f_priv;
|
||||
inode = filp->f_inode;
|
||||
|
@ -578,8 +600,11 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer,
|
|||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
fat_semgive(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fat_semgive(fs);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
@ -598,7 +623,7 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence)
|
|||
|
||||
DEBUGASSERT(filp->f_priv != NULL && filp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from struct file instance */
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
ff = filp->f_priv;
|
||||
inode = filp->f_inode;
|
||||
|
@ -612,8 +637,11 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence)
|
|||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
fat_semgive(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fat_semgive(fs);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
@ -632,7 +660,7 @@ static int fat_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
|
|||
|
||||
DEBUGASSERT(filp->f_priv != NULL && filp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from struct file instance */
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
ff = filp->f_priv;
|
||||
inode = filp->f_inode;
|
||||
|
@ -646,13 +674,112 @@ static int fat_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
|
|||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
fat_semgive(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ioctl calls are just passed through to the contained block driver */
|
||||
|
||||
fat_semgive(fs);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_sync
|
||||
*
|
||||
* Description: Synchronize the file state on disk to match internal, in-
|
||||
* memory state.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_sync(FAR struct file *filp)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct fat_mountpt_s *fs;
|
||||
struct fat_file_s *ff;
|
||||
uint32 wrttime;
|
||||
ubyte *direntry;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(filp->f_priv != NULL && filp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
ff = filp->f_priv;
|
||||
inode = filp->f_inode;
|
||||
fs = inode->i_private;
|
||||
|
||||
DEBUGASSERT(fs != NULL);
|
||||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
fat_semtake(fs);
|
||||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Check if the has been modified in any way */
|
||||
if ((ff->ff_bflags & FFBUFF_MODIFIED) != 0)
|
||||
{
|
||||
/* Flush any unwritten data in the file buffer */
|
||||
|
||||
ret = fat_ffcacheflush(fs, ff);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Update the directory entry. First read the directory
|
||||
* entry into the fs_buffer (preserving the ff_buffer)
|
||||
*/
|
||||
|
||||
ret = fat_fscacheread(fs, ff->ff_dirsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Recover a pointer to the specific directory entry
|
||||
* in the sector using the saved directory index.
|
||||
*/
|
||||
|
||||
direntry = &fs->fs_buffer[ff->ff_dirindex];
|
||||
|
||||
/* Set the archive bit, set the write time, and update
|
||||
* anything that may have* changed in the directory
|
||||
* entry: the file size, and the start cluster
|
||||
*/
|
||||
|
||||
direntry[DIR_ATTRIBUTES] |= FATATTR_ARCHIVE;
|
||||
|
||||
DIR_PUTFILESIZE(direntry, ff->ff_size);
|
||||
DIR_PUTFSTCLUSTLO(direntry, ff->ff_startcluster);
|
||||
DIR_PUTFSTCLUSTHI(direntry, ff->ff_startcluster >> 16);
|
||||
|
||||
wrttime = fat_gettime();
|
||||
DIR_PUTWRTTIME(direntry, wrttime);
|
||||
|
||||
/* Clear the modified bit in the flags */
|
||||
|
||||
ff->ff_bflags &= ~FFBUFF_MODIFIED;
|
||||
|
||||
/* Flush these change to disk and update FSINFO (if
|
||||
* appropriate.
|
||||
*/
|
||||
|
||||
fs->fs_dirty = TRUE;
|
||||
ret = fat_updatefsinfo(fs);
|
||||
}
|
||||
|
||||
errout_with_semaphore:
|
||||
fat_semgive(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_bind
|
||||
*
|
||||
|
|
|
@ -289,6 +289,12 @@
|
|||
# define DIR_GETFSTCLUSTLO(p) fat_getuint16(UBYTE_PTR(p,DIR_FSTCLUSTLO))
|
||||
# define DIR_GETFILESIZE(p) fat_getuint32(UBYTE_PTR(p,DIR_FILESIZE))
|
||||
|
||||
# define FSI_GETLEADSIG(p) fat_getuint32(UBYTE_PTR(p,FSI_LEADSIG))
|
||||
# define FSI_GETSTRUCTSIG(p) fat_getuint32(UBYTE_PTR(p,FSI_STRUCTSIG))
|
||||
# define FSI_GETFREECOUNT(p) fat_getuint32(UBYTE_PTR(p,FSI_FREECOUNT))
|
||||
# define FSI_GETNXTFREE(p) fat_getuint32(UBYTE_PTR(p,FSI_NXTFREE))
|
||||
# define FSI_GETTRAILSIG(p) fat_getuint32(UBYTE_PTR(p,FSI_TRAILSIG))
|
||||
|
||||
# define FAT_GETFAT16(p,i) fat_getuint16(UBYTE_PTR(p,i))
|
||||
# define FAT_GETFAT32(p,i) fat_getuint32(UBYTE_PTR(p,i))
|
||||
|
||||
|
@ -321,6 +327,12 @@
|
|||
# define DIR_PUTFSTCLUSTLO(p,v) fat_putuint16(UBYTE_PTR(p,DIR_FSTCLUSTLO),v)
|
||||
# define DIR_PUTFILESIZE(p,v) fat_putuint32(UBYTE_PTR(p,DIR_FILESIZE),v)
|
||||
|
||||
# define FSI_PUTLEADSIG(p,v) fat_putuint32(UBYTE_PTR(p,FSI_LEADSIG),v)
|
||||
# define FSI_PUTSTRUCTSIG(p,v) fat_putuint32(UBYTE_PTR(p,FSI_STRUCTSIG),v)
|
||||
# define FSI_PUTFREECOUNT(p,v) fat_putuint32(UBYTE_PTR(p,FSI_FREECOUNT),v)
|
||||
# define FSI_PUTNXTFREE(p,v) fat_putuint32(UBYTE_PTR(p,FSI_NXTFREE),v)
|
||||
# define FSI_PUTTRAILSIG(p,v) fat_putuint32(UBYTE_PTR(p,FSI_TRAILSIG),v)
|
||||
|
||||
# define FAT_PUTFAT16(p,i,v) fat_putuint16(UBYTE_PTR(p,i),v)
|
||||
# define FAT_PUTFAT32(p,i,v) fat_putuint32(UBYTE_PTR(p,i),v)
|
||||
|
||||
|
@ -361,6 +373,12 @@
|
|||
# define DIR_GETFSTCLUSTLO(p) UINT16_VAL(p,DIR_FSTCLUSTLO)
|
||||
# define DIR_GETFILESIZE(p) UINT32_VAL(p,DIR_FILESIZE)
|
||||
|
||||
# define FSI_GETLEADSIG(p) UINT32_VAL(p,FSI_LEADSIG)
|
||||
# define FSI_GETSTRUCTSIG(p) UINT32_VAL(p,FSI_STRUCTSIG)
|
||||
# define FSI_GETFREECOUNT(p) UINT32_VAL(p,FSI_FREECOUNT)
|
||||
# define FSI_GETNXTFREE(p) UINT32_VAL(p,FSI_NXTFREE)
|
||||
# define FSI_GETTRAILSIG(p) UINT32_VAL(p,FSI_TRAILSIG)
|
||||
|
||||
# define FAT_GETFAT16(p,i) UINT16_VAL(p,i)
|
||||
# define FAT_GETFAT32(p,i) UINT32_VAL(p,i)
|
||||
|
||||
|
@ -393,6 +411,12 @@
|
|||
# define DIR_PUTFSTCLUSTLO(p,v) UINT16_PUT(p,DIR_FSTCLUSTLO,v)
|
||||
# define DIR_PUTFILESIZE(p,v) UINT32_PUT(p,DIR_FILESIZE,v)
|
||||
|
||||
# define FSI_PUTLEADSIG(p,v) UINT32_PUT(p,FSI_LEADSIG,v)
|
||||
# define FSI_PUTSTRUCTSIG(p,v) UINT32_PUT(p,FSI_STRUCTSIG,v)
|
||||
# define FSI_PUTFREECOUNT(p,v) UINT32_PUT(p,FSI_FREECOUNT,v)
|
||||
# define FSI_PUTNXTFREE(p,v) UINT32_PUT(p,FSI_NXTFREE,v)
|
||||
# define FSI_PUTTRAILSIG(p,v) UINT32_PUT(p,FSI_TRAILSIG,v)
|
||||
|
||||
# define FAT_PUTFAT16(p,i,v) UINT16_PUT(p,i,v)
|
||||
# define FAT_PUTFAT32(p,i,v) UINT32_PUT(p,i,v)
|
||||
|
||||
|
@ -430,6 +454,7 @@ struct fat_mountpt_s
|
|||
uint16 fs_rootentcnt; /* MBR: Count of 32-bit root directory entries */
|
||||
boolean fs_mounted; /* TRUE: The file system is ready */
|
||||
boolean fs_dirty; /* TRUE: fs_buffer is dirty */
|
||||
boolean fs_fsidirty; /* TRUE: FSINFO sector must be written to disk */
|
||||
ubyte fs_type; /* FSTYPE_FAT12, FSTYPE_FAT16, or FSTYPE_FAT32 */
|
||||
ubyte fs_fatnumfats; /* MBR: Number of FATs (probably 2) */
|
||||
ubyte fs_fatsecperclus; /* MBR: Sectors per allocation unit: 2**n, n=0..7 */
|
||||
|
@ -446,7 +471,7 @@ struct fat_file_s
|
|||
{
|
||||
struct fat_file_s *ff_next; /* Retained in a singly linked list */
|
||||
boolean ff_open; /* TRUE: The file is (still) open */
|
||||
boolean ff_bflags; /* The file buffer flags */
|
||||
ubyte ff_bflags; /* The file buffer flags */
|
||||
ubyte ff_oflags; /* Flags provided when file was opened */
|
||||
ubyte ff_sectorsincluster; /* Sectors remaining in cluster */
|
||||
uint16 ff_dirindex; /* Index into ff_dirsector to directory entry */
|
||||
|
@ -503,6 +528,10 @@ EXTERN void fat_putuint32(ubyte *ptr, uint32 value32);
|
|||
EXTERN void fat_semtake(struct fat_mountpt_s *fs);
|
||||
EXTERN void fat_semgive(struct fat_mountpt_s *fs);
|
||||
|
||||
/* Get the current time for FAT creation and write times */
|
||||
|
||||
EXTERN uint32 fat_gettime(void);
|
||||
|
||||
/* Handle hardware interactions for mounting */
|
||||
|
||||
EXTERN int fat_mount(struct fat_mountpt_s *fs, boolean writeable);
|
||||
|
@ -510,16 +539,17 @@ EXTERN int fat_checkmount(struct fat_mountpt_s *fs);
|
|||
|
||||
/* low-level hardware access */
|
||||
|
||||
EXTERN int fat_hwread(struct fat_mountpt_s *fs, ubyte *buffer, size_t sector,
|
||||
unsigned int nsectors);
|
||||
EXTERN int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer, size_t sector,
|
||||
unsigned int nsectors);
|
||||
EXTERN int fat_hwread(struct fat_mountpt_s *fs, ubyte *buffer,
|
||||
size_t sector, unsigned int nsectors);
|
||||
EXTERN int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer,
|
||||
size_t sector, unsigned int nsectors);
|
||||
|
||||
/* Cluster access helpers */
|
||||
|
||||
EXTERN ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster );
|
||||
EXTERN ssize_t fat_getcluster(struct fat_mountpt_s *fs, unsigned int clusterno);
|
||||
EXTERN int fat_putcluster(struct fat_mountpt_s *fs, unsigned int clusterno, size_t startsector);
|
||||
EXTERN int fat_putcluster(struct fat_mountpt_s *fs, unsigned int clusterno,
|
||||
size_t startsector);
|
||||
|
||||
/* Help for traverseing directory trees */
|
||||
|
||||
|
@ -531,11 +561,16 @@ EXTERN int fat_finddirentry(struct fat_dirinfo_s *dirinfo, const char *path);
|
|||
EXTERN int fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
|
||||
EXTERN int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
|
||||
|
||||
/* File buffer cache (for partial sector accesses) */
|
||||
/* Mountpoint and fFile buffer cache (for partial sector accesses) */
|
||||
|
||||
EXTERN int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff);
|
||||
EXTERN int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sector);
|
||||
EXTERN int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff);
|
||||
EXTERN int fat_fscacheread(struct fat_mountpt_s *fs, size_t sector);
|
||||
EXTERN int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff);
|
||||
EXTERN int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sector);
|
||||
EXTERN int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff);
|
||||
|
||||
/* FSINFO sector support */
|
||||
|
||||
EXTERN int fat_updatefsinfo(struct fat_mountpt_s *fs);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -128,51 +128,6 @@ static int fat_fscacheflush(struct fat_mountpt_s *fs)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_fscacheread
|
||||
*
|
||||
* Desciption: Read the specified sector into the sector cache, flushing any
|
||||
* existing dirty sectors as necessary.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_fscacheread(struct fat_mountpt_s *fs, size_t sector)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* fs->fs_currentsector holds the current sector that is buffered in
|
||||
* fs->fs_buffer. If the requested sector is the same as this sector, then
|
||||
* we do nothing. Otherwise, we will have to read the new sector.
|
||||
*/
|
||||
|
||||
if (fs->fs_currentsector != sector)
|
||||
{
|
||||
/* We will need to read the new sector. First, flush the cached
|
||||
* sector if it is dirty.
|
||||
*/
|
||||
|
||||
ret = fat_fscacheflush(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then read the specified sector into the cache */
|
||||
|
||||
ret = fat_hwread(fs, fs->fs_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Update the cached sector number */
|
||||
|
||||
fs->fs_currentsector = sector;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_path2dirname
|
||||
*
|
||||
|
@ -726,6 +681,28 @@ void fat_semgive(struct fat_mountpt_s *fs)
|
|||
sem_post(&fs->fs_sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_gettime
|
||||
*
|
||||
* Desciption: Get the time and date suitble for writing into the FAT FS.
|
||||
* TIME in LS 16-bits:
|
||||
* Bits 0:4 = 2 second count (0-29 representing 0-58 seconds)
|
||||
* Bits 5-10 = minutes (0-59)
|
||||
* Bits 11-15 = hours (0-23)
|
||||
* DATE in MS 16-bits
|
||||
* Bits 0:4 = Day of month (0-31)
|
||||
* Bits 5:8 = Month of year (1-12)
|
||||
* Bits 9:15 = Year from 1980 (0-127 representing 1980-2107)
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32 fat_gettime(void)
|
||||
{
|
||||
#warning "Time not implemented"
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_mount
|
||||
*
|
||||
|
@ -1541,6 +1518,51 @@ int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_fscacheread
|
||||
*
|
||||
* Desciption: Read the specified sector into the sector cache, flushing any
|
||||
* existing dirty sectors as necessary.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_fscacheread(struct fat_mountpt_s *fs, size_t sector)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* fs->fs_currentsector holds the current sector that is buffered in
|
||||
* fs->fs_buffer. If the requested sector is the same as this sector, then
|
||||
* we do nothing. Otherwise, we will have to read the new sector.
|
||||
*/
|
||||
|
||||
if (fs->fs_currentsector != sector)
|
||||
{
|
||||
/* We will need to read the new sector. First, flush the cached
|
||||
* sector if it is dirty.
|
||||
*/
|
||||
|
||||
ret = fat_fscacheflush(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then read the specified sector into the cache */
|
||||
|
||||
ret = fat_hwread(fs, fs->fs_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Update the cached sector number */
|
||||
|
||||
fs->fs_currentsector = sector;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_ffcacheflush
|
||||
*
|
||||
|
@ -1649,4 +1671,52 @@ int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_updatefsinfo
|
||||
*
|
||||
* Desciption: Flush evertyhing buffered for the mountpoint and update
|
||||
* the FSINFO sector, if appropriate
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_updatefsinfo(struct fat_mountpt_s *fs)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Flush the fs_buffer if it is dirty */
|
||||
|
||||
ret = fat_fscacheflush(fs);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* The FSINFO sector only has to be update for the case of a FAT32 file
|
||||
* system. Check if the file system type.. If this is a FAT32 file
|
||||
* system then the fs_fsidirty flag will indicate if the FSINFO sector
|
||||
* needs to be re-written.
|
||||
*/
|
||||
|
||||
if (fs->fs_type == FSTYPE_FAT32 && fs->fs_fsidirty)
|
||||
{
|
||||
/* Create an image of the FSINFO sector in the fs_buffer */
|
||||
|
||||
memset(fs->fs_buffer, 0, fs->fs_hwsectorsize);
|
||||
FSI_PUTLEADSIG(fs->fs_buffer, 0x41615252);
|
||||
FSI_PUTSTRUCTSIG(fs->fs_buffer, 0x61417272);
|
||||
FSI_PUTFREECOUNT(fs->fs_buffer, fs->fs_fsifreecount);
|
||||
FSI_PUTNXTFREE(fs->fs_buffer, fs->fs_fsinextfree);
|
||||
FSI_PUTTRAILSIG(fs->fs_buffer, 0xaa550000);
|
||||
|
||||
/* Then flush this to disk */
|
||||
|
||||
fs->fs_currentsector = fs->fs_fsinfo;
|
||||
fs->fs_dirty = TRUE;
|
||||
ret = fat_fscacheflush(fs);
|
||||
|
||||
/* No longer dirty */
|
||||
|
||||
fs->fs_fsidirty = FALSE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FS_FAT */
|
||||
|
|
|
@ -119,7 +119,6 @@ STATUS inode_remove(const char *path)
|
|||
|
||||
/* Find the node to delete */
|
||||
|
||||
inode_semtake();
|
||||
node = inode_search(&name, &left, &parent, NULL);
|
||||
if (node)
|
||||
{
|
||||
|
@ -137,13 +136,11 @@ STATUS inode_remove(const char *path)
|
|||
*/
|
||||
|
||||
node->i_flags |= FSNODEFLAG_DELETED;
|
||||
inode_semgive();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* And delete it now -- recursively to delete all of its children */
|
||||
|
||||
inode_semgive();
|
||||
inode_free(node->i_child);
|
||||
free(node);
|
||||
return OK;
|
||||
|
@ -152,6 +149,5 @@ STATUS inode_remove(const char *path)
|
|||
|
||||
/* The node does not exist or it has references */
|
||||
|
||||
inode_semgive();
|
||||
return ERROR;
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ int read(int fd, void *buf, unsigned int nbytes)
|
|||
{
|
||||
/* Yes, then let it perform the read. NOTE that for the case
|
||||
* of the mountpoint, we depend on the read methods bing
|
||||
* identical in signal and position in the operations vtable.
|
||||
* identical in signature and position in the operations vtable.
|
||||
*/
|
||||
|
||||
ret = (int)inode->u.i_ops->read(this_file, (char*)buf, (size_t)nbytes);
|
||||
|
|
Loading…
Reference in a new issue