summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/examples/nxffs/nxffs_main.c18
-rw-r--r--nuttx/fs/nxffs/nxffs_open.c25
-rw-r--r--nuttx/fs/nxffs/nxffs_write.c81
3 files changed, 87 insertions, 37 deletions
diff --git a/apps/examples/nxffs/nxffs_main.c b/apps/examples/nxffs/nxffs_main.c
index 9a3532e2c..bef334aa4 100644
--- a/apps/examples/nxffs/nxffs_main.c
+++ b/apps/examples/nxffs/nxffs_main.c
@@ -172,7 +172,7 @@ static inline void nxffs_randname(FAR struct nxffs_filedesc_s *file)
if (!file->name)
{
fprintf(stderr, "ERROR: Failed to allocate name, length=%d\n", namelen);
- exit(3);
+ exit(5);
}
memcpy(file->name, g_mountdir, dirlen);
@@ -335,13 +335,19 @@ int user_start(int argc, char *argv[])
exit(3);
}
- /* Then write a file to the NXFFS file system */
+ /* 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)
+ */
- ret = nxffs_wrfile();
- if (ret < 0)
+ for (;;)
{
- fprintf(stderr, "ERROR: Failed to write a file\n");
- exit(3);
+ ret = nxffs_wrfile();
+ if (ret < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to write a file\n");
+ exit(4);
+ }
}
return 0;
diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c
index 9d435f760..45168d3da 100644
--- a/nuttx/fs/nxffs/nxffs_open.c
+++ b/nuttx/fs/nxffs/nxffs_open.c
@@ -310,7 +310,7 @@ static inline int nxffs_namerased(FAR struct nxffs_volume_s *volume,
{
/* This is where we will put the name */
- wrfile->ofile.entry.hoffset = nxffs_iotell(volume);
+ wrfile->ofile.entry.noffset = nxffs_iotell(volume);
}
return ret;
}
@@ -375,7 +375,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
* until the new file is successfully written.
*/
- truncate = true;
+ truncate = true;
}
/* The file exists and we were not asked to truncate (and recreate) it.
@@ -435,6 +435,15 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
wrfile->ofile.entry.utc = time(NULL);
wrfile->truncate = truncate;
+ /* Save a copy of the inode name. */
+
+ wrfile->ofile.entry.name = strdup(name);
+ if (!wrfile->ofile.entry.name)
+ {
+ ret = -ENOMEM;
+ goto errout_with_ofile;
+ }
+
/* Allocate FLASH memory for the file and set up for the write.
*
* Loop until the inode header is configured or until a failure occurs.
@@ -472,7 +481,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
if (ret != -ENOSPC || packed)
{
fdbg("Failed to find inode header memory: %d\n", -ret);
- goto errout_with_ofile;
+ goto errout_with_name;
}
/* -ENOSPC is a special case.. It means that the volume is full.
@@ -483,7 +492,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
if (ret < 0)
{
fdbg("Failed to pack the volume: %d\n", -ret);
- goto errout_with_ofile;
+ goto errout_with_name;
}
/* After packing the volume, froffset will be updated to point to the
@@ -527,7 +536,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
if (ret != -ENOSPC || packed)
{
fdbg("Failed to find inode name memory: %d\n", -ret);
- goto errout_with_ofile;
+ goto errout_with_name;
}
/* -ENOSPC is a special case.. It means that the volume is full.
@@ -538,7 +547,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
if (ret < 0)
{
fdbg("Failed to pack the volume: %d\n", -ret);
- goto errout_with_ofile;
+ goto errout_with_name;
}
/* After packing the volume, froffset will be updated to point to the
@@ -561,6 +570,8 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
*ppofile = &wrfile->ofile;
return OK;
+errout_with_name:
+ kfree(wrfile->ofile.entry.name);
errout_with_ofile:
#ifndef CONFIG_NXFSS_PREALLOCATED
kfree(wrfile);
@@ -739,7 +750,7 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
goto errout;
}
- if (wrfile->truncate)
+ if (wrfile->truncate && wrfile->ofile.entry.name)
{
fvdbg("Removing old file: %s\n", wrfile->ofile.entry.name);
diff --git a/nuttx/fs/nxffs/nxffs_write.c b/nuttx/fs/nxffs/nxffs_write.c
index e56d2e0e3..3d7ad063d 100644
--- a/nuttx/fs/nxffs/nxffs_write.c
+++ b/nuttx/fs/nxffs/nxffs_write.c
@@ -388,25 +388,32 @@ static inline ssize_t nxffs_wrappend(FAR struct nxffs_volume_s *volume,
memcpy(&volume->cache[offset], buffer, nbytestowrite);
+ /* Increment the number of bytes written to the data block */
+
+ wrfile->datlen += nbytestowrite;
+
/* Re-calculate the CRC */
- wrfile->crc = crc32(&volume->cache[offset], nbytestowrite);
+ offset = volume->iooffset + SIZEOF_NXFFS_DATA_HDR;
+ wrfile->crc = crc32(&volume->cache[offset], wrfile->datlen);
/* And write the partial write block to FLASH -- unless the data
* block is full. In that case, the block will be written below.
*/
-
- ret = nxffs_wrcache(volume, volume->ioblock, 1);
- if (ret < 0)
+
+ if (nbytesleft > 0)
{
- fdbg("nxffs_wrcache failed: %d\n", -ret);
- return ret;
+ ret = nxffs_wrcache(volume, volume->ioblock, 1);
+ if (ret < 0)
+ {
+ fdbg("nxffs_wrcache failed: %d\n", -ret);
+ return ret;
+ }
}
}
- /* Calculate the number of bytes remaining in data block */
+ /* Check if the data block is now full */
- nbytesleft = maxsize - nbytestowrite;
if (nbytesleft <= 0)
{
/* The data block is full, write the block to FLASH */
@@ -441,6 +448,7 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
{
FAR struct nxffs_volume_s *volume;
FAR struct nxffs_wrfile_s *wrfile;
+ ssize_t nbytesleft;
ssize_t nbyteswritten;
int ret;
@@ -484,7 +492,8 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
* error occurs)
*/
- while (buflen > 0)
+ nbytesleft = buflen;
+ while (nbytesleft > 0)
{
/* Have we already allocated the data block? */
@@ -493,7 +502,7 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
/* No, allocate the data block now */
wrfile->datlen = 0;
- ret = nxffs_wralloc(volume, wrfile, buflen);
+ ret = nxffs_wralloc(volume, wrfile, nbytesleft);
if (ret < 0)
{
fdbg("Failed to allocate a data block: %d\n", -ret);
@@ -510,7 +519,7 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
ret = nxffs_reverify(volume, wrfile);
if (ret < 0)
{
- fdbg("Failed to verify FLASH a data block: %d\n", -ret);
+ fdbg("Failed to verify FLASH data block: %d\n", -ret);
goto errout_with_semaphore;
}
@@ -518,18 +527,23 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
* block to flash.
*/
- nbyteswritten = nxffs_wrappend(volume, wrfile, buffer, buflen);
+ nbyteswritten = nxffs_wrappend(volume, wrfile, buffer, nbytesleft);
if (nbyteswritten < 0)
{
- fdbg("Failed to append to FLASH a data block: %d\n", -ret);
+ fdbg("Failed to append to FLASH to a data block: %d\n", -ret);
goto errout_with_semaphore;
}
/* Decrement the number of bytes remaining to be written */
- buflen -= nbyteswritten;
+ nbytesleft -= nbyteswritten;
}
+ /* Success.. return the number of bytes written */
+
+ ret = buflen;
+ filep->f_pos = wrfile->datlen;
+
errout_with_semaphore:
sem_post(&volume->exclsem);
errout:
@@ -574,13 +588,11 @@ errout:
int nxffs_wrreserve(FAR struct nxffs_volume_s *volume, size_t size)
{
- off_t offset;
int ret;
/* Seek to the beginning of the free FLASH region */
- offset = volume->froffset;
- nxffs_ioseek(volume, offset);
+ nxffs_ioseek(volume, volume->froffset);
/* Check for a seek past the end of the volume */
@@ -591,9 +603,15 @@ int nxffs_wrreserve(FAR struct nxffs_volume_s *volume, size_t size)
return -ENOSPC;
}
+ /* Skip over block headers */
+
+ if (volume->iooffset < SIZEOF_NXFFS_BLOCK_HDR)
+ {
+ volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR;
+ }
+
/* Make sure that there is space there to hold the entire object */
- DEBUGASSERT(volume->iooffset >= SIZEOF_NXFFS_BLOCK_HDR);
if (volume->iooffset + size > volume->geo.blocksize)
{
/* We will need to skip to the next block. But first, check if we are
@@ -619,16 +637,14 @@ int nxffs_wrreserve(FAR struct nxffs_volume_s *volume, size_t size)
fdbg("No more valid blocks\n");
return ret;
}
-
volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR;
- offset = volume->ioblock * volume->geo.blocksize + SIZEOF_NXFFS_BLOCK_HDR;
}
/* Update the pointer to the first next free FLASH memory -- reserving this
* block of memory.
*/
- volume->froffset = offset + size;
+ volume->froffset = nxffs_iotell(volume) + size;
return OK;
}
@@ -744,8 +760,8 @@ int nxffs_wrverify(FAR struct nxffs_volume_s *volume, size_t size)
return ret;
}
- volume->iooffset = size;
- volume->froffset = volume->ioblock * volume->geo.blocksize + size;
+ volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR;
+ volume->froffset = volume->ioblock * volume->geo.blocksize + SIZEOF_NXFFS_BLOCK_HDR;
}
/* Return -ENOSPC if there is no erased memory left in the volume for
@@ -804,13 +820,30 @@ int nxffs_wrblkhdr(FAR struct nxffs_volume_s *volume,
/* After the block has been successfully written to flash, update the inode
* statistics and reset the write state.
+ *
+ * volume:
+ * froffset - The offset the next free FLASH region. Set to just after
+ * the inode data block that we just wrote. This is where we will
+ * begin the search for the next inode header or data block.
+ */
+
+ volume->froffset = (wrfile->doffset + wrfile->datlen + SIZEOF_NXFFS_DATA_HDR);
+
+ /* wrfile->file.entry:
+ * datlen: Total file length accumulated so far. When the file is
+ * closed, this will hold the file length.
+ * doffset: Offset to the first data block. Only the offset to the
+ * first data block is saved.
*/
wrfile->ofile.entry.datlen += wrfile->datlen;
- if (wrfile->ofile.entry.doffset)
+ if (wrfile->ofile.entry.doffset == 0)
{
wrfile->ofile.entry.doffset = wrfile->doffset;
}
+
+ /* Return success */
+
ret = OK;
errout: