summaryrefslogtreecommitdiff
path: root/nuttx/fs/nxffs
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 /nuttx/fs/nxffs
parentb85797acfbfb1a29c84a0db6cfded6a6360d3f83 (diff)
downloadpx4-nuttx-e19726b3e335c2ca6bb58e55af43f1ccb3ac3057.tar.gz
px4-nuttx-e19726b3e335c2ca6bb58e55af43f1ccb3ac3057.tar.bz2
px4-nuttx-e19726b3e335c2ca6bb58e55af43f1ccb3ac3057.zip
Minor NXFFS fixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3563 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/nxffs')
-rwxr-xr-xnuttx/fs/nxffs/README.txt10
-rw-r--r--nuttx/fs/nxffs/nxffs_pack.c74
2 files changed, 63 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++)