summaryrefslogtreecommitdiff
path: root/nuttx/fs/nxffs
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-04 18:49:53 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-04 18:49:53 +0000
commit29bc6e24ce51bb7b97591f5d354bc3b9b3b05602 (patch)
treeb812c7578cc5369898dc14d49913d490cd75d0de /nuttx/fs/nxffs
parent90b3f2e71415c4cb55bd40ac25b863fa4ed63818 (diff)
downloadpx4-nuttx-29bc6e24ce51bb7b97591f5d354bc3b9b3b05602.tar.gz
px4-nuttx-29bc6e24ce51bb7b97591f5d354bc3b9b3b05602.tar.bz2
px4-nuttx-29bc6e24ce51bb7b97591f5d354bc3b9b3b05602.zip
More NXFFS bugfixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3560 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/nxffs')
-rwxr-xr-xnuttx/fs/nxffs/README.txt3
-rw-r--r--nuttx/fs/nxffs/nxffs_dump.c9
-rw-r--r--nuttx/fs/nxffs/nxffs_pack.c57
3 files changed, 56 insertions, 13 deletions
diff --git a/nuttx/fs/nxffs/README.txt b/nuttx/fs/nxffs/README.txt
index 47a7d7f97..8da14bf58 100755
--- a/nuttx/fs/nxffs/README.txt
+++ b/nuttx/fs/nxffs/README.txt
@@ -151,3 +151,6 @@ Things to Do
may be necessary whenever an lseek() is done, but not in general. Read
performance could be improved by keeping FLASH offset and read positional
information in the read open file structure.
+- Fault tolerance must be improved. We need to be absolutely certain that
+ any FLASH errors do not cause the file system to behavior incorrectly.
+
diff --git a/nuttx/fs/nxffs/nxffs_dump.c b/nuttx/fs/nxffs/nxffs_dump.c
index fbd3807d3..889f10b52 100644
--- a/nuttx/fs/nxffs/nxffs_dump.c
+++ b/nuttx/fs/nxffs/nxffs_dump.c
@@ -194,7 +194,7 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
if (crc != ecrc)
{
- fdbg(g_format, blkinfo->block, offset, "INODE", "CRC ", datlen);
+ fdbg(g_format, blkinfo->block, offset, "INODE", "CRC BAD", datlen);
return ERROR;
}
@@ -212,7 +212,10 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
{
fdbg(g_format, blkinfo->block, offset, "INODE", "CORRUPT", datlen);
}
- return noffs + inode.namlen - offset;
+
+ /* Return the block-relative offset to the next byte after the inode name */
+
+ return noffs + inode.namlen - offset - blkinfo->offset;
}
#endif
@@ -257,7 +260,7 @@ static inline ssize_t nxffs_analyzedata(FAR struct nxffs_blkinfo_s *blkinfo,
if (crc != ecrc)
{
- fdbg(g_format, blkinfo->block, offset, "DATA ", "CRC ", datlen);
+ fdbg(g_format, blkinfo->block, offset, "DATA ", "CRC BAD", datlen);
return ERROR;
}
diff --git a/nuttx/fs/nxffs/nxffs_pack.c b/nuttx/fs/nxffs/nxffs_pack.c
index 9a80b41a9..b4dc10cca 100644
--- a/nuttx/fs/nxffs/nxffs_pack.c
+++ b/nuttx/fs/nxffs/nxffs_pack.c
@@ -450,6 +450,8 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume,
{
DEBUGASSERT(pack->iooffset + SIZEOF_NXFFS_INODE_HDR <= volume->geo.blocksize);
pack->dest.entry.hoffset = nxffs_packtell(volume, pack);
+ memset(&pack->iobuffer[pack->iooffset], CONFIG_NXFFS_ERASEDSTATE,
+ SIZEOF_NXFFS_INODE_HDR);
pack->iooffset += SIZEOF_NXFFS_INODE_HDR;
}
@@ -480,7 +482,7 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume,
* calculate the header CRC.
*/
- memcpy(&volume->pack[pack->iooffset], pack->dest.entry.name, namlen);
+ memcpy(&pack->iobuffer[pack->iooffset], pack->dest.entry.name, namlen);
/* Reserve space for the inode name */
@@ -688,7 +690,7 @@ static void nxffs_wrdathdr(FAR struct nxffs_volume_s *volume,
/* Update the entire data block CRC (including the header) */
- crc = crc32(&volume->cache[volume->iooffset], pack->dest.blklen + SIZEOF_NXFFS_DATA_HDR);
+ crc = crc32(&pack->iobuffer[iooffset], pack->dest.blklen + SIZEOF_NXFFS_DATA_HDR);
nxffs_wrle32(dathdr->crc, crc);
/* Setup state to allocate the next data block */
@@ -788,6 +790,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume,
pack->src.blkpos += xfrlen;
pack->dest.fpos += xfrlen; /* Destination data offsets */
pack->dest.blkpos += xfrlen;
+ pack->dest.blklen += xfrlen; /* Destination data block size */
volume->iooffset += xfrlen; /* Source I/O block offset */
pack->iooffset += xfrlen; /* Destination I/O block offset */
@@ -948,6 +951,7 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
off_t iooffset;
off_t eblock;
off_t block;
+ bool packed;
int i;
int ret;
@@ -1002,11 +1006,15 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
* the ioblock and through the final erase block on the FLASH.
*/
+ packed = false;
for (eblock = pack.ioblock / volume->blkper;
eblock < volume->geo.neraseblocks;
eblock++)
{
- /* Read the erase block into the pack buffer. */
+ /* Read the erase block into the pack buffer. We need to do this even
+ * if we are overwriting the entire block so that we skip over
+ * previously marked bad blocks.
+ */
pack.block0 = eblock * volume->blkper;
ret = MTD_BREAD(volume->mtd, pack.block0, volume->blkper, volume->pack);
@@ -1030,28 +1038,57 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
{
/* Set the I/O position. Note on the first time we get
* pack.iooffset will hold the offset in the first I/O block
- * to the first inode header.
+ * to the first inode header. After that, it will always
+ * refer to the first byte after the block header.
*/
pack.ioblock = block;
- /* Check if this is a valid block (it will be valid for the
- * first block.
+ /* If this is not a valid block or if we have already
+ * finished packing the valid inode entries, then just fall
+ * through, reset the FLASH memory to the erase state, and
+ * write the reset values to FLASH. (The first block that
+ * we want to process will always be valid -- we have
+ * already verified that).
*/
- if (nxffs_packvalid(&pack))
+ if (!packed && nxffs_packvalid(&pack))
{
/* Yes.. pack data into this block */
ret = nxffs_packblock(volume, &pack);
if (ret < 0)
{
- fdbg("Failed to pack into block %d: %d\n",
- block, ret);
- goto errout_with_pack;
+ /* The error -ENOSPC is a special value that simply
+ * means that there is nothing further to be packed.
+ */
+
+ if (ret == -ENOSPC)
+ {
+ packed = true;
+ }
+ else
+ {
+ /* Otherwise, something really bad happened */
+
+ fdbg("Failed to pack into block %d: %d\n",
+ block, ret);
+ goto errout_with_pack;
+ }
}
}
+ /* Set any unused portion at the end of the block to the
+ * erased state.
+ */
+
+ if (pack.iooffset < volume->geo.blocksize)
+ {
+ memset(&pack.iobuffer[pack.iooffset],
+ CONFIG_NXFFS_ERASEDSTATE,
+ volume->geo.blocksize - pack.iooffset);
+ }
+
/* Next time we get here, pack.iooffset will point to the
* first byte after the block header.
*/