More NXFFS bugfixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3560 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
4e23151cdd
commit
5196a00b2d
4 changed files with 65 additions and 22 deletions
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue