diff options
-rw-r--r-- | apps/examples/nxffs/nxffs_main.c | 84 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_pack.c | 127 |
2 files changed, 155 insertions, 56 deletions
diff --git a/apps/examples/nxffs/nxffs_main.c b/apps/examples/nxffs/nxffs_main.c index 738e8ecf8..19e93138d 100644 --- a/apps/examples/nxffs/nxffs_main.c +++ b/apps/examples/nxffs/nxffs_main.c @@ -553,6 +553,7 @@ int user_start(int argc, char *argv[]) { FAR struct mtd_dev_s *mtd; int ret; + int i; /* Seed the random number generated */ @@ -585,48 +586,67 @@ int user_start(int argc, char *argv[]) exit(3); } - /* Then write a files to the NXFFS file system until either (1) all of the - * open file structures are utilized or until (2) NXFFS reports an error - * (hopefully that the file system is full) + /* Loop a few times ... file the file system with some random, files, + * delete some files randomly, fill the file system with more random file, + * delete, etc. This beats the FLASH very hard! */ - ret = nxffs_fillfs(); - fprintf(stderr, "Filled file system\n"); - fprintf(stderr, " Number of files: %d\n", g_nfiles); - fprintf(stderr, " Number deleted: %d\n", g_ndeleted); - nxffs_dump(mtd); + for (i = 0; i < 2; i++) + { + /* Write a files to the NXFFS file system until either (1) all of the + * open file structures are utilized or until (2) NXFFS reports an error + * (hopefully that the file system is full) + */ + + ret = nxffs_fillfs(); + fprintf(stderr, "Filled file system\n"); + fprintf(stderr, " Number of files: %d\n", g_nfiles); + fprintf(stderr, " Number deleted: %d\n", g_ndeleted); + nxffs_dump(mtd); - /* Verify all files written to FLASH */ + /* Verify all files written to FLASH */ + + ret = nxffs_verifyfs(); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to verify files\n"); + } + else + { + fprintf(stderr, "Verified!\n"); + } - ret = nxffs_verifyfs(); - if (ret < 0) - { - fprintf(stderr, "ERROR: Failed to verify files\n"); fprintf(stderr, " Number of files: %d\n", g_nfiles); fprintf(stderr, " Number deleted: %d\n", g_ndeleted); - } - /* Delete some files */ + /* Delete some files */ - ret = nxffs_delfiles(); - if (ret < 0) - { - fprintf(stderr, "ERROR: Failed to delete files\n"); - } - else - { - fprintf(stderr, "Deleted some files\n"); - } - fprintf(stderr, " Number of files: %d\n", g_nfiles); - fprintf(stderr, " Number deleted: %d\n", g_ndeleted); - nxffs_dump(mtd); + ret = nxffs_delfiles(); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to delete files\n"); + } + else + { + fprintf(stderr, "Deleted some files\n"); + } + + fprintf(stderr, " Number of files: %d\n", g_nfiles); + fprintf(stderr, " Number deleted: %d\n", g_ndeleted); + nxffs_dump(mtd); - /* Verify all files written to FLASH */ + /* Verify all files written to FLASH */ + + ret = nxffs_verifyfs(); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to verify files\n"); + } + else + { + fprintf(stderr, "Verified!\n"); + } - ret = nxffs_verifyfs(); - if (ret < 0) - { - fprintf(stderr, "ERROR: Failed to verify files\n"); fprintf(stderr, " Number of files: %d\n", g_nfiles); fprintf(stderr, " Number deleted: %d\n", g_ndeleted); } diff --git a/nuttx/fs/nxffs/nxffs_pack.c b/nuttx/fs/nxffs/nxffs_pack.c index ac5289398..5815d0a1a 100644 --- a/nuttx/fs/nxffs/nxffs_pack.c +++ b/nuttx/fs/nxffs/nxffs_pack.c @@ -208,6 +208,10 @@ static inline off_t nxffs_mediacheck(FAR struct nxffs_volume_s *volume, off_t froffset; int ret; + /* Initialize the packing structure to all zero */ + + memset(pack, 0, sizeof(struct nxffs_pack_s)); + /* Find the FLASH offset to the first valid block */ volume->ioblock = 0; @@ -233,7 +237,7 @@ static inline off_t nxffs_mediacheck(FAR struct nxffs_volume_s *volume, { /* No valid entries on the media -- Return offset zero */ - return -ENOSPC; + return 0; } /* Okay.. the start block and first entry have been found */ @@ -461,7 +465,7 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume, */ namlen = strlen(pack->dest.entry.name); - if (pack->iooffset + namlen < volume->geo.blocksize) + if (pack->iooffset + namlen > volume->geo.blocksize) { /* No.. that inode name will not fit in this block. Return an * indication that we are at the end of the block and try again @@ -488,7 +492,7 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume, */ mindata = MIN(NXFFS_MINDATA, pack->dest.entry.datlen); - if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata < volume->geo.blocksize) + if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata > volume->geo.blocksize) { /* No.. return an indication that we are at the end of the block * and try again later. @@ -500,13 +504,43 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume, /* Yes.. reserve space for the data block header */ pack->dest.entry.doffset = nxffs_packtell(volume, pack); - pack->iooffset += SIZEOF_NXFFS_DATA_HDR; + pack->iooffset += SIZEOF_NXFFS_DATA_HDR; + + /* Initialize the output data stream to start with the first data block */ + + pack->dest.blkoffset = pack->dest.entry.doffset; + pack->dest.blklen = 0; + pack->dest.blkpos = 0; } - /* Initialize the output data stream to start with the first data block */ + /* State 4: Starting a new block. Verify that there is space in the current + * block for another (minimal sized) block + */ + + if (pack->dest.blkoffset == 0) + { + /* Will the data block header plus a minimal amount of data fit in this + * block? (or the whole file if the file is very small). + */ + + mindata = MIN(NXFFS_MINDATA, pack->dest.entry.datlen); + if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata > volume->geo.blocksize) + { + /* No.. return an indication that we are at the end of the block + * and try again later. + */ + + return -ENOSPC; + } + + /* Yes.. reserve space for the data block header */ + + pack->dest.blkoffset = nxffs_packtell(volume, pack); + pack->iooffset += SIZEOF_NXFFS_DATA_HDR; + pack->dest.blklen = 0; + pack->dest.blkpos = 0; + } - pack->dest.blkoffset = pack->dest.entry.doffset; - pack->dest.blkpos = 0; return OK; } @@ -711,7 +745,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Are we currently processing a block from the source stream? */ - if (pack->src.blkoffset) + if (pack->src.blkoffset == 0) { /* No.. setup the source stream */ @@ -724,14 +758,29 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, } /* We enter here on a new block every time, so we always have to setup - * the dest data stream. + * the dest data stream. There should never be data block allocated at + * this point in time. */ + DEBUGASSERT(pack->dest.blkoffset == 0 && pack->dest.blkpos == 0); + ret = nxffs_destsetup(volume, pack); if (ret < 0) { - fdbg("Failed to configure the dest stream: %d\n", -ret); - return ret; + /* -ENOSPC is a special return value which simply means that all of the + * has been used up to the end. We need to return OK in this case and + * resume at the next block. + */ + + if (ret == -ENOSPC) + { + return OK; + } + else + { + fdbg("Failed to configure the dest stream: %d\n", -ret); + return ret; + } } /* Loop, transferring data from the source block to the destination pack @@ -743,7 +792,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, { /* Determine how much data is available in the dest pack buffer */ - uint16_t destlen = volume->geo.blocksize - pack->dest.blkpos; + uint16_t destlen = volume->geo.blocksize - pack->iooffset; /* Dermined how much data is available in the src data block */ @@ -755,16 +804,22 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, nxffs_ioseek(volume, pack->src.blkoffset + pack->src.blkpos); memcpy(&pack->iobuffer[pack->iooffset], &volume->cache[volume->iooffset], xfrlen); + /* Increment counts and offset for this data transfer */ + + pack->src.fpos += xfrlen; /* Source data offsets */ + pack->src.blkpos += xfrlen; + pack->dest.fpos += xfrlen; /* Destination data offsets */ + pack->dest.blkpos += xfrlen; + volume->iooffset += xfrlen; /* Source I/O block offset */ + pack->iooffset += xfrlen; /* Destination I/O block offset */ + /* Now, either the (1) src block has been fully transferred, (2) all - * of the source data has been transferred, of (3) the the destination + * of the source data has been transferred, or (3) the the destination * block is full, .. or all three. * * Check if all of the bytes in the source inode have been transferred. */ - pack->src.fpos += xfrlen; - pack->src.blkpos += xfrlen; - if (pack->src.fpos >= pack->src.entry.datlen) { /* Write the final destination data block header and inode @@ -777,7 +832,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Find the next valid source inode */ offset = pack->src.blkoffset + pack->src.blklen; - ret = nxffs_nextentry(volume, offset, &pack->src.entry); + ret = nxffs_nextentry(volume, offset, &pack->src.entry); if (ret < 0) { /* No more valid inode entries. Just return an end-of-flash error @@ -797,9 +852,15 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Setup the dest stream */ + pack->dest.entry.hoffset = 0; + pack->dest.entry.noffset = 0; + pack->dest.entry.doffset = 0; pack->dest.entry.name = pack->src.entry.name; pack->dest.entry.utc = pack->src.entry.utc; pack->dest.entry.datlen = pack->src.entry.datlen; + pack->dest.blkoffset = 0; + pack->dest.blklen = 0; + pack->dest.blkpos = 0; pack->src.entry.name = NULL; /* Is there sufficient space at the end of the I/O block to hold @@ -815,16 +876,37 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, return OK; } + /* Set the current inode header off to the current position and reserve + * the memory. + */ + pack->dest.entry.hoffset = nxffs_packtell(volume, pack); + pack->iooffset += SIZEOF_NXFFS_INODE_HDR; + + /* Then configure the destination stream */ + ret = nxffs_destsetup(volume, pack); if (ret < 0) { - return ret; + /* -ENOSPC is a special return value which simply means that all of the + * has been used up to the end. We need to return OK in this case and + * resume at the next block. + */ + + if (ret == -ENOSPC) + { + return OK; + } + else + { + fdbg("Failed to configure the dest stream: %d\n", -ret); + return ret; + } } } /* Not at the end of the source data stream. Check if we are at the - * end of the current data block. + * end of the current source data block. */ else if (pack->src.blkpos >= pack->src.blklen) @@ -833,7 +915,8 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Yes.. find the next data block in the source input stream. */ - ret = nxffs_nextblock(volume, offset, &blkentry); + offset = pack->src.blkoffset + pack->src.blklen; + ret = nxffs_nextblock(volume, offset, &blkentry); if (ret < 0) { fdbg("Failed to find next data block: %d\n", -ret); @@ -849,10 +932,6 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Check if the destination block is full */ - pack->dest.fpos += xfrlen; - pack->dest.blkpos += xfrlen; - pack->iooffset += xfrlen; - if (pack->iooffset >= volume->geo.blocksize) { /* Yes.. Write the destination data block header and return success */ |