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:
patacongo 2008-09-08 17:04:14 +00:00
parent 7f85f96228
commit d57cb4fc90
5 changed files with 79 additions and 25 deletions

View File

@ -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.

View File

@ -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 &lt;spudmonkey@racsa.co.cr&gt;
* 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 &lt;spudmonkey@racsa.co.cr&gt;

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}