static REDSTATUS BranchBlockCost()

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;
}