in FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c [1649:1751]
static REDSTATUS BranchOneBlock(
uint32_t *pulBlock,
void **ppBuffer,
uint16_t uBFlag)
{
REDSTATUS ret = 0;
if(pulBlock == NULL)
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
ALLOCSTATE state = ALLOCSTATE_FREE;
uint32_t ulPrevBlock = *pulBlock;
if(ulPrevBlock != BLOCK_SPARSE)
{
ret = RedImapBlockState(ulPrevBlock, &state);
}
if(ret == 0)
{
if(state == ALLOCSTATE_NEW)
{
/* Block is already branched, so simply get it buffered dirty
if requested.
*/
if(ppBuffer != NULL)
{
if(*ppBuffer != NULL)
{
RedBufferDirty(*ppBuffer);
}
else
{
ret = RedBufferGet(ulPrevBlock, uBFlag | BFLAG_DIRTY, ppBuffer);
}
}
}
else
{
/* Block does not exist or is committed state, so allocate a
new block for the branch.
*/
ret = RedImapAllocBlock(pulBlock);
if(ret == 0)
{
if(ulPrevBlock == BLOCK_SPARSE)
{
/* Block did not exist previously, so just get it
buffered if requested.
*/
if(ppBuffer != NULL)
{
if(*ppBuffer != NULL)
{
/* How could there be an existing buffer when
the block did not exist?
*/
REDERROR();
ret = -RED_EINVAL;
}
else
{
ret = RedBufferGet(*pulBlock, (uint16_t)((uint32_t)uBFlag | BFLAG_NEW | BFLAG_DIRTY), ppBuffer);
}
}
}
else
{
/* Branch the buffer for the committed state block to
the newly allocated location.
*/
if(ppBuffer != NULL)
{
if(*ppBuffer == NULL)
{
ret = RedBufferGet(ulPrevBlock, uBFlag, ppBuffer);
}
if(ret == 0)
{
RedBufferBranch(*ppBuffer, *pulBlock);
}
}
/* Mark the committed state block almost free.
*/
if(ret == 0)
{
ret = RedImapBlockSet(ulPrevBlock, false);
}
}
}
}
}
}
return ret;
}