summaryrefslogtreecommitdiff
path: root/nuttx/fs/nxffs/nxffs_pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/fs/nxffs/nxffs_pack.c')
-rw-r--r--nuttx/fs/nxffs/nxffs_pack.c57
1 files changed, 47 insertions, 10 deletions
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.
*/