More NXFFS bugfixes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3550 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-05-02 01:30:30 +00:00
parent 6d61ed50e4
commit f24821c3fa
6 changed files with 126 additions and 66 deletions

2
TODO
View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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,21 +735,6 @@ static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume,
{
volume->ofiles = ofile->flink;
}
/* Release the open file entry */
nxffs_freeentry(&ofile->entry);
/* 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)
#endif
{
kfree(ofile);
}
}
else
{
@ -757,6 +742,33 @@ static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume,
}
}
/****************************************************************************
* Name: nxffs_freeofile
*
* Description:
* Free resources held by an open file.
*
****************************************************************************/
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);
/* 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)
#endif
{
kfree(ofile);
}
}
/****************************************************************************
* Name: nxffs_wrclose
*
@ -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);
}

View File

@ -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 */
/* Seek to the current file offset */
filep->f_pos = ofile->entry.datlen;
break;
}
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;
}
/* Seek to the current file offset */
/* Read data from that file offset */
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;
}
/* 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;
}

View File

@ -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: