static REDSTATUS BranchBlock()

in FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c [1512:1619]


static REDSTATUS BranchBlock(
    CINODE     *pInode,
    BRANCHDEPTH depth,
    bool        fBuffer)
{
    REDSTATUS   ret;
    uint32_t    ulCost = 0U; /* Init'd to quiet warnings. */

    ret = BranchBlockCost(pInode, depth, &ulCost);

    if((ret == 0) && (ulCost > FreeBlockCount()))
    {
        ret = -RED_ENOSPC;
    }

    if(ret == 0)
    {
      #if DINDIR_POINTERS > 0U
        if(pInode->uDindirEntry != COORD_ENTRY_INVALID)
        {
            ret = BranchOneBlock(&pInode->ulDindirBlock, CAST_VOID_PTR_PTR(&pInode->pDindir), BFLAG_META_DINDIR);

            if(ret == 0)
            {
                /*  In case we just created the double indirect.
                */
                pInode->pDindir->ulInode = pInode->ulInode;

                pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulDindirBlock;
            }
        }

        if(ret == 0)
      #endif
      #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
        {
            if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (depth >= BRANCHDEPTH_INDIR))
            {
                ret = BranchOneBlock(&pInode->ulIndirBlock, CAST_VOID_PTR_PTR(&pInode->pIndir), BFLAG_META_INDIR);

                if(ret == 0)
                {
                    /*  In case we just created the indirect.
                    */
                    pInode->pIndir->ulInode = pInode->ulInode;

                  #if DINDIR_POINTERS > 0U
                    if(pInode->uDindirEntry != COORD_ENTRY_INVALID)
                    {
                        pInode->pDindir->aulEntries[pInode->uDindirEntry] = pInode->ulIndirBlock;
                    }
                    else
                  #endif
                    {
                        pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulIndirBlock;
                    }
                }
            }
        }

        if(ret == 0)
      #endif
        {
            if(depth == BRANCHDEPTH_FILE_DATA)
            {
              #if REDCONF_INODE_BLOCKS == 1
                bool    fAllocedNew = (pInode->ulDataBlock == BLOCK_SPARSE);
              #endif
                void  **ppBufPtr = (fBuffer || (pInode->pbData != NULL)) ? CAST_VOID_PTR_PTR(&pInode->pbData) : NULL;

                ret = BranchOneBlock(&pInode->ulDataBlock, ppBufPtr, 0U);

                if(ret == 0)
                {
                  #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
                    if(pInode->uIndirEntry != COORD_ENTRY_INVALID)
                    {
                        pInode->pIndir->aulEntries[pInode->uIndirEntry] = pInode->ulDataBlock;
                    }
                    else
                  #endif
                    {
                        pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulDataBlock;
                    }

                  #if REDCONF_INODE_BLOCKS == 1
                    if(fAllocedNew)
                    {
                        if(pInode->pInodeBuf->ulBlocks < INODE_DATA_BLOCKS)
                        {
                            pInode->pInodeBuf->ulBlocks++;
                        }
                        else
                        {
                            CRITICAL_ERROR();
                            ret = -RED_EFUBAR;
                        }
                    }
                  #endif
                }
            }
        }

        CRITICAL_ASSERT(ret == 0);
    }

    return ret;
}