summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-02 01:30:30 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-02 01:30:30 +0000
commit6e723db07e440e19453f35e8e3a3850e3b4d7373 (patch)
tree238656fe5bc625b70bf5d74d0ff24d510079503b
parenta86b56511ae7a4f183841e3708407625fcec8e2c (diff)
downloadpx4-nuttx-6e723db07e440e19453f35e8e3a3850e3b4d7373.tar.gz
px4-nuttx-6e723db07e440e19453f35e8e3a3850e3b4d7373.tar.bz2
px4-nuttx-6e723db07e440e19453f35e8e3a3850e3b4d7373.zip
More NXFFS bugfixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3550 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/examples/nxffs/nxffs_main.c35
-rw-r--r--nuttx/TODO2
-rw-r--r--nuttx/configs/sim/nxffs/defconfig2
-rw-r--r--nuttx/fs/nxffs/nxffs_dump.c6
-rw-r--r--nuttx/fs/nxffs/nxffs_open.c63
-rw-r--r--nuttx/fs/nxffs/nxffs_read.c93
-rw-r--r--nuttx/fs/nxffs/nxffs_write.c20
7 files changed, 146 insertions, 75 deletions
diff --git a/apps/examples/nxffs/nxffs_main.c b/apps/examples/nxffs/nxffs_main.c
index 9ba7c5fad..8c12825fa 100644
--- a/apps/examples/nxffs/nxffs_main.c
+++ b/apps/examples/nxffs/nxffs_main.c
@@ -318,31 +318,41 @@ static ssize_t nxffs_rdblock(int fd, FAR struct nxffs_filedesc_s *file,
size_t offset, size_t len)
{
size_t maxio = (rand() % CONFIG_EXAMPLES_NXFFS_MAXIO) + 1;
- size_t nbytestoread = len - offset;
ssize_t nbytesread;
- if (nbytestoread > maxio)
+ if (len > maxio)
{
- nbytestoread = maxio;
+ len = maxio;
}
- nbytesread = read(fd, &g_fileimage[offset], nbytestoread);
+ nbytesread = read(fd, &g_fileimage[offset], len);
if (nbytesread < 0)
{
fprintf(stderr, "Failed to read file: %d\n", errno);
fprintf(stderr, " File name: %s\n", file->name);
fprintf(stderr, " File size: %d\n", file->len);
fprintf(stderr, " Read offset: %d\n", offset);
- fprintf(stderr, " Read size: %d\n", nbytestoread);
+ fprintf(stderr, " Read size: %d\n", len);
return ERROR;
}
- else if (nbytesread != nbytestoread)
+ else if (nbytesread == 0)
+ {
+#if 0 /* No... we do this on purpose sometimes */
+ fprintf(stderr, "Unexpected end-of-file:\n");
+ fprintf(stderr, " File name: %s\n", file->name);
+ fprintf(stderr, " File size: %d\n", file->len);
+ fprintf(stderr, " Read offset: %d\n", offset);
+ fprintf(stderr, " Read size: %d\n", len);
+#endif
+ return ERROR;
+ }
+ else if (nbytesread != len)
{
fprintf(stderr, "Partial read:\n");
fprintf(stderr, " File name: %s\n", file->name);
fprintf(stderr, " File size: %d\n", file->len);
fprintf(stderr, " Read offset: %d\n", offset);
- fprintf(stderr, " Read size: %d\n", nbytestoread);
+ fprintf(stderr, " Read size: %d\n", len);
fprintf(stderr, " Bytes read: %d\n", nbytesread);
}
return nbytesread;
@@ -372,7 +382,7 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file)
/* Read all of the data info the fileimage buffer using random read sizes */
- for (ntotalread =0; ntotalread < file->len; )
+ for (ntotalread = 0; ntotalread < file->len; )
{
nbytesread = nxffs_rdblock(fd, file, ntotalread, file->len - ntotalread);
if (nbytesread < 0)
@@ -399,11 +409,12 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file)
/* Try reading past the end of the file */
nbytesread = nxffs_rdblock(fd, file, ntotalread, 1024) ;
- if (nbytesread >= 0)
+ if (nbytesread > 0)
{
fprintf(stderr, "Read past the end of file\n");
- fprintf(stderr, " File name: %s\n", file->name);
- fprintf(stderr, " File size: %d\n", file->len);
+ fprintf(stderr, " File name: %s\n", file->name);
+ fprintf(stderr, " File size: %d\n", file->len);
+ fprintf(stderr, " Bytes read: %d\n", nbytesread);
close(fd);
return ERROR;
}
@@ -461,7 +472,7 @@ static int nxffs_verifyfs(void)
}
else
{
- fprintf(stderr, "File %d file OK\n", i);
+ fprintf(stderr, "File %d: OK\n", i);
}
}
}
diff --git a/nuttx/TODO b/nuttx/TODO
index 24666fc92..23e9c7200 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -392,6 +392,8 @@ o Libraries (lib/)
o File system / Generic drivers (fs/, drivers/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ NOTE: The NXFFS file system has its own TODO list at nuttx/fs/nxffs/README.txt
+
Description: Implement chmod(), truncate().
Status: Open
Priority: Low
diff --git a/nuttx/configs/sim/nxffs/defconfig b/nuttx/configs/sim/nxffs/defconfig
index c3edcfc15..acedc357d 100644
--- a/nuttx/configs/sim/nxffs/defconfig
+++ b/nuttx/configs/sim/nxffs/defconfig
@@ -116,7 +116,7 @@ CONFIG_ARCH_BOARD_SIM=y
#
#CONFIG_APPS_DIR=
CONFIG_DEBUG=y
-CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_VERBOSE=n
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEBUG_FS=y
CONFIG_MM_REGIONS=1
diff --git a/nuttx/fs/nxffs/nxffs_dump.c b/nuttx/fs/nxffs/nxffs_dump.c
index ccbaf320e..5534af749 100644
--- a/nuttx/fs/nxffs/nxffs_dump.c
+++ b/nuttx/fs/nxffs/nxffs_dump.c
@@ -193,12 +193,12 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
/* If must be a good header */
- if (state = INODE_STATE_FILE)
+ if (state == INODE_STATE_FILE)
{
fdbg(" Block %d:%d: Verified FILE inode, datlen: %d\n",
blkinfo->block, offset, datlen);
}
- else if (state = INODE_STATE_DELETED)
+ else if (state == INODE_STATE_DELETED)
{
fdbg(" Block %d:%d: Verified DELETED inode, datlen: %d\n",
blkinfo->block, offset, datlen);
@@ -249,7 +249,7 @@ static inline ssize_t nxffs_analyzedata(FAR struct nxffs_blkinfo_s *blkinfo,
nxffs_wrle32(dathdr.crc, 0);
crc = crc32((FAR const uint8_t *)&dathdr, SIZEOF_NXFFS_DATA_HDR);
- crc = crc32part(&blkinfo->buffer[blkinfo->offset + SIZEOF_NXFFS_DATA_HDR], datlen, crc);
+ crc = crc32part(&blkinfo->buffer[offset + SIZEOF_NXFFS_DATA_HDR], datlen, crc);
if (crc != ecrc)
{
diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c
index 604d1a0f4..0c101b78e 100644
--- a/nuttx/fs/nxffs/nxffs_open.c
+++ b/nuttx/fs/nxffs/nxffs_open.c
@@ -702,15 +702,15 @@ errout:
}
/****************************************************************************
- * Name: nxffs_freeofile
+ * Name: nxffs_remofile
*
* Description:
- * Free resources held by an open file.
+ * Remove an entry from the open file list.
*
****************************************************************************/
-static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume,
- FAR struct nxffs_ofile_s *ofile)
+static inline void nxffs_remofile(FAR struct nxffs_volume_s *volume,
+ FAR struct nxffs_ofile_s *ofile)
{
FAR struct nxffs_ofile_s *prev;
FAR struct nxffs_ofile_s *curr;
@@ -735,25 +735,37 @@ static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume,
{
volume->ofiles = ofile->flink;
}
+ }
+ else
+ {
+ fdbg("ERROR: Open inode %p not found\n", ofile);
+ }
+}
+
+/****************************************************************************
+ * Name: nxffs_freeofile
+ *
+ * Description:
+ * Free resources held by an open file.
+ *
+ ****************************************************************************/
- /* Release the open file entry */
+static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume,
+ FAR struct nxffs_ofile_s *ofile)
+{
+ /* Release the open file entry */
- nxffs_freeentry(&ofile->entry);
+ nxffs_freeentry(&ofile->entry);
- /* Then free the open file container (unless this the pre-alloated
- * write-only open file container)
- */
+ /* Then free the open file container (unless this the pre-alloated
+ * write-only open file container)
+ */
#ifdef CONFIG_NXFSS_PREALLOCATED
- if ((FAR struct nxffs_wrfile_s*)ofile != &g_wrfile)
+ if ((FAR struct nxffs_wrfile_s*)ofile != &g_wrfile)
#endif
- {
- kfree(ofile);
- }
- }
- else
{
- fdbg("ERROR: Open inode %p not found\n", ofile);
+ kfree(ofile);
}
}
@@ -797,6 +809,13 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
}
}
+ /* Truncation is implemented by writing the new file, then deleting the
+ * older version of the file. Note that we removed the entry from the
+ * open file list earlier in the close sequence; this will prevent the
+ * open file check from failing when we remove the old version of the
+ * file.
+ */
+
if (wrfile->truncate && wrfile->ofile.entry.name)
{
fvdbg("Removing old file: %s\n", wrfile->ofile.entry.name);
@@ -1059,16 +1078,22 @@ int nxffs_close(FAR struct file *filep)
ret = OK;
if (ofile->crefs == 1)
{
- /* Decrementing the reference count would take it zero. Handle
- * finalization of the write operation.
+ /* Decrementing the reference count would take it zero.
+ *
+ * Remove the entry from the open file list. We do this early
+ * to avoid some chick-and-egg problems with file truncation.
*/
+ nxffs_remofile(volume, ofile);
+
+ /* Handle special finalization of the write operation. */
+
if (ofile->mode == O_WROK)
{
ret = nxffs_wrclose(volume, (FAR struct nxffs_wrfile_s *)ofile);
}
- /* Delete the open file state structure */
+ /* Release all resouces held by the open file */
nxffs_freeofile(volume, ofile);
}
diff --git a/nuttx/fs/nxffs/nxffs_read.c b/nuttx/fs/nxffs/nxffs_read.c
index 91bff3956..bfc4270b4 100644
--- a/nuttx/fs/nxffs/nxffs_read.c
+++ b/nuttx/fs/nxffs/nxffs_read.c
@@ -65,6 +65,7 @@ struct nxffs_blkentry_s
{
off_t hoffset; /* Offset to the block data header */
uint16_t datlen; /* Length of data following the header */
+ uint16_t foffset; /* Offset to start of data */
};
/****************************************************************************
@@ -273,17 +274,18 @@ int nxffs_nextblock(FAR struct nxffs_volume_s *volume, off_t offset,
* data headers.
*
* Input Parameters:
- * volume - Describes the current volume
- * entry - Describes the open inode
- * fpos - The desired file position
+ * volume - Describes the current volume
+ * entry - Describes the open inode
+ * fpos - The desired file position
+ * blkentry - Describes the block entry that we are positioned in
*
****************************************************************************/
static ssize_t nxffs_rdseek(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_entry_s *entry,
- off_t fpos)
+ off_t fpos,
+ FAR struct nxffs_blkentry_s *blkentry)
{
- struct nxffs_blkentry_s blkentry;
size_t datstart;
size_t datend;
off_t offset;
@@ -302,7 +304,7 @@ static ssize_t nxffs_rdseek(FAR struct nxffs_volume_s *volume,
{
/* Check if the next data block contains the sought after file position */
- ret = nxffs_nextblock(volume, offset, &blkentry);
+ ret = nxffs_nextblock(volume, offset, blkentry);
if (ret < 0)
{
fdbg("nxffs_nextblock failed: %d\n", -ret);
@@ -312,17 +314,18 @@ static ssize_t nxffs_rdseek(FAR struct nxffs_volume_s *volume,
/* Get the range of data offsets for this data block */
datstart = datend;
- datend += blkentry.datlen;
+ datend += blkentry->datlen;
/* Offset to search for the the next data block */
- offset = blkentry.hoffset + SIZEOF_NXFFS_DATA_HDR + blkentry.datlen;
+ offset = blkentry->hoffset + SIZEOF_NXFFS_DATA_HDR + blkentry->datlen;
}
while (datend <= fpos);
/* Return the offset to the data within the current data block */
- nxffs_ioseek(volume, blkentry.hoffset + SIZEOF_NXFFS_DATA_HDR + fpos - datstart);
+ blkentry->foffset = fpos - datstart;
+ nxffs_ioseek(volume, blkentry->hoffset + SIZEOF_NXFFS_DATA_HDR + blkentry->foffset);
return OK;
}
@@ -342,7 +345,12 @@ ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
{
FAR struct nxffs_volume_s *volume;
FAR struct nxffs_ofile_s *ofile;
- ssize_t ret;
+ struct nxffs_blkentry_s blkentry;
+ ssize_t total;
+ size_t available;
+ size_t readsize;
+ ssize_t nread;
+ int ret;
fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos);
@@ -380,40 +388,63 @@ ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
goto errout_with_semaphore;
}
- /* Don't seek past the end of the file */
+ /* Loop until all bytes have been read */
- if (filep->f_pos >= ofile->entry.datlen)
+ for (total = 0; total < buflen; )
{
- /* Return end-of-file */
+ /* Don't seek past the end of the file */
- filep->f_pos = ofile->entry.datlen;
- ret = 0;
- goto errout_with_semaphore;
- }
+ if (filep->f_pos >= ofile->entry.datlen)
+ {
+ /* Return the partial read */
+
+ filep->f_pos = ofile->entry.datlen;
+ break;
+ }
- /* Seek to the current file offset */
+ /* Seek to the current file offset */
- ret = nxffs_rdseek(volume, &ofile->entry, filep->f_pos);
- if (ret < 0)
- {
- fdbg("nxffs_rdseek failed: %d\n", -ret);
- ret = -EACCES;
- goto errout_with_semaphore;
- }
+ ret = nxffs_rdseek(volume, &ofile->entry, filep->f_pos, &blkentry);
+ if (ret < 0)
+ {
+ fdbg("nxffs_rdseek failed: %d\n", -ret);
+ ret = -EACCES;
+ goto errout_with_semaphore;
+ }
- /* Read data from that file offset */
+ /* How many bytes are available at this offset */
+
+ available = blkentry.datlen - blkentry.foffset;
+
+ /* Don't read more than we need to */
+
+ readsize = buflen - total;
+ if (readsize > available)
+ {
+ readsize = available;
+ }
+
+ /* Read data from that file offset */
+
+ nread = nxffs_rddata(volume, (FAR uint8_t *)&buffer[total], readsize);
+ if (nread < 0)
+ {
+ ret = nread;
+ goto errout_with_semaphore;
+ }
- ret = nxffs_rddata(volume, (FAR uint8_t *)buffer, buflen);
- if (ret > 0)
- {
/* Update the file offset */
- filep->f_pos += ret;
+ filep->f_pos += nread;
+ total += nread;
}
+ sem_post(&volume->exclsem);
+ return total;
+
errout_with_semaphore:
sem_post(&volume->exclsem);
errout:
- return ret;
+ return (ssize_t)ret;
}
diff --git a/nuttx/fs/nxffs/nxffs_write.c b/nuttx/fs/nxffs/nxffs_write.c
index 8e91d2a7e..2dcd91654 100644
--- a/nuttx/fs/nxffs/nxffs_write.c
+++ b/nuttx/fs/nxffs/nxffs_write.c
@@ -448,8 +448,9 @@ 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;
+ ssize_t remaining;
+ ssize_t nwritten;
+ ssize_t total;
int ret;
fvdbg("Write %d bytes to offset %d\n", buflen, filep->f_pos);
@@ -492,9 +493,10 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
* error occurs)
*/
- nbytesleft = buflen;
- while (nbytesleft > 0)
+ for (total = 0; total < buflen; )
{
+ remaining = buflen- total;
+
/* Have we already allocated the data block? */
if (wrfile->doffset == 0)
@@ -502,7 +504,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, nbytesleft);
+ ret = nxffs_wralloc(volume, wrfile, remaining);
if (ret < 0)
{
fdbg("Failed to allocate a data block: %d\n", -ret);
@@ -527,8 +529,8 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
* block to flash.
*/
- nbyteswritten = nxffs_wrappend(volume, wrfile, buffer, nbytesleft);
- if (nbyteswritten < 0)
+ nwritten = nxffs_wrappend(volume, wrfile, &buffer[total], remaining);
+ if (nwritten < 0)
{
fdbg("Failed to append to FLASH to a data block: %d\n", -ret);
goto errout_with_semaphore;
@@ -536,12 +538,12 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
/* Decrement the number of bytes remaining to be written */
- nbytesleft -= nbyteswritten;
+ total += nwritten;
}
/* Success.. return the number of bytes written */
- ret = buflen;
+ ret = total;
filep->f_pos = wrfile->datlen;
errout_with_semaphore: