diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-04 18:49:53 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-04 18:49:53 +0000 |
commit | 29bc6e24ce51bb7b97591f5d354bc3b9b3b05602 (patch) | |
tree | b812c7578cc5369898dc14d49913d490cd75d0de | |
parent | 90b3f2e71415c4cb55bd40ac25b863fa4ed63818 (diff) | |
download | nuttx-29bc6e24ce51bb7b97591f5d354bc3b9b3b05602.tar.gz nuttx-29bc6e24ce51bb7b97591f5d354bc3b9b3b05602.tar.bz2 nuttx-29bc6e24ce51bb7b97591f5d354bc3b9b3b05602.zip |
More NXFFS bugfixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3560 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | apps/examples/nxffs/nxffs_main.c | 31 | ||||
-rw-r--r-- | nuttx/drivers/mtd/rammtd.c | 18 | ||||
-rwxr-xr-x | nuttx/fs/nxffs/README.txt | 3 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_dump.c | 9 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_pack.c | 57 |
5 files changed, 89 insertions, 29 deletions
diff --git a/apps/examples/nxffs/nxffs_main.c b/apps/examples/nxffs/nxffs_main.c index 19e93138d..779375629 100644 --- a/apps/examples/nxffs/nxffs_main.c +++ b/apps/examples/nxffs/nxffs_main.c @@ -223,6 +223,7 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file) { size_t offset; int fd; + int ret; /* Create a random file */ @@ -259,8 +260,21 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file) fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Write offset: %d\n", offset); fprintf(stderr, " Write size: %d\n", nbytestowrite); - nxffs_freefile(file); close(fd); + + /* Remove any garbage file that might have been left behind */ + + ret = unlink(file->name); + if (ret < 0) + { + fprintf(stderr, " Failed to remove corrupted file\n"); + } + else + { + fprintf(stderr, " Successfully removed corrupted file\n"); + } + + nxffs_freefile(file); return ERROR; } else if (nbyteswritten != nbytestowrite) @@ -510,13 +524,8 @@ static int nxffs_delfiles(void) /* And delete the next undeleted file after that random index */ - for (j = ndx + 1; j != ndx; j++) + for (j = ndx + 1; j != ndx;) { - if (j >= CONFIG_EXAMPLES_NXFFS_MAXOPEN) - { - j = 0; - } - file = &g_files[j]; if (file->name && !file->deleted) { @@ -535,6 +544,14 @@ static int nxffs_delfiles(void) break; } } + + /* Increment the index and test for wrap-around */ + + if (++j >= CONFIG_EXAMPLES_NXFFS_MAXOPEN) + { + j = 0; + } + } } diff --git a/nuttx/drivers/mtd/rammtd.c b/nuttx/drivers/mtd/rammtd.c index 6a2e1f4c2..a7adf4b99 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 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. */ |