From e17d3eedc63a01896b7bf8ed9a592748f61246ce Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 30 Apr 2011 23:24:48 +0000 Subject: Misc NXFFS bug fixes git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3545 42af7a65-404d-4744-a932-0658087f49c3 --- apps/examples/nxffs/nxffs_main.c | 18 ++++++--- nuttx/fs/nxffs/nxffs_open.c | 25 +++++++++---- nuttx/fs/nxffs/nxffs_write.c | 81 ++++++++++++++++++++++++++++------------ 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: -- cgit v1.2.3