All open file must be adjusted when the filesystem is packed
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3567 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
77d4700a62
commit
71bd9ca54e
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user