summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2014-03-04 08:34:11 +1100
committerLorenz Meier <lm@inf.ethz.ch>2014-03-04 13:41:13 +0100
commited45e813aff84f5646ea7ad1d7ab50f597bdebb9 (patch)
treee126e0f51d38a4ba292818a0c68a50e23dfe2d45
parent454523bebfbaca9a77ba9827ba11454caffaa31d (diff)
downloadpx4-nuttx-ed45e813aff84f5646ea7ad1d7ab50f597bdebb9.tar.gz
px4-nuttx-ed45e813aff84f5646ea7ad1d7ab50f597bdebb9.tar.bz2
px4-nuttx-ed45e813aff84f5646ea7ad1d7ab50f597bdebb9.zip
FAT: move cluster expansion checks to start of IO loops
this fixes a filesystem corruption bug at cluster boundaries. Thanks to tkloss for reporting the issue. Fixes issue #12
-rw-r--r--nuttx/fs/fat/fs_fat32.c104
1 files changed, 50 insertions, 54 deletions
diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c
index 2fbb0cba2..1ef2b23e2 100644
--- a/nuttx/fs/fat/fs_fat32.c
+++ b/nuttx/fs/fat/fs_fat32.c
@@ -518,6 +518,28 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
{
bytesread = 0;
+ /* Check if the current read stream has incremented to the next
+ * cluster boundary
+ */
+
+ if (ff->ff_sectorsincluster < 1)
+ {
+ /* Find the next cluster in the FAT. */
+
+ cluster = fat_getcluster(fs, ff->ff_currentcluster);
+ 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;
+ ff->ff_currentsector = fat_cluster2sector(fs, cluster);
+ ff->ff_sectorsincluster = fs->fs_fatsecperclus;
+ }
+
fat_read_restart:
/* Check if the user has provided a buffer large enough to
@@ -616,28 +638,6 @@ fat_read_restart:
readsize += bytesread;
buflen -= bytesread;
sectorindex = filep->f_pos & SEC_NDXMASK(fs);
-
- /* Check if the current read stream has incremented to the next
- * cluster boundary
- */
-
- if (buflen != 0 && ff->ff_sectorsincluster < 1)
- {
- /* Find the next cluster in the FAT. */
-
- cluster = fat_getcluster(fs, ff->ff_currentcluster);
- 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;
- ff->ff_currentsector = fat_cluster2sector(fs, cluster);
- ff->ff_sectorsincluster = fs->fs_fatsecperclus;
- }
}
fat_semgive(fs);
@@ -756,6 +756,34 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
* hold one or more complete sectors.
*/
+ if (ff->ff_sectorsincluster < 1)
+ {
+ /* Extend the current cluster by one (unless lseek was used to
+ * move the file position back from the end of the file)
+ */
+
+ cluster = fat_extendchain(fs, ff->ff_currentcluster);
+
+ /* Verify the cluster number */
+
+ if (cluster < 0)
+ {
+ ret = cluster;
+ goto errout_with_semaphore;
+ }
+ else if (cluster < 2 || cluster >= fs->fs_nclusters)
+ {
+ ret = -ENOSPC;
+ goto errout_with_semaphore;
+ }
+
+ /* Setup to write the first sector from the new cluster */
+
+ ff->ff_currentcluster = cluster;
+ ff->ff_sectorsincluster = fs->fs_fatsecperclus;
+ ff->ff_currentsector = fat_cluster2sector(fs, cluster);
+ }
+
fat_write_restart:
nsectors = buflen / fs->fs_hwsectorsize;
@@ -891,38 +919,6 @@ fat_write_restart:
byteswritten += writesize;
buflen -= writesize;
sectorindex = filep->f_pos & SEC_NDXMASK(fs);
-
- /* Check if the current read stream has incremented to the next
- * cluster boundary
- */
-
- if (buflen != 0 && ff->ff_sectorsincluster < 1)
- {
- /* Extend the current cluster by one (unless lseek was used to
- * move the file position back from the end of the file)
- */
-
- cluster = fat_extendchain(fs, ff->ff_currentcluster);
-
- /* Verify the cluster number */
-
- if (cluster < 0)
- {
- ret = cluster;
- goto errout_with_semaphore;
- }
- else if (cluster < 2 || cluster >= fs->fs_nclusters)
- {
- ret = -ENOSPC;
- goto errout_with_semaphore;
- }
-
- /* Setup to write the first sector from the new cluster */
-
- ff->ff_currentcluster = cluster;
- ff->ff_sectorsincluster = fs->fs_fatsecperclus;
- ff->ff_currentsector = fat_cluster2sector(fs, cluster);
- }
}
/* The transfer has completed without error. Update the file size */