summaryrefslogtreecommitdiff
path: root/nuttx/fs
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-08 17:04:14 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-08 17:04:14 +0000
commit76159a251b1b514e1d296223616ef2cb891c632f (patch)
tree563fb1802003f60f1c83a3a52f5f6cacade2364a /nuttx/fs
parent6dc0251ef29e9eac634fb7638d53174ad07f6946 (diff)
downloadpx4-nuttx-76159a251b1b514e1d296223616ef2cb891c632f.tar.gz
px4-nuttx-76159a251b1b514e1d296223616ef2cb891c632f.tar.bz2
px4-nuttx-76159a251b1b514e1d296223616ef2cb891c632f.zip
Fix FAT seek bug
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@896 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs')
-rw-r--r--nuttx/fs/fat/fs_fat32.c43
-rw-r--r--nuttx/fs/fat/fs_fat32.h7
-rw-r--r--nuttx/fs/fat/fs_fat32util.c48
3 files changed, 74 insertions, 24 deletions
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 <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 */
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 <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;
+}
+
+