From 76159a251b1b514e1d296223616ef2cb891c632f Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 8 Sep 2008 17:04:14 +0000 Subject: Fix FAT seek bug git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@896 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/fs/fat/fs_fat32.c | 43 +++++++++++++++++++++------------------- nuttx/fs/fat/fs_fat32.h | 7 ++++--- nuttx/fs/fat/fs_fat32util.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 24 deletions(-) (limited to 'nuttx/fs') diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c index 47290642d..97ec1fd49 100644 --- a/nuttx/fs/fat/fs_fat32.c +++ b/nuttx/fs/fat/fs_fat32.c @@ -44,6 +44,7 @@ ****************************************************************************/ #include + #include #include #include @@ -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 */ diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h index 576e7ea84..55d6fbbb4 100644 --- a/nuttx/fs/fat/fs_fat32.h +++ b/nuttx/fs/fat/fs_fat32.h @@ -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) diff --git a/nuttx/fs/fat/fs_fat32util.c b/nuttx/fs/fat/fs_fat32util.c index c6680b6f0..f38cc3741 100644 --- a/nuttx/fs/fat/fs_fat32util.c +++ b/nuttx/fs/fat/fs_fat32util.c @@ -44,6 +44,7 @@ ****************************************************************************/ #include + #include #include #include @@ -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; +} + + -- cgit v1.2.3