in FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c [1772:1886]
static REDSTATUS BranchBlockCost(
const CINODE *pInode,
BRANCHDEPTH depth,
uint32_t *pulCost)
{
REDSTATUS ret = 0;
if(!CINODE_IS_MOUNTED(pInode) || !pInode->fCoordInited || (depth > BRANCHDEPTH_MAX) || (pulCost == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
ALLOCSTATE state;
/* ulCost is initialized to the maximum number of blocks that could
be branched, and decremented for every block we determine does not
need to be branched.
*/
#if DINDIR_POINTERS > 0U
uint32_t ulCost = 3U;
#elif REDCONF_DIRECT_POINTERS < INODE_ENTRIES
uint32_t ulCost = 2U;
#else
uint32_t ulCost = 1U;
#endif
#if DINDIR_POINTERS > 0U
if(pInode->uDindirEntry != COORD_ENTRY_INVALID)
{
if(pInode->ulDindirBlock != BLOCK_SPARSE)
{
ret = RedImapBlockState(pInode->ulDindirBlock, &state);
if((ret == 0) && (state == ALLOCSTATE_NEW))
{
/* Double indirect already branched.
*/
ulCost--;
}
}
}
else
{
/* At this inode offset there are no double indirects.
*/
ulCost--;
}
if(ret == 0)
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
{
if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (depth >= BRANCHDEPTH_INDIR))
{
if(pInode->ulIndirBlock != BLOCK_SPARSE)
{
ret = RedImapBlockState(pInode->ulIndirBlock, &state);
if((ret == 0) && (state == ALLOCSTATE_NEW))
{
/* Indirect already branched.
*/
ulCost--;
}
}
}
else
{
/* Either not branching this deep, or at this inode offset
there are no indirects.
*/
ulCost--;
}
}
if(ret == 0)
#endif
{
if(depth == BRANCHDEPTH_FILE_DATA)
{
if(pInode->ulDataBlock != BLOCK_SPARSE)
{
ret = RedImapBlockState(pInode->ulDataBlock, &state);
if((ret == 0) && (state == ALLOCSTATE_NEW))
{
/* File data block already branched.
*/
ulCost--;
/* If the file data block is branched, then its parent
nodes should be branched as well.
*/
REDASSERT(ulCost == 0U);
}
}
}
else
{
/* Not branching this deep.
*/
ulCost--;
}
}
if(ret == 0)
{
*pulCost = ulCost;
}
}
return ret;
}