diff --git a/fs/nxffs/nxffs.h b/fs/nxffs/nxffs.h index f2e9572e961..735e4fc0aa8 100644 --- a/fs/nxffs/nxffs.h +++ b/fs/nxffs/nxffs.h @@ -555,6 +555,8 @@ extern off_t nxffs_iotell(FAR struct nxffs_volume_s *volume); * Input Parameters: * volume - Describes the NXFFS volume. The paramters ioblock and iooffset * in the volume structure determine the behavior of nxffs_getc(). + * reserve - If less than this much space is available at the end of the + * block, then skip to the next block. * * Returned Value: * Zero is returned on success. Otherwise, a negated errno indicating the @@ -564,7 +566,7 @@ extern off_t nxffs_iotell(FAR struct nxffs_volume_s *volume); * ****************************************************************************/ -extern int nxffs_getc(FAR struct nxffs_volume_s *volume); +extern int nxffs_getc(FAR struct nxffs_volume_s *volume, uint16_t reserve); /**************************************************************************** * Name: nxffs_freeentry diff --git a/fs/nxffs/nxffs_block.c b/fs/nxffs/nxffs_block.c index 4f3f89f6f18..a069048b894 100644 --- a/fs/nxffs/nxffs_block.c +++ b/fs/nxffs/nxffs_block.c @@ -99,7 +99,9 @@ int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block) ret = nxffs_rdcache(volume, block); if (ret < 0) { - fdbg("Failed to read data into cache: %d\n", ret); + /* Perhaps we are at the end of the media */ + + fvdbg("Failed to read data into cache: %d\n", ret); return ret; } @@ -109,15 +111,29 @@ int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block) */ blkhdr = (FAR struct nxffs_block_s *)volume->cache; - if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) == 0 && - blkhdr->state == BLOCK_STATE_GOOD) + if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) == 0) { - /* The block is valid */ + /* This does appear to be a block */ - return OK; + if (blkhdr->state == BLOCK_STATE_GOOD) + { + /* The block is valid */ + + return OK; + } + else if (blkhdr->state == BLOCK_STATE_BAD) + { + /* -ENOENT is a special indication that this is a properly marked + * bad block + */ + + return -ENOENT; + } } - return -ENOENT; + /* Whatever is here where a block header should be is invalid */ + + return -EINVAL; } /**************************************************************************** diff --git a/fs/nxffs/nxffs_cache.c b/fs/nxffs/nxffs_cache.c index ca0cb101c85..5c5cbaa1875 100644 --- a/fs/nxffs/nxffs_cache.c +++ b/fs/nxffs/nxffs_cache.c @@ -196,6 +196,8 @@ off_t nxffs_iotell(FAR struct nxffs_volume_s *volume) * Input Parameters: * volume - Describes the NXFFS volume. The paramters ioblock and iooffset * in the volume structure determine the behavior of nxffs_getc(). + * reserve - If less than this much space is available at the end of the + * block, then skip to the next block. * * Returned Value: * Zero is returned on success. Otherwise, a negated errno indicating the @@ -203,24 +205,26 @@ off_t nxffs_iotell(FAR struct nxffs_volume_s *volume) * ****************************************************************************/ -int nxffs_getc(FAR struct nxffs_volume_s *volume) +int nxffs_getc(FAR struct nxffs_volume_s *volume, uint16_t reserve) { int ret; + DEBUGASSERT(reserve > 0); + /* Loop to skip over bad blocks */ - + do { - /* Check if we have read past the current block */ + /* Check if we have the reserve amount at the end of the current block */ - if (volume->iooffset >= volume->geo.blocksize) + if (volume->iooffset + reserve > volume->geo.blocksize) { /* Check for attempt to read past the end of FLASH */ off_t nextblock = volume->ioblock + 1; if (nextblock >= volume->nblocks) { - fdbg("End of FLASH encountered\n"); + fvdbg("End of FLASH encountered\n"); return -ENOSPC; } @@ -241,7 +245,7 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume) ret = nxffs_verifyblock(volume, volume->ioblock); if (ret < 0 && ret != -ENOENT) { - fdbg("Failed to read valid data into cache: %d\n", ret); + fvdbg("Failed to read valid data into cache: %d\n", ret); return ret; } } diff --git a/fs/nxffs/nxffs_dump.c b/fs/nxffs/nxffs_dump.c index 889f10b5283..938b1276d99 100644 --- a/fs/nxffs/nxffs_dump.c +++ b/fs/nxffs/nxffs_dump.c @@ -73,6 +73,7 @@ struct nxffs_blkinfo_s off_t nblocks; off_t block; off_t offset; + bool verbose; }; /**************************************************************************** @@ -170,7 +171,10 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo, { /* Not than we cannot verify the inode header */ - fdbg(g_format, blkinfo->block, offset, "INODE", "UNVERFD", datlen); + if (blkinfo->verbose) + { + fdbg(g_format, blkinfo->block, offset, "INODE", "UNVERFD", datlen); + } return ERROR; } @@ -202,11 +206,17 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo, if (state == INODE_STATE_FILE) { - fdbg(g_format, blkinfo->block, offset, "INODE", "OK ", datlen); + if (blkinfo->verbose) + { + fdbg(g_format, blkinfo->block, offset, "INODE", "OK ", datlen); + } } else if (state == INODE_STATE_DELETED) { - fdbg(g_format, blkinfo->block, offset, "INODE", "DELETED", datlen); + if (blkinfo->verbose) + { + fdbg(g_format, blkinfo->block, offset, "INODE", "DELETED", datlen); + } } else { @@ -266,7 +276,10 @@ static inline ssize_t nxffs_analyzedata(FAR struct nxffs_blkinfo_s *blkinfo, /* If must be a good header */ - fdbg(g_format, blkinfo->block, offset, "DATA ", "OK ", datlen); + if (blkinfo->verbose) + { + fdbg(g_format, blkinfo->block, offset, "DATA ", "OK ", datlen); + } return SIZEOF_NXFFS_DATA_HDR + datlen; } #endif @@ -303,8 +316,11 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) size_t nerased = nxffs_erased(blkinfo->buffer + SIZEOF_NXFFS_BLOCK_HDR, datsize); if (nerased == datsize) { - fdbg(g_format, blkinfo->block, 0, "BLOCK", "ERASED ", - blkinfo->geo.blocksize); + if (blkinfo->verbose) + { + fdbg(g_format, blkinfo->block, 0, "BLOCK", "ERASED ", + blkinfo->geo.blocksize); + } return; } #if 0 /* Too much output, to little information */ @@ -384,7 +400,9 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) * and CONFIG_DEBUG_FS must be enabled for this function to do anything. * * Input Parameters: - * mtd - The MTD device that provides the interface to NXFFS-formatted media. + * mtd - The MTD device that provides the interface to NXFFS-formatted + * media. + * verbose - FALSE: only show errors * * Returned Value: * Zero is returned on success. Otherwise, a negated errno value is @@ -392,7 +410,7 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) * ****************************************************************************/ -int nxffs_dump(FAR struct mtd_dev_s *mtd) +int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose) { #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_FS) struct nxffs_blkinfo_s blkinfo; @@ -407,16 +425,20 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd) ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&blkinfo.geo)); if (ret < 0) { - fdbg("MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret); + fdbg("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret); goto errout; } + /* Save the verbose output indication */ + + blkinfo.verbose = verbose; + /* Allocate a buffer to hold one block */ blkinfo.buffer = (FAR uint8_t *)kmalloc(blkinfo.geo.blocksize); if (!blkinfo.buffer) { - fdbg("Failed to allocate block cache\n"); + fdbg("ERROR: Failed to allocate block cache\n"); ret = -ENOMEM; goto errout; } @@ -436,7 +458,7 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd) ret = MTD_BREAD(mtd, blkinfo.block, 1, blkinfo.buffer); if (ret < 0) { - fdbg("Failed to read block %d\n", blkinfo.block); + fdbg("ERROR: Failed to read block %d\n", blkinfo.block); goto errout_with_block; } diff --git a/fs/nxffs/nxffs_initialize.c b/fs/nxffs/nxffs_initialize.c index 6cfd68b5e4b..c040fa64999 100644 --- a/fs/nxffs/nxffs_initialize.c +++ b/fs/nxffs/nxffs_initialize.c @@ -394,7 +394,7 @@ int nxffs_limits(FAR struct nxffs_volume_s *volume) nerased = 0; for (;;) { - int ch = nxffs_getc(volume); + int ch = nxffs_getc(volume, 1); if (ch < 0) { /* Failed to read the next byte... this could mean that the FLASH diff --git a/fs/nxffs/nxffs_inode.c b/fs/nxffs/nxffs_inode.c index 6f77dcf577f..496b87418e6 100644 --- a/fs/nxffs/nxffs_inode.c +++ b/fs/nxffs/nxffs_inode.c @@ -282,7 +282,7 @@ int nxffs_nextentry(FAR struct nxffs_volume_s *volume, off_t offset, { /* Read the next character */ - ch = nxffs_getc(volume); + ch = nxffs_getc(volume, SIZEOF_NXFFS_INODE_HDR - nmagic); if (ch < 0) { fvdbg("nxffs_getc failed: %d\n", -ch); diff --git a/fs/nxffs/nxffs_open.c b/fs/nxffs/nxffs_open.c index 6d8e30f1da1..7f5ffeae064 100644 --- a/fs/nxffs/nxffs_open.c +++ b/fs/nxffs/nxffs_open.c @@ -745,7 +745,7 @@ static inline int nxffs_rdopen(FAR struct nxffs_volume_s *volume, ret = nxffs_findinode(volume, name, &ofile->entry); if (ret != OK) { - fdbg("Inode '%s' not found: %d\n", name, -ret); + fvdbg("Inode '%s' not found: %d\n", name, -ret); goto errout_with_ofile; } diff --git a/fs/nxffs/nxffs_pack.c b/fs/nxffs/nxffs_pack.c index b4dc10ccabc..ea40e1d70ac 100644 --- a/fs/nxffs/nxffs_pack.c +++ b/fs/nxffs/nxffs_pack.c @@ -550,6 +550,7 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume, pack->dest.blkpos = 0; } + volume->froffset = nxffs_packtell(volume, pack); return OK; } @@ -791,8 +792,9 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, 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 */ + volume->iooffset += xfrlen; /* Source I/O block offset */ + volume->froffset += xfrlen; /* Free FLASH offset */ /* Now, either the (1) src block has been fully transferred, (2) all * of the source data has been transferred, or (3) the the destination @@ -896,7 +898,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Yes.. find the next data block in the source input stream. */ - offset = pack->src.blkoffset + SIZEOF_NXFFS_BLOCK_HDR + pack->src.blklen; + offset = pack->src.blkoffset + SIZEOF_NXFFS_DATA_HDR + pack->src.blklen; ret = nxffs_nextblock(volume, offset, &blkentry); if (ret < 0) { @@ -1000,7 +1002,8 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume) * nxffs_startpos() that the inode header will fit at hoffset. */ - pack.iooffset += SIZEOF_NXFFS_INODE_HDR; + pack.iooffset += SIZEOF_NXFFS_INODE_HDR; + volume->froffset = nxffs_packtell(volume, &pack); /* Then pack all erase blocks starting with the erase block that contains * the ioblock and through the final erase block on the FLASH. diff --git a/fs/nxffs/nxffs_read.c b/fs/nxffs/nxffs_read.c index 36f2166bbdd..bc222c1597c 100644 --- a/fs/nxffs/nxffs_read.c +++ b/fs/nxffs/nxffs_read.c @@ -292,7 +292,7 @@ int nxffs_nextblock(FAR struct nxffs_volume_s *volume, off_t offset, { /* Read the next character */ - ch = nxffs_getc(volume); + ch = nxffs_getc(volume, SIZEOF_NXFFS_DATA_HDR - nmagic); if (ch < 0) { fvdbg("nxffs_getc failed: %d\n", -ch); diff --git a/include/nuttx/nxffs.h b/include/nuttx/nxffs.h index 351e70beddd..d601b4a41a8 100644 --- a/include/nuttx/nxffs.h +++ b/include/nuttx/nxffs.h @@ -112,7 +112,9 @@ EXTERN int nxffs_initialize(FAR struct mtd_dev_s *mtd); * and CONFIG_DEBUG_FS must be enabled for this function to do anything. * * Input Parameters: - * mtd - The MTD device that provides the interface to NXFFS-formatted media. + * mtd - The MTD device that provides the interface to NXFFS-formatted + * media. + * verbose - FALSE: only show errors * * Returned Value: * Zero is returned on success. Otherwise, a negated errno value is @@ -120,7 +122,7 @@ EXTERN int nxffs_initialize(FAR struct mtd_dev_s *mtd); * ****************************************************************************/ -EXTERN int nxffs_dump(FAR struct mtd_dev_s *mtd); +EXTERN int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose); #undef EXTERN #ifdef __cplusplus