Fix NXFFS positioning bug

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3569 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-05-06 15:19:07 +00:00
parent 97da40cebb
commit 0f1bdb6ab2
5 changed files with 79 additions and 51 deletions

View File

@ -11,6 +11,7 @@ Contents:
Headers
NXFFS Limitations
Multiple Writers
ioctls
Things to Do
General NXFFS organization
@ -133,6 +134,16 @@ Also note that a deadlock condition would occur if the SAME thread
attempted to open two files for writing. The thread would would be
blocked waiting for itself to close the first file.
ioctls
======
The file system supports to ioctls:
FIOC_REFORMAT: Will force the flash to be erased and a fresh, empty
NXFFS file system to be written on it.
FIOC_OPTIMIZE: Will force immediate repacking of the file system. This
will increase the amount of wear on the FLASH if you use this!
Things to Do
============
@ -150,7 +161,7 @@ Things to Do
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.
- Wear leveling could be improved as well. Files are re-packed at the front
- Wear leveling might be improved (?). Files are re-packed at the front
of FLASH as part of the clean-up operation. However, that means the files
that are not modified often become fixed in place at the beginning of
FLASH. This reduces the size of the pool moving files at the end of the

View File

@ -134,7 +134,7 @@ static inline int nxffs_hdrpos(FAR struct nxffs_volume_s *volume,
wrfile->ofile.entry.hoffset = nxffs_iotell(volume);
}
return OK;
return ret;
}
/****************************************************************************
@ -189,7 +189,7 @@ static inline int nxffs_nampos(FAR struct nxffs_volume_s *volume,
wrfile->ofile.entry.noffset = nxffs_iotell(volume);
}
return OK;
return ret;
}
/****************************************************************************

View File

@ -610,7 +610,7 @@ errout:
*
* Returned Values:
* Zero on success; Otherwise, a negated errno value is returned to
* indicate the nature of the failure.
* indicate the nature of the failure (not used).
*
****************************************************************************/
@ -651,55 +651,60 @@ static int nxffs_wrinodehdr(FAR struct nxffs_volume_s *volume,
* header that is called during the normal file close operation:
*/
return nxffs_wrinode(volume, &pack->dest.entry);
ret = nxffs_wrinode(volume, &pack->dest.entry);
}
/* Cases 1: Both the inode header and name are in the unwritten cache memory. */
/* Initialize the inode header */
iooffset += (ioblock - pack->block0) * volume->geo.blocksize;
inode = (FAR struct nxffs_inode_s *)&volume->pack[iooffset];
memcpy(inode->magic, g_inodemagic, NXFFS_MAGICSIZE);
nxffs_wrle32(inode->noffs, pack->dest.entry.noffset);
nxffs_wrle32(inode->doffs, pack->dest.entry.doffset);
nxffs_wrle32(inode->utc, pack->dest.entry.utc);
nxffs_wrle32(inode->crc, 0);
nxffs_wrle32(inode->datlen, pack->dest.entry.datlen);
/* Get the length of the inode name */
namlen = strlen(pack->dest.entry.name);
DEBUGASSERT(namlen < CONFIG_NXFFS_MAXNAMLEN);
inode->state = CONFIG_NXFFS_ERASEDSTATE;
inode->namlen = namlen;
/* Calculate the CRC */
crc = crc32((FAR const uint8_t *)inode, SIZEOF_NXFFS_INODE_HDR);
crc = crc32part((FAR const uint8_t *)pack->dest.entry.name, namlen, crc);
/* Finish the inode header */
inode->state = INODE_STATE_FILE;
nxffs_wrle32(inode->crc, crc);
/* If any open files reference this inode, then update the open file
* state.
*/
ret = nxffs_updateinode(volume, &pack->dest.entry);
if (ret < 0)
else
{
fdbg("Failed to update inode info: %s\n", -ret);
/* Cases 1: Both the inode header and name are in the unwritten cache
* memory.
*
* Initialize the inode header.
*/
iooffset += (ioblock - pack->block0) * volume->geo.blocksize;
inode = (FAR struct nxffs_inode_s *)&volume->pack[iooffset];
memcpy(inode->magic, g_inodemagic, NXFFS_MAGICSIZE);
nxffs_wrle32(inode->noffs, pack->dest.entry.noffset);
nxffs_wrle32(inode->doffs, pack->dest.entry.doffset);
nxffs_wrle32(inode->utc, pack->dest.entry.utc);
nxffs_wrle32(inode->crc, 0);
nxffs_wrle32(inode->datlen, pack->dest.entry.datlen);
/* Get the length of the inode name */
namlen = strlen(pack->dest.entry.name);
DEBUGASSERT(namlen < CONFIG_NXFFS_MAXNAMLEN);
inode->state = CONFIG_NXFFS_ERASEDSTATE;
inode->namlen = namlen;
/* Calculate the CRC */
crc = crc32((FAR const uint8_t *)inode, SIZEOF_NXFFS_INODE_HDR);
crc = crc32part((FAR const uint8_t *)pack->dest.entry.name, namlen, crc);
/* Finish the inode header */
inode->state = INODE_STATE_FILE;
nxffs_wrle32(inode->crc, crc);
/* If any open files reference this inode, then update the open file
* state.
*/
ret = nxffs_updateinode(volume, &pack->dest.entry);
if (ret < 0)
{
fdbg("Failed to update inode info: %s\n", -ret);
}
}
/* Reset the dest inode information */
nxffs_freeentry(&pack->dest.entry);
memset(&pack->dest, 0, sizeof(struct nxffs_packstream_s));
return OK;
return ret;
}
/****************************************************************************

View File

@ -416,10 +416,20 @@ int nxffs_rdblkhdr(FAR struct nxffs_volume_s *volume, off_t offset,
uint32_t crc;
uint16_t doffset;
uint16_t dlen;
int ret;
/* Make sure the the block containing the data block header is in the cache */
nxffs_ioseek(volume, offset);
ret = nxffs_rdcache(volume, volume->ioblock);
if (ret < 0)
{
fvdbg("Failed to read data into cache: %d\n", ret);
return ret;
}
/* Read the header at the FLASH offset */
nxffs_ioseek(volume, offset);
doffset = volume->iooffset;
memcpy(&blkhdr, &volume->cache[doffset], SIZEOF_NXFFS_DATA_HDR);

