9
0
Fork 0

All open file must be adjusted when the filesystem is packed

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3567 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-05-05 21:45:08 +00:00
parent 9163401634
commit 75bbfc1095
3 changed files with 229 additions and 21 deletions

View File

@ -778,6 +778,26 @@ extern int nxffs_reformat(FAR struct nxffs_volume_s *volume);
extern FAR struct nxffs_ofile_s *nxffs_findofile(FAR struct nxffs_volume_s *volume,
FAR const char *name);
/****************************************************************************
* Name: nxffs_findwriter
*
* Description:
* Search the list of already opened files and return the open file
* instance for the write.
*
* Input Parameters:
* volume - Describes the NXFFS volume.
*
* Returned Value:
* If there is an active writer of the volume, its open file instance is
* returned. NULL is returned otherwise.
*
* Defined in nxffs_open.c
*
****************************************************************************/
extern FAR struct nxffs_wrfile_s *nxffs_findwriter(FAR struct nxffs_volume_s *volume);
/****************************************************************************
* Name: nxffs_wrinode
*
@ -792,7 +812,29 @@ extern FAR struct nxffs_ofile_s *nxffs_findofile(FAR struct nxffs_volume_s *volu
*
* Input parameters
* volume - Describes the NXFFS volume
* entry - Describes the indoe header to write
* entry - Describes the inode header to write
*
* Returned Value:
* Zero is returned on success; Otherwise, a negated errno value is returned
* indicating the nature of the failure.
*
* Defined in nxffs_open.c
*
****************************************************************************/
extern int nxffs_wrinode(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_entry_s *entry);
/****************************************************************************
* Name: nxffs_updateinode
*
* Description:
* The packing logic has moved an inode. Check if any open files are using
* this inode and, if so, move the data in the open file structure as well.
*
* Input parameters
* volume - Describes the NXFFS volume
* entry - Describes the new inode entry
*
* Returned Value:
* Zero is returned on success; Otherwise, a negated errno value is returned
@ -800,8 +842,8 @@ extern FAR struct nxffs_ofile_s *nxffs_findofile(FAR struct nxffs_volume_s *volu
*
****************************************************************************/
extern int nxffs_wrinode(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_entry_s *entry);
extern int nxffs_updateinode(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_entry_s *entry);
/****************************************************************************
* Name: nxffs_wrreserve

View File

@ -945,6 +945,35 @@ FAR struct nxffs_ofile_s *nxffs_findofile(FAR struct nxffs_volume_s *volume,
return NULL;
}
/****************************************************************************
* Name: nxffs_findwriter
*
* Description:
* Search the list of already opened files and return the open file
* instance for the write.
*
* Input Parameters:
* volume - Describes the NXFFS volume.
*
* Returned Value:
* If there is an active writer of the volume, its open file instance is
* returned. NULL is returned otherwise.
*
****************************************************************************/
FAR struct nxffs_wrfile_s *nxffs_findwriter(FAR struct nxffs_volume_s *volume)
{
/* We can tell if the write is in-use because it will have an allocated
* name attached.
*/
#ifdef CONFIG_NXFSS_PREALLOCATED
return g_wrfile.ofile.entry.name != NULL ? &g_wrfile : NULL;
#else
# error "Missing implementation"
#endif
}
/****************************************************************************
* Name: nxffs_open
*
@ -1106,7 +1135,7 @@ errout:
*
* Input parameters
* volume - Describes the NXFFS volume
* entry - Describes the indoe header to write
* entry - Describes the inode header to write
*
* Returned Value:
* Zero is returned on success; Otherwise, a negated errno value is returned
@ -1180,4 +1209,39 @@ errout:
return ret;
}
/****************************************************************************
* Name: nxffs_updateinode
*
* Description:
* The packing logic has moved an inode. Check if any open files are using
* this inode and, if so, move the data in the open file structure as well.
*
* Input parameters
* volume - Describes the NXFFS volume
* entry - Describes the new inode entry
*
* Returned Value:
* Zero is returned on success; Otherwise, a negated errno value is returned
* indicating the nature of the failure.
*
****************************************************************************/
int nxffs_updateinode(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_entry_s *entry)
{
FAR struct nxffs_ofile_s *ofile;
/* Find the open inode structure matching this name */
ofile = nxffs_findofile(volume, entry->name);
if (ofile)
{
/* Yes.. the file is open. Update the FLASH offsets to inode headers */
ofile->entry.hoffset = entry->hoffset;
ofile->entry.noffset = entry->noffset;
ofile->entry.doffset = entry->doffset;
}
return OK;
}

View File

