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:
parent
6d61ed50e4
commit
f24821c3fa
2
TODO
2
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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user