Minor NXFFS fixes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3563 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-05-05 01:15:31 +00:00
parent 9721078fdd
commit d6812a0f9f
3 changed files with 81 additions and 21 deletions

View File

@ -136,9 +136,6 @@ blocked waiting for itself to close the first file.
Things to Do Things to Do
============ ============
- The implementation is not yet finished. It needs at, a minimum,
completion of the file system packing logic. It is not usuable without
that feature.
- The statfs() implementation is minimal. It whould have some calcuation - The statfs() implementation is minimal. It whould have some calcuation
of the f_bfree, f_bavail, f_files, f_ffree return values. of the f_bfree, f_bavail, f_files, f_ffree return values.
- There are too many allocs and frees. More structures may need to be - There are too many allocs and frees. More structures may need to be
@ -153,4 +150,11 @@ Things to Do
information in the read open file structure. information in the read open file structure.
- Fault tolerance must be improved. We need to be absolutely certain that - Fault tolerance must be improved. We need to be absolutely certain that
any FLASH errors do not cause the file system to behavior incorrectly. 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
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
FLASH. As the file system becomes more filled with fixed files at the
front of the device, the level of wear on the blocks at the end of the
FLASH increases.

View File

@ -258,19 +258,24 @@ static inline off_t nxffs_mediacheck(FAR struct nxffs_volume_s *volume,
* Input Parameters: * Input Parameters:
* volume - The volume to be packed * volume - The volume to be packed
* pack - The volume packing state structure. * pack - The volume packing state structure.
* offset - location to return the pointer to first valid inode header. * froffset - On input, this is the location where we should be searching
* for the location to begin packing. If -ENOSPC is returned -- meaning
* that the FLASH -- then no packing can be performed. In this case
* (only) , then the free flash offset is returned through this location.
* *
* Returned Values: * Returned Values:
* Zero on success; Otherwise, a negated errno value is returned to * Zero on success; Otherwise, a negated errno value is returned to
* indicate the nature of the failure. * indicate the nature of the failure. If -ENOSPC is returned then the
* free FLASH offset is also returned.
* *
****************************************************************************/ ****************************************************************************/
static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume, static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_pack_s *pack, FAR struct nxffs_pack_s *pack,
off_t offset) off_t *froffset)
{ {
struct nxffs_blkentry_s blkentry; struct nxffs_blkentry_s blkentry;
off_t offset = *froffset;
off_t wasted; off_t wasted;
off_t nbytes; off_t nbytes;
int ret; int ret;
@ -352,6 +357,7 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume,
* the end-of-flash indication. * the end-of-flash indication.
*/ */
*froffset = volume->froffset;
return -ENOSPC; return -ENOSPC;
} }
@ -365,9 +371,11 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume,
if (ret < 0) if (ret < 0)
{ {
/* No more valid inode entries. Just return an end-of-flash error /* No more valid inode entries. Just return an end-of-flash error
* indication. * indication. However, there could be many deleted inodes; set
* volume->froffset to indicate the true free FLASH position.
*/ */
*froffset = offset;
return -ENOSPC; return -ENOSPC;
} }
} }
@ -975,14 +983,43 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
* begin the packing operation. * begin the packing operation.
*/ */
ret = nxffs_startpos(volume, &pack, iooffset); packed = false;
ret = nxffs_startpos(volume, &pack, &iooffset);
if (ret < 0) if (ret < 0)
{ {
/* This is a normal situation if the volume is full */ /* This is a normal situation if the volume is full */
if (ret == -ENOSPC) if (ret == -ENOSPC)
{ {
return OK; /* In the case where the volume is full, nxffs_startpos() will
* recalculate the free FLASH offset and store in in iooffset. There
* may be deleted files at the end of FLASH. In this case, we don't
* have to pack any files, we simply have to erase FLASH at the end.
* But don't do this unless there is some particularly big FLASH
* savings (otherwise, we risk wearing out these final blocks).
*/
if (iooffset + CONFIG_NXFFS_TAILTHRESHOLD < volume->froffset)
{
/* Yes... we can recover CONFIG_NXFFS_TAILTHRESHOLD bytes */
pack.ioblock = nxffs_getblock(volume, iooffset);
pack.iooffset = nxffs_getoffset(volume, iooffset, pack.ioblock);
volume->froffset = iooffset;
/* Setting packed to true will supress all packing operations */
packed = true;
}
/* Otherwise return OK.. meaning that there is nothing more we can
* do to recover FLASH space.
*/
else
{
return OK;
}
} }
else else
{ {
@ -990,26 +1027,27 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
return ret; return ret;
} }
} }
else
{
/* Otherwise, begin pack at this src/dest block combination. Initialize
* ioblock and iooffset with the position of the first inode header.
*/
/* Otherwise, begin pack at this src/dest block combination. Initialize pack.ioblock = nxffs_getblock(volume, pack.dest.entry.hoffset);
* ioblock and iooffset with the position of the first inode header. pack.iooffset = nxffs_getoffset(volume, pack.dest.entry.hoffset, pack.ioblock);
*/
pack.ioblock = nxffs_getblock(volume, pack.dest.entry.hoffset); /* Reserve space for the inode header. Note we are guaranteed by
pack.iooffset = nxffs_getoffset(volume, pack.dest.entry.hoffset, pack.ioblock); * nxffs_startpos() that the inode header will fit at hoffset.
*/
/* Reserve space for the inode header. Note we are guaranteed by pack.iooffset += SIZEOF_NXFFS_INODE_HDR;
* nxffs_startpos() that the inode header will fit at hoffset. volume->froffset = nxffs_packtell(volume, &pack);
*/ }
pack.iooffset += SIZEOF_NXFFS_INODE_HDR;
volume->froffset = nxffs_packtell(volume, &pack);
/* Then pack all erase blocks starting with the erase block that contains /* Then pack all erase blocks starting with the erase block that contains
* the ioblock and through the final erase block on the FLASH. * the ioblock and through the final erase block on the FLASH.
*/ */
packed = false;
for (eblock = pack.ioblock / volume->blkper; for (eblock = pack.ioblock / volume->blkper;
eblock < volume->geo.neraseblocks; eblock < volume->geo.neraseblocks;
eblock++) eblock++)

