FAT read logic integrated
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@237 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
3431a8a20c
commit
e3615933cc
|
@ -254,6 +254,15 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
|
|||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Create a file buffer to support partial sector accesses */
|
||||
|
||||
ff->ff_buffer = (ubyte*)malloc(fs->fs_hwsectorsize);
|
||||
if (!ff->ff_buffer)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_struct;
|
||||
}
|
||||
|
||||
/* Initialize the file private data (only need to initialize non-zero elements) */
|
||||
|
||||
ff->ff_open = TRUE;
|
||||
|
@ -262,7 +271,7 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
|
|||
|
||||
/* Save information that can be used later to recover the directory entry */
|
||||
|
||||
ff->ff_dirsector = fs->fs_sector;
|
||||
ff->ff_dirsector = fs->fs_currentsector;
|
||||
ff->ff_dirindex = dirinfo.fd_index;
|
||||
|
||||
/* File cluster/size info */
|
||||
|
@ -279,7 +288,6 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
|
|||
{
|
||||
ff->ff_position = ff->ff_size;
|
||||
}
|
||||
return OK;
|
||||
|
||||
/* Attach the private date to the struct file instance */
|
||||
|
||||
|
@ -297,7 +305,12 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
|
|||
fat_semgive(fs);
|
||||
return OK;
|
||||
|
||||
/* Error exits */
|
||||
/* Error exits -- goto's are nasty things, but they sure can make error
|
||||
* handling a lot simpler.
|
||||
*/
|
||||
|
||||
errout_with_struct:
|
||||
free(ff);
|
||||
|
||||
errout_with_semaphore:
|
||||
fat_semgive(fs);
|
||||
|
@ -342,6 +355,13 @@ static ssize_t fat_read(FAR struct file *filp, char *buffer, size_t buflen)
|
|||
struct inode *inode;
|
||||
struct fat_mountpt_s *fs;
|
||||
struct fat_file_s *ff;
|
||||
unsigned int cluster;
|
||||
unsigned int bytesread;
|
||||
unsigned int readsize;
|
||||
unsigned int nsectors;
|
||||
size_t readsector;
|
||||
size_t bytesleft;
|
||||
char *userbuffer = buffer;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
@ -358,12 +378,174 @@ static ssize_t fat_read(FAR struct file *filp, char *buffer, size_t buflen)
|
|||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
fat_semtake(fs);
|
||||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
return -ENOSYS;
|
||||
|
||||
/* Check if the file was opened with read access */
|
||||
|
||||
if ((ff->ff_oflags & O_RDOK) == 0)
|
||||
{
|
||||
ret= -EACCES;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Get the number of bytes left in the file */
|
||||
|
||||
bytesleft = ff->ff_size - ff->ff_position;
|
||||
|
||||
/* Truncate read count so that it does not exceed the number
|
||||
* of bytes left in the file.
|
||||
*/
|
||||
|
||||
if (buflen > bytesleft)
|
||||
{
|
||||
buflen = bytesleft;
|
||||
}
|
||||
|
||||
/* Loop until either (1) all data has been transferred, or (2) an
|
||||
* error occurs.
|
||||
*/
|
||||
|
||||
readsize = 0;
|
||||
while (buflen > 0)
|
||||
{
|
||||
/* Get offset into the sector where we begin the read */
|
||||
|
||||
int sectorindex = ff->ff_position & SEC_NDXMASK(fs);
|
||||
|
||||
/* Check if the current read stream happens to lie on a
|
||||
* sector boundary.
|
||||
*/
|
||||
|
||||
if (sectorindex == 0)
|
||||
{
|
||||
/* Try to read another contiguous sector from the cluster */
|
||||
|
||||
ff->ff_sectorsincluster--;
|
||||
|
||||
/* Are there unread sectors remaining in the cluster? */
|
||||
|
||||
if (ff->ff_sectorsincluster > 0)
|
||||
{
|
||||
/* Yes.. There are more sectors in this cluster to be read
|
||||
* just increment the current sector number and read.
|
||||
*/
|
||||
|
||||
readsector = ff->ff_currentsector + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. Handle a special case of the first sector */
|
||||
|
||||
if (ff->ff_position == 0)
|
||||
{
|
||||
cluster = ff->ff_startcluster;
|
||||
}
|
||||
|
||||
/* But in the general case, we have to find the next cluster
|
||||
* in the FAT.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
cluster = fat_getcluster(fs, ff->ff_currentcluster);
|
||||
}
|
||||
|
||||
/* Verify the cluster number */
|
||||
|
||||
if (cluster < 2 || cluster >= fs->fs_nclusters)
|
||||
{
|
||||
ret = -EINVAL; /* Not the right error */
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Setup to read the first sector from the new cluster */
|
||||
|
||||
ff->ff_currentcluster = cluster;
|
||||
readsector = fat_cluster2sector(fs, cluster);
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
}
|
||||
|
||||
/* Check if the user has provided a buffer large enough to
|
||||
* hold one or more complete sectors.
|
||||
*/
|
||||
|
||||
nsectors = buflen / fs->fs_hwsectorsize;
|
||||
if (nsectors > 0)
|
||||
{
|
||||
/* Read maximum contiguous sectors directly without using
|
||||
* our tiny read buffer.
|
||||
*
|
||||
* Limit the number of sectors that we read on this time
|
||||
* through the loop to the remaining contiguous sectors
|
||||
* in this cluster
|
||||
*/
|
||||
|
||||
if (nsectors > ff->ff_sectorsincluster)
|
||||
{
|
||||
nsectors = ff->ff_sectorsincluster;
|
||||
}
|
||||
|
||||
/* We are not sure of the state of the file buffer so
|
||||
* the safest thing to do is just invalidate it
|
||||
*/
|
||||
|
||||
(void)fat_ffcacheinvalidate(fs, ff);
|
||||
|
||||
/* Read all of the sectors directory into user memory */
|
||||
|
||||
ret = fat_hwread(fs, userbuffer, readsector, nsectors);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
ff->ff_sectorsincluster -= nsectors - 1;
|
||||
bytesread = nsectors * fs->fs_hwsectorsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are reading a partial sector. First, read the whole sector
|
||||
* into the file data buffer. This is a caching buffer so if
|
||||
* it is already there then all is well.
|
||||
*/
|
||||
|
||||
ret = fat_ffcacheread(fs, ff, readsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Copy the partial sector into the user buffer */
|
||||
|
||||
bytesread = fs->fs_hwsectorsize - sectorindex;
|
||||
if (bytesread > buflen)
|
||||
{
|
||||
bytesread = buflen;
|
||||
}
|
||||
|
||||
memcpy(userbuffer, &ff->ff_buffer[sectorindex], bytesread);
|
||||
}
|
||||
|
||||
/* Set up for the next sector read */
|
||||
|
||||
userbuffer += bytesread;
|
||||
ff->ff_position += bytesread;
|
||||
readsize += bytesread;
|
||||
buflen -= bytesread;
|
||||
}
|
||||
}
|
||||
|
||||
fat_semgive(fs);
|
||||
return readsize;
|
||||
|
||||
errout_with_semaphore:
|
||||
fat_semgive(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -392,6 +574,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer,
|
|||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
fat_semtake(fs);
|
||||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
|
@ -425,6 +608,7 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence)
|
|||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
fat_semtake(fs);
|
||||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
|
@ -458,6 +642,7 @@ static int fat_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
|
|||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
fat_semtake(fs);
|
||||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
|
@ -485,7 +670,21 @@ static int fat_bind(FAR struct inode *blkdriver, const void *data,
|
|||
struct fat_mountpt_s *fs;
|
||||
int ret;
|
||||
|
||||
/* Open the block driver */
|
||||
|
||||
if (!blkdriver || !blkdriver->u.i_bops)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ( blkdriver->u.i_bops->open &&
|
||||
blkdriver->u.i_bops->open(blkdriver) != OK)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Create an instance of the mountpt state structure */
|
||||
|
||||
fs = (struct fat_mountpt_s *)zalloc(sizeof(struct fat_mountpt_s));
|
||||
if ( !fs )
|
||||
{
|
||||
|
|
|
@ -146,12 +146,6 @@
|
|||
#define FATATTR_LONGNAME \
|
||||
(FATATTR_READONLY|FATATTR_HIDDEN|FATATTR_SYSTEM|FATATTR_VOLUMEID)
|
||||
|
||||
/* File system types */
|
||||
|
||||
#define FSTYPE_FAT12 0
|
||||
#define FSTYPE_FAT16 1
|
||||
#define FSTYPE_FAT32 2
|
||||
|
||||
/* Directory indexing helper. Each directory entry is 32-bytes in length.
|
||||
* The number of directory entries in a sector then varies with the size
|
||||
* of the sector supported in hardware.
|
||||
|
@ -164,6 +158,19 @@
|
|||
#define SEC_NDXMASK(f) ((f)->fs_hwsectorsize - 1)
|
||||
#define SEC_NSECTORS(f,n) ((n) / (f)->fs_hwsectorsize)
|
||||
|
||||
/****************************************************************************
|
||||
* File system types */
|
||||
|
||||
#define FSTYPE_FAT12 0
|
||||
#define FSTYPE_FAT16 1
|
||||
#define FSTYPE_FAT32 2
|
||||
|
||||
/* File buffer flags */
|
||||
|
||||
#define FFBUFF_VALID 1
|
||||
#define FFBUFF_DIRTY 2
|
||||
#define FFBUFF_MODIFIED 4
|
||||
|
||||
/****************************************************************************
|
||||
* These offset describe the FSINFO sector
|
||||
*/
|
||||
|
@ -413,7 +420,7 @@ struct fat_mountpt_s
|
|||
size_t fs_rootbase; /* MBR: Cluster no. of 1st cluster of root dir */
|
||||
size_t fs_database; /* Logical block of start data sectors */
|
||||
size_t fs_fsinfo; /* MBR: Sector number of FSINFO sector */
|
||||
size_t fs_sector; /* The sector number buffered in fs_buffer */
|
||||
size_t fs_currentsector; /* The sector number buffered in fs_buffer */
|
||||
uint32 fs_nclusters; /* Maximum number of data clusters */
|
||||
uint32 fs_fatsize; /* MBR: Count of sectors occupied by one fat */
|
||||
uint32 fs_fattotsec; /* MBR: Total count of sectors on the volume */
|
||||
|
@ -439,13 +446,17 @@ 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_oflags; /* Flags provided when file was opened */
|
||||
ubyte ff_sectorsincluster; /* Sectors remaining in cluster */
|
||||
uint16 ff_dirindex; /* Index into ff_dirsector to directory entry */
|
||||
uint32 ff_currentcluster; /* Current cluster being accessed */
|
||||
size_t ff_dirsector; /* Sector containing the directory entry */
|
||||
size_t ff_position; /* File position for read/write/seek in bytes */
|
||||
size_t ff_size; /* Size of the file in bytes */
|
||||
size_t ff_startcluster; /* Start cluster of file on media */
|
||||
size_t ff_currentsector; /* Current sector in the file buffer */
|
||||
ubyte *ff_buffer; /* File buffer (for partial sector accesses) */
|
||||
};
|
||||
|
||||
/* This structure is used internally for describing directory entries */
|
||||
|
@ -480,19 +491,52 @@ extern "C" {
|
|||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Utitilies to handle unaligned or byte swapped accesses */
|
||||
|
||||
EXTERN uint16 fat_getuint16(ubyte *ptr);
|
||||
EXTERN uint32 fat_getuint32(ubyte *ptr);
|
||||
EXTERN void fat_putuint16(ubyte *ptr, uint16 value16);
|
||||
EXTERN void fat_putuint32(ubyte *ptr, uint32 value32);
|
||||
|
||||
/* Manage the per-mount semaphore that protects access to shared resources */
|
||||
|
||||
EXTERN void fat_semtake(struct fat_mountpt_s *fs);
|
||||
EXTERN void fat_semgive(struct fat_mountpt_s *fs);
|
||||
|
||||
/* Handle hardware interactions for mounting */
|
||||
|
||||
EXTERN int fat_mount(struct fat_mountpt_s *fs, boolean writeable);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Help for traverseing directory trees */
|
||||
|
||||
EXTERN int fat_nextdirentry(struct fat_dirinfo_s *dirinfo);
|
||||
EXTERN int fat_finddirentry(struct fat_dirinfo_s *dirinfo, const char *path);
|
||||
|
||||
/* File creation helpers */
|
||||
|
||||
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) */
|
||||
|
||||
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);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -79,88 +79,25 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_hwread
|
||||
*
|
||||
* Desciption: Read the specified sector into the sector buffer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_hwread(struct fat_mountpt_s *fs, ubyte *buffer,
|
||||
size_t sector, unsigned int nsectors)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
if (fs && fs->fs_blkdriver )
|
||||
{
|
||||
struct inode *inode = fs->fs_blkdriver;
|
||||
if (inode && inode->u.i_bops && inode->u.i_bops->read)
|
||||
{
|
||||
ssize_t nSectorsRead = inode->u.i_bops->read(inode, buffer,
|
||||
sector, nsectors);
|
||||
if (nSectorsRead == nsectors)
|
||||
{
|
||||
ret = OK;
|
||||
}
|
||||
else if (nSectorsRead < 0)
|
||||
{
|
||||
ret = nSectorsRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_hwwrite
|
||||
*
|
||||
* Desciption: Write the sector buffer to the specified sector
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer,
|
||||
size_t sector, unsigned int nsectors)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
if (fs && fs->fs_blkdriver )
|
||||
{
|
||||
struct inode *inode = fs->fs_blkdriver;
|
||||
if (inode && inode->u.i_bops && inode->u.i_bops->write)
|
||||
{
|
||||
ssize_t nSectorsWritten =
|
||||
inode->u.i_bops->write(inode, buffer, sector, nsectors);
|
||||
|
||||
if (nSectorsWritten == nsectors)
|
||||
{
|
||||
ret = OK;
|
||||
}
|
||||
else if (nSectorsWritten < 0)
|
||||
{
|
||||
ret = nSectorsWritten;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_cacheflush
|
||||
* Name: fat_fscacheflush
|
||||
*
|
||||
* Desciption: Flush any dirty sectors as necessary
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_cacheflush(struct fat_mountpt_s *fs)
|
||||
static int fat_fscacheflush(struct fat_mountpt_s *fs)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check if the fs_buffer is dirty. In this case, we will write back the
|
||||
* contents of fs_buffer.
|
||||
* contents of fs_buffer.
|
||||
*/
|
||||
|
||||
if (fs->fs_dirty)
|
||||
{
|
||||
/* Write the dirty sector */
|
||||
|
||||
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_sector, 1);
|
||||
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
|
@ -168,15 +105,15 @@ static int fat_cacheflush(struct fat_mountpt_s *fs)
|
|||
|
||||
/* Does the sector lie in the FAT region? */
|
||||
|
||||
if (fs->fs_sector < fs->fs_fatbase + fs->fs_fatsize)
|
||||
if (fs->fs_currentsector < fs->fs_fatbase + fs->fs_fatsize)
|
||||
{
|
||||
/* Yes, then make the change in the FAT copy as well */
|
||||
int i;
|
||||
|
||||
for (i = fs->fs_fatnumfats; i >= 2; i--)
|
||||
{
|
||||
fs->fs_sector += fs->fs_fatsize;
|
||||
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_sector, 1);
|
||||
fs->fs_currentsector += fs->fs_fatsize;
|
||||
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
|
@ -192,29 +129,29 @@ static int fat_cacheflush(struct fat_mountpt_s *fs)
|
|||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_cacheread
|
||||
* Name: fat_fscacheread
|
||||
*
|
||||
* Desciption: Read the specified sector into the sector cache, flushing any
|
||||
* existing dirty sectors as necessary.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_cacheread(struct fat_mountpt_s *fs, uint32 sector)
|
||||
static int fat_fscacheread(struct fat_mountpt_s *fs, size_t sector)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* fs->sector 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.
|
||||
/* 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_sector != 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_cacheflush(fs);
|
||||
ret = fat_fscacheflush(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
|
@ -230,287 +167,12 @@ static int fat_cacheread(struct fat_mountpt_s *fs, uint32 sector)
|
|||
|
||||
/* Update the cached sector number */
|
||||
|
||||
fs->fs_sector = sector;
|
||||
fs->fs_currentsector = sector;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_clustger2sector
|
||||
*
|
||||
* Desciption: Convert a cluster number to a start sector number
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster )
|
||||
{
|
||||
cluster -= 2;
|
||||
if (cluster >= fs->fs_nclusters - 2)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
return cluster * fs->fs_fatsecperclus + fs->fs_database;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_getcluster
|
||||
*
|
||||
* Desciption: Get the cluster start sector into the FAT
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t fat_getcluster(struct fat_mountpt_s *fs, unsigned int clusterno)
|
||||
{
|
||||
/* Verify that the cluster number is within range */
|
||||
|
||||
if (clusterno >= 2 && clusterno < fs->fs_nclusters)
|
||||
{
|
||||
/* Okay.. Read the next cluster from the FAT. The way we will do
|
||||
* this depends on the type of FAT filesystm we are dealing with.
|
||||
*/
|
||||
|
||||
switch (fs->fs_type)
|
||||
{
|
||||
case FSTYPE_FAT12 :
|
||||
{
|
||||
size_t fatsector;
|
||||
unsigned int fatoffset;
|
||||
unsigned int startsector;
|
||||
unsigned int fatindex;
|
||||
|
||||
/* FAT12 is more complex because it has 12-bits (1.5 bytes)
|
||||
* per FAT entry. Get the offset to the first byte:
|
||||
*/
|
||||
|
||||
fatoffset = (clusterno * 3) / 2;
|
||||
fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
|
||||
/* Read the sector at this offset */
|
||||
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the first, LS byte of the cluster from the FAT */
|
||||
|
||||
fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
startsector = fs->fs_buffer[fatindex];
|
||||
|
||||
/* With FAT12, the second byte of the cluster number may lie in
|
||||
* a different sector than the first byte.
|
||||
*/
|
||||
|
||||
fatindex++;
|
||||
if (fatindex >= fs->fs_hwsectorsize)
|
||||
{
|
||||
fatsector++;
|
||||
fatindex = 0;
|
||||
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the second, MS byte of the cluster for 16-bits. The
|
||||
* does not depend on the endian-ness of the target, but only
|
||||
* on the fact that the byte stream is little-endian.
|
||||
*/
|
||||
|
||||
startsector |= (unsigned int)fs->fs_buffer[fatindex] << 8;
|
||||
|
||||
/* Now, pick out the correct 12 bit cluster start sector value */
|
||||
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
/* Odd.. take the MS 12-bits */
|
||||
startsector >>= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Even.. take the LS 12-bits */
|
||||
startsector &= 0x0fff;
|
||||
}
|
||||
return startsector;
|
||||
}
|
||||
|
||||
case FSTYPE_FAT16 :
|
||||
{
|
||||
unsigned int fatoffset = 2 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
return FAT_GETFAT16(fs->fs_buffer, fatindex);
|
||||
}
|
||||
|
||||
case FSTYPE_FAT32 :
|
||||
{
|
||||
unsigned int fatoffset = 4 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
return FAT_GETFAT16(fs->fs_buffer, fatindex) & 0x0fffffff;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* There is no cluster information, or an error occured */
|
||||
return (ssize_t)ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_putcluster
|
||||
*
|
||||
* Desciption: Write a new cluster start sector into the FAT
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_putcluster(struct fat_mountpt_s *fs, unsigned int clusterno, size_t startsector)
|
||||
{
|
||||
/* Verify that the cluster number is within range. Zero erases the cluster. */
|
||||
|
||||
if (clusterno == 0 || (clusterno >= 2 && clusterno < fs->fs_nclusters))
|
||||
{
|
||||
/* Okay.. Write the next cluster into the FAT. The way we will do
|
||||
* this depends on the type of FAT filesystm we are dealing with.
|
||||
*/
|
||||
|
||||
switch (fs->fs_type)
|
||||
{
|
||||
case FSTYPE_FAT12 :
|
||||
{
|
||||
size_t fatsector;
|
||||
unsigned int fatoffset;
|
||||
unsigned int fatindex;
|
||||
ubyte value;
|
||||
|
||||
/* FAT12 is more complex because it has 12-bits (1.5 bytes)
|
||||
* per FAT entry. Get the offset to the first byte:
|
||||
*/
|
||||
|
||||
fatoffset = (clusterno * 3) / 2;
|
||||
fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
|
||||
/* Make sure that the sector at this offset is in the cache */
|
||||
|
||||
if (fat_cacheread(fs, fatsector)< 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Output the LS byte first handling the 12-bit alignment within
|
||||
* the 16-bits
|
||||
*/
|
||||
|
||||
fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
value = (fs->fs_buffer[fatindex] & 0x0f) | startsector << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (ubyte)startsector;
|
||||
}
|
||||
fs->fs_buffer[fatindex] = value;
|
||||
|
||||
/* With FAT12, the second byte of the cluster number may lie in
|
||||
* a different sector than the first byte.
|
||||
*/
|
||||
|
||||
fatindex++;
|
||||
if (fatindex >= fs->fs_hwsectorsize)
|
||||
{
|
||||
/* Read the next sector */
|
||||
|
||||
fatsector++;
|
||||
fatindex = 0;
|
||||
|
||||
/* Set the dirty flag to make sure the sector that we
|
||||
* just modified is written out.
|
||||
*/
|
||||
|
||||
fs->fs_dirty = TRUE;
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the MS byte first handling the 12-bit alignment within
|
||||
* the 16-bits
|
||||
*/
|
||||
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
value = (ubyte)(startsector >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (fs->fs_buffer[fatindex] & 0xf0) | (startsector & 0x0f);
|
||||
}
|
||||
fs->fs_buffer[fatindex] = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSTYPE_FAT16 :
|
||||
{
|
||||
unsigned int fatoffset = 2 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
FAT_PUTFAT16(fs->fs_buffer, fatindex, startsector & 0xffff);
|
||||
}
|
||||
break;
|
||||
|
||||
case FSTYPE_FAT32 :
|
||||
{
|
||||
unsigned int fatoffset = 4 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_cacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
FAT_PUTFAT32(fs->fs_buffer, fatindex, startsector & 0x0fffffff);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Mark the modified sector as "dirty" and return success */
|
||||
|
||||
fs->fs_dirty = 1;
|
||||
return OK;
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_path2dirname
|
||||
*
|
||||
|
@ -1265,6 +927,345 @@ int fat_checkmount(struct fat_mountpt_s *fs)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_hwread
|
||||
*
|
||||
* Desciption: Read the specified sector into the sector buffer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_hwread(struct fat_mountpt_s *fs, ubyte *buffer, size_t sector,
|
||||
unsigned int nsectors)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
if (fs && fs->fs_blkdriver )
|
||||
{
|
||||
struct inode *inode = fs->fs_blkdriver;
|
||||
if (inode && inode->u.i_bops && inode->u.i_bops->read)
|
||||
{
|
||||
ssize_t nSectorsRead = inode->u.i_bops->read(inode, buffer,
|
||||
sector, nsectors);
|
||||
if (nSectorsRead == nsectors)
|
||||
{
|
||||
ret = OK;
|
||||
}
|
||||
else if (nSectorsRead < 0)
|
||||
{
|
||||
ret = nSectorsRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_hwwrite
|
||||
*
|
||||
* Desciption: Write the sector buffer to the specified sector
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer, size_t sector,
|
||||
unsigned int nsectors)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
if (fs && fs->fs_blkdriver )
|
||||
{
|
||||
struct inode *inode = fs->fs_blkdriver;
|
||||
if (inode && inode->u.i_bops && inode->u.i_bops->write)
|
||||
{
|
||||
ssize_t nSectorsWritten =
|
||||
inode->u.i_bops->write(inode, buffer, sector, nsectors);
|
||||
|
||||
if (nSectorsWritten == nsectors)
|
||||
{
|
||||
ret = OK;
|
||||
}
|
||||
else if (nSectorsWritten < 0)
|
||||
{
|
||||
ret = nSectorsWritten;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_cluster2sector
|
||||
*
|
||||
* Desciption: Convert a cluster number to a start sector number
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster )
|
||||
{
|
||||
cluster -= 2;
|
||||
if (cluster >= fs->fs_nclusters - 2)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
return cluster * fs->fs_fatsecperclus + fs->fs_database;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_getcluster
|
||||
*
|
||||
* Desciption: Get the cluster start sector into the FAT
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t fat_getcluster(struct fat_mountpt_s *fs, unsigned int clusterno)
|
||||
{
|
||||
/* Verify that the cluster number is within range */
|
||||
|
||||
if (clusterno >= 2 && clusterno < fs->fs_nclusters)
|
||||
{
|
||||
/* Okay.. Read the next cluster from the FAT. The way we will do
|
||||
* this depends on the type of FAT filesystm we are dealing with.
|
||||
*/
|
||||
|
||||
switch (fs->fs_type)
|
||||
{
|
||||
case FSTYPE_FAT12 :
|
||||
{
|
||||
size_t fatsector;
|
||||
unsigned int fatoffset;
|
||||
unsigned int startsector;
|
||||
unsigned int fatindex;
|
||||
|
||||
/* FAT12 is more complex because it has 12-bits (1.5 bytes)
|
||||
* per FAT entry. Get the offset to the first byte:
|
||||
*/
|
||||
|
||||
fatoffset = (clusterno * 3) / 2;
|
||||
fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
|
||||
/* Read the sector at this offset */
|
||||
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the first, LS byte of the cluster from the FAT */
|
||||
|
||||
fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
startsector = fs->fs_buffer[fatindex];
|
||||
|
||||
/* With FAT12, the second byte of the cluster number may lie in
|
||||
* a different sector than the first byte.
|
||||
*/
|
||||
|
||||
fatindex++;
|
||||
if (fatindex >= fs->fs_hwsectorsize)
|
||||
{
|
||||
fatsector++;
|
||||
fatindex = 0;
|
||||
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the second, MS byte of the cluster for 16-bits. The
|
||||
* does not depend on the endian-ness of the target, but only
|
||||
* on the fact that the byte stream is little-endian.
|
||||
*/
|
||||
|
||||
startsector |= (unsigned int)fs->fs_buffer[fatindex] << 8;
|
||||
|
||||
/* Now, pick out the correct 12 bit cluster start sector value */
|
||||
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
/* Odd.. take the MS 12-bits */
|
||||
startsector >>= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Even.. take the LS 12-bits */
|
||||
startsector &= 0x0fff;
|
||||
}
|
||||
return startsector;
|
||||
}
|
||||
|
||||
case FSTYPE_FAT16 :
|
||||
{
|
||||
unsigned int fatoffset = 2 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
return FAT_GETFAT16(fs->fs_buffer, fatindex);
|
||||
}
|
||||
|
||||
case FSTYPE_FAT32 :
|
||||
{
|
||||
unsigned int fatoffset = 4 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
return FAT_GETFAT16(fs->fs_buffer, fatindex) & 0x0fffffff;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* There is no cluster information, or an error occured */
|
||||
return (ssize_t)ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_putcluster
|
||||
*
|
||||
* Desciption: Write a new cluster start sector into the FAT
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_putcluster(struct fat_mountpt_s *fs, unsigned int clusterno, size_t startsector)
|
||||
{
|
||||
/* Verify that the cluster number is within range. Zero erases the cluster. */
|
||||
|
||||
if (clusterno == 0 || (clusterno >= 2 && clusterno < fs->fs_nclusters))
|
||||
{
|
||||
/* Okay.. Write the next cluster into the FAT. The way we will do
|
||||
* this depends on the type of FAT filesystm we are dealing with.
|
||||
*/
|
||||
|
||||
switch (fs->fs_type)
|
||||
{
|
||||
case FSTYPE_FAT12 :
|
||||
{
|
||||
size_t fatsector;
|
||||
unsigned int fatoffset;
|
||||
unsigned int fatindex;
|
||||
ubyte value;
|
||||
|
||||
/* FAT12 is more complex because it has 12-bits (1.5 bytes)
|
||||
* per FAT entry. Get the offset to the first byte:
|
||||
*/
|
||||
|
||||
fatoffset = (clusterno * 3) / 2;
|
||||
fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
|
||||
/* Make sure that the sector at this offset is in the cache */
|
||||
|
||||
if (fat_fscacheread(fs, fatsector)< 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Output the LS byte first handling the 12-bit alignment within
|
||||
* the 16-bits
|
||||
*/
|
||||
|
||||
fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
value = (fs->fs_buffer[fatindex] & 0x0f) | startsector << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (ubyte)startsector;
|
||||
}
|
||||
fs->fs_buffer[fatindex] = value;
|
||||
|
||||
/* With FAT12, the second byte of the cluster number may lie in
|
||||
* a different sector than the first byte.
|
||||
*/
|
||||
|
||||
fatindex++;
|
||||
if (fatindex >= fs->fs_hwsectorsize)
|
||||
{
|
||||
/* Read the next sector */
|
||||
|
||||
fatsector++;
|
||||
fatindex = 0;
|
||||
|
||||
/* Set the dirty flag to make sure the sector that we
|
||||
* just modified is written out.
|
||||
*/
|
||||
|
||||
fs->fs_dirty = TRUE;
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the MS byte first handling the 12-bit alignment within
|
||||
* the 16-bits
|
||||
*/
|
||||
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
value = (ubyte)(startsector >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (fs->fs_buffer[fatindex] & 0xf0) | (startsector & 0x0f);
|
||||
}
|
||||
fs->fs_buffer[fatindex] = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSTYPE_FAT16 :
|
||||
{
|
||||
unsigned int fatoffset = 2 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
FAT_PUTFAT16(fs->fs_buffer, fatindex, startsector & 0xffff);
|
||||
}
|
||||
break;
|
||||
|
||||
case FSTYPE_FAT32 :
|
||||
{
|
||||
unsigned int fatoffset = 4 * clusterno;
|
||||
size_t fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);
|
||||
unsigned int fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
FAT_PUTFAT32(fs->fs_buffer, fatindex, startsector & 0x0fffffff);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Mark the modified sector as "dirty" and return success */
|
||||
|
||||
fs->fs_dirty = 1;
|
||||
return OK;
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_nextdirentry
|
||||
*
|
||||
|
@ -1439,7 +1440,7 @@ int fat_finddirentry(struct fat_dirinfo_s *dirinfo, const char *path)
|
|||
{
|
||||
/* Read the next sector into memory */
|
||||
|
||||
ret = fat_cacheread(fs, dirinfo->fd_currsector);
|
||||
ret = fat_fscacheread(fs, dirinfo->fd_currsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
|
@ -1540,4 +1541,112 @@ int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_ffcacheflush
|
||||
*
|
||||
* Desciption: Flush any dirty sectors as necessary
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check if the ff_buffer is dirty. In this case, we will write back the
|
||||
* contents of ff_buffer.
|
||||
*/
|
||||
|
||||
if (ff->ff_bflags && (FFBUFF_DIRTY|FFBUFF_VALID) == (FFBUFF_DIRTY|FFBUFF_VALID))
|
||||
{
|
||||
/* Write the dirty sector */
|
||||
|
||||
ret = fat_hwwrite(fs, ff->ff_buffer, ff->ff_currentsector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* No longer dirty */
|
||||
|
||||
ff->ff_bflags &= ~FFBUFF_DIRTY;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_ffcacheread
|
||||
*
|
||||
* Desciption: Read the specified sector into the sector cache, flushing any
|
||||
* existing dirty sectors as necessary.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sector)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ff->ff_currentsector holds the current sector that is buffered in
|
||||
* ff->ff_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 (ff->ff_currentsector != sector || (ff->ff_bflags & FFBUFF_VALID) == 0)
|
||||
{
|
||||
/* We will need to read the new sector. First, flush the cached
|
||||
* sector if it is dirty.
|
||||
*/
|
||||
|
||||
ret = fat_ffcacheflush(fs, ff);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then read the specified sector into the cache */
|
||||
|
||||
ret = fat_hwread(fs, ff->ff_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Update the cached sector number */
|
||||
|
||||
ff->ff_currentsector = sector;
|
||||
ff->ff_bflags |= FFBUFF_VALID;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_ffcacheread
|
||||
*
|
||||
* Desciption: Invalidate the current file buffer contents
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Is there anything valid in the buffer now? */
|
||||
|
||||
if ((ff->ff_bflags & FFBUFF_VALID) != 0)
|
||||
{
|
||||
/* We will invalidate the buffered sector */
|
||||
|
||||
ret = fat_ffcacheflush(fs, ff);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then discard the current cache contents */
|
||||
|
||||
ff->ff_bflags &= ~FFBUFF_VALID;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FS_FAT */
|
||||
|
|
Loading…
Reference in New Issue