NXFFS file deletion is functional
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3552 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
2e16ee3714
commit
40c085d15a
@ -55,6 +55,12 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Re-define fdbg so that the output does not have so much diagnostic info.
|
||||
* This should still, however, always agree with the defintion in debug.h.
|
||||
*/
|
||||
|
||||
#undef fdbg
|
||||
#define fdbg lib_rawprintf
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -73,6 +79,10 @@ struct nxffs_blkinfo_s
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char g_hdrformat[] = " BLOCK:OFFS TYPE STATE LENGTH\n";
|
||||
static const char g_format[] = " %5d:%-5d %s %s %5d\n";
|
||||
static const char g_blkformat[] = "--%5d:%-5d %s %s %5d\n";
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -161,8 +171,7 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
|
||||
{
|
||||
/* Not than we cannot verify the inode header */
|
||||
|
||||
fdbg(" Block %d:%d: Unverifiable inode, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "UNVERFD", datlen);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
@ -186,8 +195,7 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
|
||||
|
||||
if (crc != ecrc)
|
||||
{
|
||||
fdbg(" Block %d:%d: Potential inode with bad CRC, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "CRC ", datlen);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
@ -195,18 +203,15 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
|
||||
|
||||
if (state == INODE_STATE_FILE)
|
||||
{
|
||||
fdbg(" Block %d:%d: Verified FILE inode, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "OK ", datlen);
|
||||
}
|
||||
else if (state == INODE_STATE_DELETED)
|
||||
{
|
||||
fdbg(" Block %d:%d: Verified DELETED inode, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "DELETED", datlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
fdbg(" Block %d:%d: Verified inode with CORRUPTED state, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "CORRUPT", datlen);
|
||||
}
|
||||
return noffs + inode.namlen - offset;
|
||||
}
|
||||
@ -253,15 +258,13 @@ static inline ssize_t nxffs_analyzedata(FAR struct nxffs_blkinfo_s *blkinfo,
|
||||
|
||||
if (crc != ecrc)
|
||||
{
|
||||
fdbg(" Block %d:%d: Potential data block with bad CRC, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "DATA ", "CRC ", datlen);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* If must be a good header */
|
||||
|
||||
fdbg(" Block %d:%d: Verified data block, datlen: %d\n",
|
||||
blkinfo->block, offset, datlen);
|
||||
fdbg(g_format, blkinfo->block, offset, "DATA ", "OK ", datlen);
|
||||
return SIZEOF_NXFFS_DATA_HDR + datlen;
|
||||
}
|
||||
#endif
|
||||
@ -282,7 +285,6 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo)
|
||||
int hdrndx;
|
||||
int datndx;
|
||||
int inndx;
|
||||
int nerased;
|
||||
int i;
|
||||
|
||||
/* Verify that there is a header on the block */
|
||||
@ -290,15 +292,34 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo)
|
||||
blkhdr = (FAR struct nxffs_block_s *)blkinfo->buffer;
|
||||
if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0)
|
||||
{
|
||||
fdbg(" Block %d:0: ERROR -- no header\n", blkinfo->block);
|
||||
fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "NO FRMT",
|
||||
blkinfo->geo.blocksize);
|
||||
}
|
||||
else if (blkhdr->state == BLOCK_STATE_GOOD)
|
||||
{
|
||||
size_t datsize = blkinfo->geo.blocksize - SIZEOF_NXFFS_BLOCK_HDR;
|
||||
size_t nerased = nxffs_erased(blkinfo->buffer + SIZEOF_NXFFS_BLOCK_HDR, datsize);
|
||||
if (nerased == datsize)
|
||||
{
|
||||
fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "ERASED ",
|
||||
blkinfo->geo.blocksize);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "IN USE ",
|
||||
blkinfo->geo.blocksize);
|
||||
}
|
||||
}
|
||||
else if (blkhdr->state == BLOCK_STATE_BAD)
|
||||
{
|
||||
fdbg(" Block %d:0: BAD\n", blkinfo->block);
|
||||
fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "BAD ",
|
||||
blkinfo->geo.blocksize);
|
||||
}
|
||||
else if (blkhdr->state != BLOCK_STATE_GOOD)
|
||||
else
|
||||
{
|
||||
fdbg(" Block %d:0: ERROR -- bad state\n", blkinfo->block);
|
||||
fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "CORRUPT",
|
||||
blkinfo->geo.blocksize);
|
||||
}
|
||||
|
||||
/* Serach for Inode and data block headers. */
|
||||
@ -310,11 +331,7 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo)
|
||||
{
|
||||
uint8_t ch = blkinfo->buffer[i];
|
||||
|
||||
if (ch == CONFIG_NXFFS_ERASEDSTATE)
|
||||
{
|
||||
nerased++;
|
||||
}
|
||||
else if (ch == g_inodemagic[inndx])
|
||||
if (ch == g_inodemagic[inndx])
|
||||
{
|
||||
inndx++;
|
||||
datndx = 0;
|
||||
@ -402,8 +419,9 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd)
|
||||
/* Now read every block on the device */
|
||||
|
||||
fdbg("NXFFS Dump:\n");
|
||||
blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize;
|
||||
fdbg(g_hdrformat);
|
||||
|
||||
blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize;
|
||||
for (blkinfo.block = 0, blkinfo.offset = 0;
|
||||
blkinfo.block < blkinfo.nblocks;
|
||||
blkinfo.block++, blkinfo.offset += blkinfo.geo.blocksize)
|
||||
|
@ -82,9 +82,11 @@
|
||||
* information.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success. Otherwise, a negater errno value is returned
|
||||
* Zero on success. Otherwise, a negated errno value is returned
|
||||
* indicating the nature of the failure.
|
||||
*
|
||||
* On return, the
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
||||
@ -93,6 +95,7 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
||||
struct nxffs_inode_s inode;
|
||||
uint32_t ecrc;
|
||||
uint32_t crc;
|
||||
uint8_t state;
|
||||
int namlen;
|
||||
int ret;
|
||||
|
||||
@ -104,11 +107,15 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
||||
nxffs_ioseek(volume, offset);
|
||||
memcpy(&inode, &volume->cache[volume->iooffset], SIZEOF_NXFFS_INODE_HDR);
|
||||
|
||||
/* Check if the file is marked as deleted. */
|
||||
/* Check if the file state is recognized. */
|
||||
|
||||
if (inode.state != INODE_STATE_FILE)
|
||||
state = inode.state;
|
||||
if (state != INODE_STATE_FILE && state != INODE_STATE_DELETED)
|
||||
{
|
||||
return -ENOENT;
|
||||
/* This can't be a valid inode.. don't bother with the rest */
|
||||
|
||||
ret = -ENOENT;
|
||||
goto errout_no_offset;
|
||||
}
|
||||
|
||||
/* Copy the packed header into the user-friendly buffer */
|
||||
@ -133,7 +140,8 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
||||
if (!entry->name)
|
||||
{
|
||||
fdbg("Failed to allocate name, namlen: %d\n", namlen);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto errout_no_offset;
|
||||
}
|
||||
|
||||
/* Seek to the expected location of the name in FLASH */
|
||||
@ -148,7 +156,7 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("nxffsx_rdcache failed: %d\n", -ret);
|
||||
return ret;
|
||||
goto errout_with_name;
|
||||
}
|
||||
|
||||
/* Read the file name from the expected offset in FLASH */
|
||||
@ -162,10 +170,45 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
||||
if (crc != ecrc)
|
||||
{
|
||||
fdbg("CRC entry: %08x CRC calculated: %08x\n", ecrc, crc);
|
||||
nxffs_freeentry(entry);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto errout_with_name;
|
||||
}
|
||||
|
||||
/* We have a good inode header.. but it still could a deleted file.
|
||||
* Check the file state.
|
||||
*/
|
||||
|
||||
if (state != INODE_STATE_FILE)
|
||||
{
|
||||
/* It is a deleted file. But still, the data offset and the
|
||||
* start size is good so we can use this information to advance
|
||||
* further in FLASH memory and reduce the search time.
|
||||
*/
|
||||
|
||||
offset = entry->doffset + entry->datlen + SIZEOF_NXFFS_DATA_HDR;
|
||||
nxffs_freeentry(entry);
|
||||
ret = -ENOENT;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Everything is good.. leave the offset pointing to the valid inode
|
||||
* header.
|
||||
*/
|
||||
|
||||
return OK;
|
||||
|
||||
/* On errors where we are suspicious of the validity of the inode header,
|
||||
* we need to increment the file position to just after the "good" magic
|
||||
* word.
|
||||
*/
|
||||
|
||||
errout_with_name:
|
||||
nxffs_freeentry(entry);
|
||||
errout_no_offset:
|
||||
offset += NXFFS_MAGICSIZE;
|
||||
errout:
|
||||
nxffs_ioseek(volume, offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -102,7 +102,7 @@ int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name)
|
||||
{
|
||||
/* We can't remove the inode if it is open */
|
||||
|
||||
fdbg("Inode is open\n");
|
||||
fdbg("Inode '%s' is open\n", name);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name)
|
||||
ret = nxffs_findinode(volume, name, &entry);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("Inode '%s' not found\n");
|
||||
fdbg("Inode '%s' not found\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user