@ -622,6 +622,7 @@ static int nxffs_wrinodehdr(FAR struct nxffs_volume_s *volume,
uint16_t iooffset;
uint32_t crc;
int namlen;
int ret;
/* Get seek positions corresponding to the inode header location */
@ -684,6 +685,16 @@ static int nxffs_wrinodehdr(FAR struct nxffs_volume_s *volume,
inode->state = INODE_STATE_FILE;
nxffs_wrle32(inode->crc, crc);
/* If any open files reference this inode, then update the open file
* state.
*/
ret = nxffs_updateinode(volume, &pack->dest.entry);
if (ret < 0)
{
fdbg("Failed to update inode info: %s\n", -ret);
}
/* Reset the dest inode information */
nxffs_freeentry(&pack->dest.entry);
@ -962,6 +973,37 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume,
return -ENOSYS;
}
/****************************************************************************
* Name: nxffs_packwriter
*
* Description:
* There is a write in progress at the time that the volume is packed.
* This is the normal case because it is the write failures that trigger
* the packing operation to begin with.
*
* Writing is performed at the end of the free FLASH region and this
* implemenation is restricted to a single writer. The new inode is not
* written to FLASH until the the writer is closed and so will not be
* found by nxffs_packblock().
*
* Input Parameters:
* volume - The volume to be packed
* pack - The volume packing state structure.
*
* Returned Values:
* Zero on success; Otherwise, a negated errno value is returned to
* indicate the nature of the failure.
*
****************************************************************************/
static inline int nxffs_packwriter(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_pack_s *pack,
FAR struct nxffs_wrfile_s *wrfile)
{
#warning "Missing logic"
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -985,6 +1027,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume,
int nxffs_pack(FAR struct nxffs_volume_s *volume)
{
struct nxffs_pack_s pack;
FAR struct nxffs_wrfile_s *wrfile;
off_t iooffset;
off_t eblock;
off_t block;
@ -1011,6 +1054,8 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
*/
packed = false;
wrfile = NULL;
ret = nxffs_startpos(volume, &pack, &iooffset);
if (ret < 0)
{
@ -1028,9 +1073,18 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
if (iooffset + CONFIG_NXFFS_TAILTHRESHOLD < volume->froffset)
{
/* Setting 'packed' to true will supress all packing operations */
/* Setting 'packed' to true will supress normal inode packing
* operation.
*/
packed = true;
/* Writing is performed at the end of the free FLASH region.
* If we are not packing files, we could still need to pack
* the partially written file at the end of FLASH.
*/
wrfile = nxffs_findwriter(volume);
}
/* Otherwise return OK.. meaning that there is nothing more we can
@ -1108,28 +1162,76 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
* already verified that).
*/
if (!packed && nxffs_packvalid(&pack))
if (nxffs_packvalid(&pack))
{
/* Yes.. pack data into this block */
/* Have we finished packing inodes? */
ret = nxffs_packblock(volume, &pack);
if (ret < 0)
{
/* The error -ENOSPC is a special value that simply
* means that there is nothing further to be packed.
*/
if (!packed)
{
DEBUGASSERT(wrfile == NULL);
if (ret == -ENOSPC)
/* Pack inode data into this block */
ret = nxffs_packblock(volume, &pack);
if (ret < 0)
{
packed = true;
/* The error -ENOSPC is a special value that simply
* means that there is nothing further to be packed.
*/
if (ret == -ENOSPC)
{
packed = true;
/* Writing is performed at the end of the free
* FLASH region and this implemenation is restricted
* to a single writer. The new inode is not
* written to FLASH until the the writer is closed
* and so will not be found by nxffs_packblock().
*/
wrfile = nxffs_findwriter(volume);
}
else
{
/* Otherwise, something really bad happened */
fdbg("Failed to pack into block %d: %d\n",
block, ret);
goto errout_with_pack;
}
}
else
{
/* Otherwise, something really bad happened */
}
fdbg("Failed to pack into block %d: %d\n",
block, ret);
goto errout_with_pack;
/* If all of the "normal" inodes have been packed, then check if
* we need to the current, in-progress write operation.
*/
if (wrfile)
{
DEBUGASSERT(packed == true);
/* Pack write data into this block */
ret = nxffs_packwriter(volume, &pack, wrfile);
if (ret < 0)
{
/* The error -ENOSPC is a special value that simply
* means that there is nothing further to be packed.
*/
if (ret == -ENOSPC)
{
wrfile = NULL;
}
else
{
/* Otherwise, something really bad happened */
fdbg("Failed to pack into block %d: %d\n",
block, ret);
goto errout_with_pack;
}
}
}
}