static REDSTATUS WriteAligned()

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


static REDSTATUS WriteAligned(
    CINODE         *pInode,
    uint32_t        ulBlockStart,
    uint32_t       *pulBlockCount,
    const uint8_t  *pbBuffer)
{
    REDSTATUS       ret = 0;

    if((pulBlockCount == NULL) || (pbBuffer == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        bool     fFull = false;
        uint32_t ulBlockCount = *pulBlockCount;
        uint32_t ulBlockIndex;

        /*  Branch all of the file data blocks in advance.
        */
        for(ulBlockIndex = 0U; (ulBlockIndex < ulBlockCount) && !fFull; ulBlockIndex++)
        {
            ret = RedInodeDataSeek(pInode, ulBlockStart + ulBlockIndex);

            if((ret == 0) || (ret == -RED_ENODATA))
            {
                ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, false);

                if(ret == -RED_ENOSPC)
                {
                    if(ulBlockIndex > 0U)
                    {
                        ret = 0;
                    }

                    fFull = true;
                }
            }

            if(ret != 0)
            {
                break;
            }
        }

        ulBlockCount = ulBlockIndex;
        ulBlockIndex = 0U;

        if(fFull)
        {
            ulBlockCount--;
        }

        /*  Write the data to disk one contiguous extent at a time.
        */
        while((ret == 0) && (ulBlockIndex < ulBlockCount))
        {
            uint32_t ulExtentStart;
            uint32_t ulExtentLen = ulBlockCount - ulBlockIndex;

            ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen);

            if(ret == 0)
            {
                ret = RedIoWrite(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]);

                if(ret == 0)
                {
                    /*  If there is any buffered file data for the extent we
                        just wrote, those buffers are now stale.
                    */
                    ret = RedBufferDiscardRange(ulExtentStart, ulExtentLen);
                }

                if(ret == 0)
                {
                    ulBlockIndex += ulExtentLen;
                }
            }
        }

        if(ret == 0)
        {
            *pulBlockCount = ulBlockCount;
        }
    }

    return ret;
}