Misc NXFFS bug fixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3545 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
e0f72ff94e
commit
478aaafea4
@ -310,7 +310,7 @@ static inline int nxffs_namerased(FAR struct nxffs_volume_s *volume,
|
|||||||
{
|
{
|
||||||
/* This is where we will put the name */
|
/* This is where we will put the name */
|
||||||
|
|
||||||
wrfile->ofile.entry.hoffset = nxffs_iotell(volume);
|
wrfile->ofile.entry.noffset = nxffs_iotell(volume);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -435,6 +435,15 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume,
|
|||||||
wrfile->ofile.entry.utc = time(NULL);
|
wrfile->ofile.entry.utc = time(NULL);
|
||||||
wrfile->truncate = truncate;
|
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.
|
/* Allocate FLASH memory for the file and set up for the write.
|
||||||
*
|
*
|
||||||
* Loop until the inode header is configured or until a failure occurs.
|
* 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)
|
if (ret != -ENOSPC || packed)
|
||||||
{
|
{
|
||||||
fdbg("Failed to find inode header memory: %d\n", -ret);
|
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.
|
/* -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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to pack the volume: %d\n", -ret);
|
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
|
/* 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)
|
if (ret != -ENOSPC || packed)
|
||||||
{
|
{
|
||||||
fdbg("Failed to find inode name memory: %d\n", -ret);
|
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.
|
/* -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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to pack the volume: %d\n", -ret);
|
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
|
/* 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;
|
*ppofile = &wrfile->ofile;
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
|
errout_with_name:
|
||||||
|
kfree(wrfile->ofile.entry.name);
|
||||||
errout_with_ofile:
|
errout_with_ofile:
|
||||||
#ifndef CONFIG_NXFSS_PREALLOCATED
|
#ifndef CONFIG_NXFSS_PREALLOCATED
|
||||||
kfree(wrfile);
|
kfree(wrfile);
|
||||||
@ -739,7 +750,7 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrfile->truncate)
|
if (wrfile->truncate && wrfile->ofile.entry.name)
|
||||||
{
|
{
|
||||||
fvdbg("Removing old file: %s\n", wrfile->ofile.entry.name);
|
fvdbg("Removing old file: %s\n", wrfile->ofile.entry.name);
|
||||||
|
|
||||||
|
@ -388,14 +388,21 @@ static inline ssize_t nxffs_wrappend(FAR struct nxffs_volume_s *volume,
|
|||||||
|
|
||||||
memcpy(&volume->cache[offset], buffer, nbytestowrite);
|
memcpy(&volume->cache[offset], buffer, nbytestowrite);
|
||||||
|
|
||||||
|
/* Increment the number of bytes written to the data block */
|
||||||
|
|
||||||
|
wrfile->datlen += nbytestowrite;
|
||||||
|
|
||||||
/* Re-calculate the CRC */
|
/* 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
|
/* And write the partial write block to FLASH -- unless the data
|
||||||
* block is full. In that case, the block will be written below.
|
* block is full. In that case, the block will be written below.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (nbytesleft > 0)
|
||||||
|
{
|
||||||
ret = nxffs_wrcache(volume, volume->ioblock, 1);
|
ret = nxffs_wrcache(volume, volume->ioblock, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -403,10 +410,10 @@ static inline ssize_t nxffs_wrappend(FAR struct nxffs_volume_s *volume,
|
|||||||
return 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)
|
if (nbytesleft <= 0)
|
||||||
{
|
{
|
||||||
/* The data block is full, write the block to FLASH */
|
/* 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_volume_s *volume;
|
||||||
FAR struct nxffs_wrfile_s *wrfile;
|
FAR struct nxffs_wrfile_s *wrfile;
|
||||||
|
ssize_t nbytesleft;
|
||||||
ssize_t nbyteswritten;
|
ssize_t nbyteswritten;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -484,7 +492,8 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle
|
|||||||
* error occurs)
|
* error occurs)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (buflen > 0)
|
nbytesleft = buflen;
|
||||||
|
while (nbytesleft > 0)
|
||||||
{
|
{
|
||||||
/* Have we already allocated the data block? */
|
/* 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 */
|
/* No, allocate the data block now */
|
||||||
|
|
||||||
wrfile->datlen = 0;
|
wrfile->datlen = 0;
|
||||||
ret = nxffs_wralloc(volume, wrfile, buflen);
|
ret = nxffs_wralloc(volume, wrfile, nbytesleft);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to allocate a data block: %d\n", -ret);
|
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);
|
ret = nxffs_reverify(volume, wrfile);
|
||||||
if (ret < 0)
|
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;
|
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.
|
* block to flash.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nbyteswritten = nxffs_wrappend(volume, wrfile, buffer, buflen);
|
nbyteswritten = nxffs_wrappend(volume, wrfile, buffer, nbytesleft);
|
||||||
if (nbyteswritten < 0)
|
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;
|
goto errout_with_semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement the number of bytes remaining to be written */
|
/* 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:
|
errout_with_semaphore:
|
||||||
sem_post(&volume->exclsem);
|
sem_post(&volume->exclsem);
|
||||||
errout:
|
errout:
|
||||||
@ -574,13 +588,11 @@ errout:
|
|||||||
|
|
||||||
int nxffs_wrreserve(FAR struct nxffs_volume_s *volume, size_t size)
|
int nxffs_wrreserve(FAR struct nxffs_volume_s *volume, size_t size)
|
||||||
{
|
{
|
||||||
off_t offset;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Seek to the beginning of the free FLASH region */
|
/* Seek to the beginning of the free FLASH region */
|
||||||
|
|
||||||
offset = volume->froffset;
|
nxffs_ioseek(volume, volume->froffset);
|
||||||
nxffs_ioseek(volume, offset);
|
|
||||||
|
|
||||||
/* Check for a seek past the end of the volume */
|
/* 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;
|
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 */
|
/* 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)
|
if (volume->iooffset + size > volume->geo.blocksize)
|
||||||
{
|
{
|
||||||
/* We will need to skip to the next block. But first, check if we are
|
/* 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");
|
fdbg("No more valid blocks\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR;
|
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
|
/* Update the pointer to the first next free FLASH memory -- reserving this
|
||||||
* block of memory.
|
* block of memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
volume->froffset = offset + size;
|
volume->froffset = nxffs_iotell(volume) + size;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,8 +760,8 @@ int nxffs_wrverify(FAR struct nxffs_volume_s *volume, size_t size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
volume->iooffset = size;
|
volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR;
|
||||||
volume->froffset = volume->ioblock * volume->geo.blocksize + size;
|
volume->froffset = volume->ioblock * volume->geo.blocksize + SIZEOF_NXFFS_BLOCK_HDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return -ENOSPC if there is no erased memory left in the volume for
|
/* 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
|
/* After the block has been successfully written to flash, update the inode
|
||||||
* statistics and reset the write state.
|
* 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;
|
wrfile->ofile.entry.datlen += wrfile->datlen;
|
||||||
if (wrfile->ofile.entry.doffset)
|
if (wrfile->ofile.entry.doffset == 0)
|
||||||
{
|
{
|
||||||
wrfile->ofile.entry.doffset = wrfile->doffset;
|
wrfile->ofile.entry.doffset = wrfile->doffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user