Fix FAT seek bug
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@896 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
7f85f96228
commit
d57cb4fc90
|
@ -459,4 +459,6 @@
|
|||
* Fixed several critical bugs with regard to fat reading and writing and FAT12
|
||||
accesses. Basically the FAT FS only worked with my tiny test files and test
|
||||
cases. A lot of stronger FAT tested is needed!!
|
||||
* Fixed another FAT bug in implementation of FAT lseek; this prohibit correct
|
||||
random access to large files.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: September 7, 2008</p>
|
||||
<p>Last Updated: September 8, 2008</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -1117,6 +1117,8 @@ nuttx-0.3.14 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||
* Fixed several critical bugs with regard to fat reading and writing and FAT12
|
||||
accesses. Basically the FAT FS only worked with my tiny test files and test
|
||||
cases. A lot of stronger FAT tested is needed!!
|
||||
* Fixed another FAT bug in implementation of FAT lseek; this prohibit correct
|
||||
random access to large files.
|
||||
|
||||
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statfs.h>
|
||||
|
@ -478,9 +479,11 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
|||
* and the file offset.
|
||||
*/
|
||||
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster)
|
||||
+ (SEC_NSECTORS(fs, filep->f_pos) & CLUS_NDXMASK(fs));
|
||||
fdbg("Start with sector: %d\n", ff->ff_currentsector);
|
||||
ret = fat_currentsector(fs, ff, filep->f_pos);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop until either (1) all data has been transferred, or (2) an
|
||||
|
@ -676,8 +679,11 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
|||
* and the file offset.
|
||||
*/
|
||||
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster)
|
||||
+ (SEC_NSECTORS(fs, filep->f_pos) & CLUS_NDXMASK(fs));
|
||||
ret = fat_currentsector(fs, ff, filep->f_pos);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop until either (1) all data has been transferred, or (2) an
|
||||
|
@ -773,7 +779,9 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
|||
}
|
||||
|
||||
memcpy(&ff->ff_buffer[sectorindex], userbuffer, writesize);
|
||||
ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED);
|
||||
|
||||
ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED);
|
||||
ff->ff_cachesector = ff->ff_currentsector;
|
||||
}
|
||||
|
||||
/* Set up for the next write */
|
||||
|
@ -844,7 +852,6 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
sint32 cluster;
|
||||
ssize_t position;
|
||||
unsigned int clustersize;
|
||||
unsigned int sectoroffset;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
@ -906,6 +913,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
if (position > ff->ff_size && (ff->ff_oflags & O_WROK) == 0)
|
||||
{
|
||||
/* Otherwise, the position is limited to the file size */
|
||||
|
||||
position = ff->ff_size;
|
||||
}
|
||||
|
||||
|
@ -948,7 +956,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
*/
|
||||
|
||||
ff->ff_currentcluster = cluster;
|
||||
if (position <= clustersize)
|
||||
if (position < clustersize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -1015,16 +1023,17 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
|
||||
/* We get here after we have found the sector containing
|
||||
* the requested position.
|
||||
*
|
||||
* Save the new file position
|
||||
*/
|
||||
|
||||
sectoroffset = (position - 1) / fs->fs_hwsectorsize;
|
||||
filep->f_pos += position;
|
||||
|
||||
/* And get the current sector from the cluster and
|
||||
* the sectoroffset into the cluster.
|
||||
/* Then get the current sector from the cluster and the offset
|
||||
* into the cluster from the position
|
||||
*/
|
||||
|
||||
ff->ff_currentsector =
|
||||
fat_cluster2sector(fs, cluster) + sectoroffset;
|
||||
(void)fat_currentsector(fs, ff, filep->f_pos);
|
||||
|
||||
/* Load the sector corresponding to the position */
|
||||
|
||||
|
@ -1037,13 +1046,6 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
}
|
||||
}
|
||||
|
||||
/* Save the number of sectors left in the cluster */
|
||||
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus - sectoroffset;
|
||||
|
||||
/* And save the new file position */
|
||||
|
||||
filep->f_pos += position;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1141,6 +1143,7 @@ static int fat_sync(FAR struct file *filep)
|
|||
}
|
||||
|
||||
/* Check if the has been modified in any way */
|
||||
|
||||
if ((ff->ff_bflags & FFBUFF_MODIFIED) != 0)
|
||||
{
|
||||
/* Flush any unwritten data in the file buffer */
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
#define SEC_NDXMASK(f) ((f)->fs_hwsectorsize - 1)
|
||||
#define SEC_NSECTORS(f,n) ((n) / (f)->fs_hwsectorsize)
|
||||
|
||||
#define CLUS_NDXMASK(f) ((f)->fs_fatsecperclus -1)
|
||||
#define CLUS_NDXMASK(f) ((f)->fs_fatsecperclus - 1)
|
||||
|
||||
/****************************************************************************
|
||||
* File system types */
|
||||
|
@ -615,8 +615,9 @@ EXTERN int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s
|
|||
|
||||
/* FSINFO sector support */
|
||||
|
||||
EXTERN int fat_updatefsinfo(struct fat_mountpt_s *fs);
|
||||
EXTERN int fat_nfreeclusters(struct fat_mountpt_s *fs, size_t *pfreeclusters);
|
||||
EXTERN int fat_updatefsinfo(struct fat_mountpt_s *fs);
|
||||
EXTERN int fat_nfreeclusters(struct fat_mountpt_s *fs, size_t *pfreeclusters);
|
||||
EXTERN int fat_currentsector(struct fat_mountpt_s *fs, struct fat_file_s *ff, off_t position);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -2303,7 +2304,8 @@ int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff)
|
|||
|
||||
/* Then discard the current cache contents */
|
||||
|
||||
ff->ff_bflags &= ~FFBUFF_VALID;
|
||||
ff->ff_bflags &= ~FFBUFF_VALID;
|
||||
ff->ff_cachesector = 0;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
@ -2461,3 +2463,47 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, size_t *pfreeclusters)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_nfreeclusters
|
||||
*
|
||||
* Desciption:
|
||||
* Given the file position, set the correct current sector to access.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_currentsector(struct fat_mountpt_s *fs, struct fat_file_s *ff,
|
||||
off_t position)
|
||||
{
|
||||
int sectoroffset;
|
||||
|
||||
if (position <= ff->ff_size )
|
||||
{
|
||||
/* sectoroffset is the sector number offset into the current cluster */
|
||||
|
||||
sectoroffset = SEC_NSECTORS(fs, position) & CLUS_NDXMASK(fs);
|
||||
|
||||
/* The current cluster is the the first sector of the cluster plus
|
||||
* the sector offset
|
||||
*/
|
||||
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster)
|
||||
+ sectoroffset;
|
||||
|
||||
/* The remainder is the number of sectors left in the cluster to be
|
||||
* read/written
|
||||
*/
|
||||
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus - sectoroffset;
|
||||
|
||||
fvdbg("position=%d currentsector=%d sectorsincluster=%d\n",
|
||||
position, ff->ff_currentsector, ff->ff_sectorsincluster);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* The position does not lie within the file */
|
||||
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue