diff --git a/fs/nxffs/README.txt b/fs/nxffs/README.txt index 72da497a91..a257351107 100755 --- a/fs/nxffs/README.txt +++ b/fs/nxffs/README.txt @@ -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 diff --git a/fs/nxffs/nxffs_open.c b/fs/nxffs/nxffs_open.c index 28d602294d..99998350b8 100644 --- a/fs/nxffs/nxffs_open.c +++ b/fs/nxffs/nxffs_open.c @@ -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; } /**************************************************************************** diff --git a/fs/nxffs/nxffs_pack.c b/fs/nxffs/nxffs_pack.c index 2d5fc63583..66ae2b0730 100644 --- a/fs/nxffs/nxffs_pack.c +++ b/fs/nxffs/nxffs_pack.c @@ -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; } /**************************************************************************** diff --git a/fs/nxffs/nxffs_read.c b/fs/nxffs/nxffs_read.c index cf9bf78e0a..02f7e528bb 100644 --- a/fs/nxffs/nxffs_read.c +++ b/fs/nxffs/nxffs_read.c @@ -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); diff --git a/fs/nxffs/nxffs_write.c b/fs/nxffs/nxffs_write.c index b0ba59d0c8..b2b9dbab28 100644 --- a/fs/nxffs/nxffs_write.c +++ b/fs/nxffs/nxffs_write.c @@ -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); }