summaryrefslogtreecommitdiffstats
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-05-04 18:49:53 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-05-04 18:49:53 +0000
commit51740b3bfa2f4db7cf23da37b7152fe597fa6bee (patch)
treeb812c7578cc5369898dc14d49913d490cd75d0de /nuttx
parent5cbf37fadcf91c2eb2a7714116fff4955220a987 (diff)
More NXFFS bugfixes
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3560 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/drivers/mtd/rammtd.c18
-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
4 files changed, 65 insertions, 22 deletions
diff --git a/nuttx/drivers/mtd/rammtd.c b/nuttx/drivers/mtd/rammtd.c
index 6a2e1f4c20..a7adf4b99f 100644
--- a/nuttx/drivers/mtd/rammtd.c
+++ b/nuttx/drivers/mtd/rammtd.c
@@ -127,13 +127,6 @@ static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks
DEBUGASSERT(dev);
- /* Convert the erase block to a logical block and the number of blocks
- * in logical block numbers
- */
-
- startblock *= CONFIG_RAMMTD_BLKPER;
- nblocks *= CONFIG_RAMMTD_BLKPER;
-
/* Don't let the erase exceed the size of the ram buffer */
if (startblock >= priv->nblocks)
@@ -141,11 +134,18 @@ static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks
return 0;
}
- if (startblock + nblocks >= priv->nblocks)
+ if (startblock + nblocks > priv->nblocks)
{
- nblocks = priv->nblocks - nblocks;
+ nblocks = priv->nblocks - startblock;
}
+ /* Convert the erase block to a logical block and the number of blocks
+ * in logical block numbers
+ */
+
+ startblock *= CONFIG_RAMMTD_BLKPER;
+ nblocks *= CONFIG_RAMMTD_BLKPER;
+
/* Get the offset corresponding to the first block and the size
* corresponding to the number of blocks.
*/
diff --git a/nuttx/fs/nxffs/README.txt b/nuttx/fs/nxffs/README.txt
index 47a7d7f971..8da14bf58c 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 fbd3807d35..889f10b528 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 9a80b41a9c..b4dc10ccab 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.
*/