View File

@ -102,7 +102,7 @@
*
* On successful return the following are also valid:
*
* wrfile->doffset - Flash offset to candidate header position
* wrfile->doffset - Flash offset to candidate data block header position
* volume->ioblock - Read/write block number of the block containing the
* header position
* volume->iooffset - The offset in the block to the candidate header
@ -122,11 +122,13 @@ static inline int nxffs_hdrpos(FAR struct nxffs_volume_s *volume,
ret = nxffs_wrreserve(volume, SIZEOF_NXFFS_DATA_HDR + size);
if (ret == OK)
{
/* Save the offset to the FLASH region reserved for the inode header */
/* Save the offset to the FLASH region reserved for the data block
* header
*/
wrfile->doffset = nxffs_iotell(volume);
}
return OK;
return ret;
}
/****************************************************************************
@ -163,7 +165,7 @@ static inline int nxffs_hdrpos(FAR struct nxffs_volume_s *volume,
*
* On successful return the following are also valid:
*
* wrfile->doffset - Flash offset to candidate header position
* wrfile->doffset - Flash offset to candidate data block header position
* volume->ioblock - Read/write block number of the block containing the
* header position
* volume->iooffset - The offset in the block to the candidate header
@ -183,7 +185,7 @@ static inline int nxffs_hdrerased(FAR struct nxffs_volume_s *volume,
ret = nxffs_wrverify(volume, SIZEOF_NXFFS_DATA_HDR + size);
if (ret == OK)
{
/* This is where we will put the header */
/* This is where we will put the data block header */
wrfile->doffset = nxffs_iotell(volume);
}