summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-05 01:15:31 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-05 01:15:31 +0000
commite19726b3e335c2ca6bb58e55af43f1ccb3ac3057 (patch)
tree607c241b48f5358ecd27017ce3b4605aef751b37
parentb85797acfbfb1a29c84a0db6cfded6a6360d3f83 (diff)
downloadnuttx-e19726b3e335c2ca6bb58e55af43f1ccb3ac3057.tar.gz
nuttx-e19726b3e335c2ca6bb58e55af43f1ccb3ac3057.tar.bz2
nuttx-e19726b3e335c2ca6bb58e55af43f1ccb3ac3057.zip
Minor NXFFS fixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3563 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-xnuttx/fs/nxffs/README.txt10
-rw-r--r--nuttx/fs/nxffs/nxffs_pack.c74
-rw-r--r--nuttx/include/nuttx/nxffs.h18
3 files changed, 81 insertions, 21 deletions
diff --git a/nuttx/fs/nxffs/README.txt b/nuttx/fs/nxffs/README.txt
index 8da14bf58..72da497a9 100755
--- a/nuttx/fs/nxffs/README.txt
+++ b/nuttx/fs/nxffs/README.txt
@@ -136,9 +136,6 @@ blocked waiting for itself to close the first file.
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
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
@@ -153,4 +150,11 @@ 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
+ 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.
diff --git a/nuttx/fs/nxffs/nxffs_pack.c b/nuttx/fs/nxffs/nxffs_pack.c
index 57fa11e76..70ae506d4 100644
--- a/nuttx/fs/nxffs/nxffs_pack.c
+++ b/nuttx/fs/nxffs/nxffs_pack.c
@@ -258,19 +258,24 @@ static inline off_t nxffs_mediacheck(FAR struct nxffs_volume_s *volume,
* Input Parameters:
* volume - The volume to be packed
* 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:
* 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,
FAR struct nxffs_pack_s *pack,
- off_t offset)
+ off_t *froffset)
{
struct nxffs_blkentry_s blkentry;
+ off_t offset = *froffset;
off_t wasted;
off_t nbytes;
int ret;
@@ -352,6 +357,7 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume,
* the end-of-flash indication.
*/
+ *froffset = volume->froffset;
return -ENOSPC;
}
@@ -365,9 +371,11 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume,
if (ret < 0)
{
/* 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;
}
}
@@ -975,14 +983,43 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
* begin the packing operation.
*/
- ret = nxffs_startpos(volume, &pack, iooffset);
+ packed = false;
+ ret = nxffs_startpos(volume, &pack, &iooffset);
if (ret < 0)
{
/* This is a normal situation if the volume is full */
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
{
@@ -990,26 +1027,27 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
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
- * ioblock and iooffset with the position of the first inode header.
- */
-
- pack.ioblock = nxffs_getblock(volume, pack.dest.entry.hoffset);
- pack.iooffset = nxffs_getoffset(volume, pack.dest.entry.hoffset, pack.ioblock);
+ pack.ioblock = nxffs_getblock(volume, pack.dest.entry.hoffset);
+ pack.iooffset = nxffs_getoffset(volume, pack.dest.entry.hoffset, pack.ioblock);
- /* Reserve space for the inode header. Note we are guaranteed by
- * nxffs_startpos() that the inode header will fit at hoffset.
- */
+ /* Reserve space for the inode header. Note we are guaranteed by
+ * nxffs_startpos() that the inode header will fit at hoffset.
+ */
- pack.iooffset += SIZEOF_NXFFS_INODE_HDR;
- 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
* the ioblock and through the final erase block on the FLASH.
*/
- packed = false;
for (eblock = pack.ioblock / volume->blkper;
eblock < volume->geo.neraseblocks;
eblock++)
diff --git a/nuttx/include/nuttx/nxffs.h b/nuttx/include/nuttx/nxffs.h
index d601b4a41..4d1343676 100644
--- a/nuttx/include/nuttx/nxffs.h
+++ b/nuttx/include/nuttx/nxffs.h
@@ -59,14 +59,32 @@
# error "CONFIG_NXFFS_ERASEDSTATE must be either 0x00 or 0xff"
#endif
+/* Don't bother trying to pack things closer together than this. */
+
#ifndef CONFIG_NXFFS_PACKTHRESHOLD
# define CONFIG_NXFFS_PACKTHRESHOLD 32
#endif
+/* This is how big an inode name is permitted to be. */
+
#ifndef CONFIG_NXFFS_MAXNAMLEN
# define CONFIG_NXFFS_MAXNAMLEN 255
#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
* 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