View File

@ -59,14 +59,32 @@
# error "CONFIG_NXFFS_ERASEDSTATE must be either 0x00 or 0xff" # error "CONFIG_NXFFS_ERASEDSTATE must be either 0x00 or 0xff"
#endif #endif
/* Don't bother trying to pack things closer together than this. */
#ifndef CONFIG_NXFFS_PACKTHRESHOLD #ifndef CONFIG_NXFFS_PACKTHRESHOLD
# define CONFIG_NXFFS_PACKTHRESHOLD 32 # define CONFIG_NXFFS_PACKTHRESHOLD 32
#endif #endif
/* This is how big an inode name is permitted to be. */
#ifndef CONFIG_NXFFS_MAXNAMLEN #ifndef CONFIG_NXFFS_MAXNAMLEN
# define CONFIG_NXFFS_MAXNAMLEN 255 # define CONFIG_NXFFS_MAXNAMLEN 255
#endif #endif
/* Clean-up can either mean packing files together toward the end of the file
* or, if file are deleted at the end of the file, clean up can simply mean
* erasing the end of FLASH memory so that it can be re-used again. However,
* doing this can also harm the life of the FLASH part because it can mean
* that the tail end of the FLASH is re-used too often.
*
* This threshold determines if/when it is worth erased the tail end of FLASH
* and making it available for re-use (and possible over-wear).
*/
#ifndef CONFIG_NXFFS_TAILTHRESHOLD
# define CONFIG_NXFFS_TAILTHRESHOLD (8*1024)
#endif
/* At present, only a single pre-allocated NXFFS volume is supported. This /* At present, only a single pre-allocated NXFFS volume is supported. This
* is because here can be only a single NXFFS volume mounted at any time. * is because here can be only a single NXFFS volume mounted at any time.
* This has to do with the fact that we bind to an MTD driver (instead of a * This has to do with the fact that we bind to an MTD driver (instead of a