summaryrefslogtreecommitdiff
path: root/nuttx/fs
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-09-15 20:05:00 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-09-15 20:05:00 +0000
commitea058253e4344a337b61a3e412694361b07f082e (patch)
tree0747fdb7fc6b535c06b91ccc95319cb04fdd41ea /nuttx/fs
parent893721387a67b3e472506c21bfdb70cd6fe62776 (diff)
downloadpx4-nuttx-ea058253e4344a337b61a3e412694361b07f082e.tar.gz
px4-nuttx-ea058253e4344a337b61a3e412694361b07f082e.tar.bz2
px4-nuttx-ea058253e4344a337b61a3e412694361b07f082e.zip
Fix a critical bug in FAT sector management
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3955 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs')
-rw-r--r--nuttx/fs/fat/fs_fat32.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c
index d41df88d5..c7157b091 100644
--- a/nuttx/fs/fat/fs_fat32.c
+++ b/nuttx/fs/fat/fs_fat32.c
@@ -630,6 +630,7 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
int32_t cluster;
unsigned int byteswritten;
unsigned int writesize;
+ unsigned int bufsize;
unsigned int nsectors;
uint8_t *userbuffer = (uint8_t*)buffer;
int sectorindex;
@@ -776,28 +777,56 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
goto errout_with_semaphore;
}
}
+ else
+ {
+ /* But in this rare case, we do have to mark the unused cached
+ * buffer as the current buffer.
+ */
+
+ ff->ff_cachesector = ff->ff_currentsector;
+ }
/* Copy the partial sector from the user buffer */
- writesize = fs->fs_hwsectorsize - sectorindex;
- if (writesize > buflen)
+ bufsize = fs->fs_hwsectorsize - sectorindex;
+ if (bufsize > buflen)
{
- /* We will not write to the end of the buffer */
+ /* We will not write to the end of the buffer. Set
+ * write size to the size of the user buffer.
+ */
writesize = buflen;
}
else
{
- /* We will write to the end of the buffer (or beyond) */
+ /* We will write to the end of the cached sector and
+ * perhaps beyond. Set writesize to the number of
+ * bytes still available in the cached sector.
+ */
- ff->ff_sectorsincluster--;
- ff->ff_currentsector++;
+ writesize = bufsize;
}
+ /* Copy the data into the cached sector and make sure that the
+ * cached sector is marked "dirty"
+ */
+
memcpy(&ff->ff_buffer[sectorindex], userbuffer, writesize);
+ ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED);
+
+ /* Do we need to write more in the next sector? We may need
+ * to this if we wrote to the end of the cached sector.
+ */
- ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED);
- ff->ff_cachesector = ff->ff_currentsector;
+ if (writesize >= bufsize)
+ {
+ /* We will write to the end of the buffer (or beyond). Bump
+ * up the current sector number.
+ */
+
+ ff->ff_sectorsincluster--;
+ ff->ff_currentsector++;
+ }
}
/* Set up for the next write */