/*             ----> DO NOT REMOVE THE FOLLOWING NOTICE <----

                   Copyright (c) 2014-2015 Datalight, Inc.
                       All Rights Reserved Worldwide.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; use version 2 of the License.

    This program is distributed in the hope that it will be useful,
    but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*  Businesses and individuals that for commercial or other reasons cannot
    comply with the terms of the GPLv2 license may obtain a commercial license
    before incorporating Reliance Edge into proprietary software for
    distribution in any form.  Visit http://www.datalight.com/reliance-edge for
    more information.
*/
/** @file
    @brief Implements the block device buffering system.

    This module implements the block buffer cache.  It has a number of block
    sized buffers which are used to store data from a given block (identified
    by both block number and volume number: this cache is shared among all
    volumes).  Block buffers may be either dirty or clean.  Most I/O passes
    through this module.  When a buffer is needed for a block which is not in
    the cache, a "victim" is selected via a simple LRU scheme.
*/
#include <redfs.h>
#include <redcore.h>


#if DINDIR_POINTERS > 0U
  #define INODE_META_BUFFERS 3U /* Inode, double indirect, indirect */
#elif REDCONF_INDIRECT_POINTERS > 0U
  #define INODE_META_BUFFERS 2U /* Inode, indirect */
#elif REDCONF_DIRECT_POINTERS == INODE_ENTRIES
  #define INODE_META_BUFFERS 1U /* Inode only */
#endif

#define INODE_BUFFERS (INODE_META_BUFFERS + 1U) /* Add data buffer */

#if REDCONF_IMAP_EXTERNAL == 1
  #define IMAP_BUFFERS 1U
#else
  #define IMAP_BUFFERS 0U
#endif

#if (REDCONF_READ_ONLY == 1) || (REDCONF_API_FSE == 1)
  /*  Read, write, truncate, lookup: One inode all the way down, plus imap.
  */
  #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + IMAP_BUFFERS)
#elif REDCONF_API_POSIX == 1
  #if REDCONF_API_POSIX_RENAME == 1
    #if REDCONF_RENAME_ATOMIC == 1
      /*  Two parent directories all the way down.  Source and destination inode
          buffer.  One inode buffer for cyclic rename detection.  Imap.  The
          parent inode buffers are released before deleting the destination
          inode, so that does not increase the minimum.
      */
      #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 3U + IMAP_BUFFERS)
    #else
      /*  Two parent directories all the way down.  Source inode buffer.  One
          inode buffer for cyclic rename detection.  Imap.
      */
      #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 2U + IMAP_BUFFERS)
    #endif
  #else
    /*  Link/create: Needs a parent inode all the way down, an extra inode
        buffer, and an imap buffer.

        Unlink is the same, since the parent inode buffers are released before
        the inode is deleted.
    */
    #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + 1U + IMAP_BUFFERS)
  #endif
#endif

#if REDCONF_BUFFER_COUNT < MINIMUM_BUFFER_COUNT
#error "REDCONF_BUFFER_COUNT is too low for the configuration"
#endif


/*  A note on the typecasts in the below macros: Operands to bitwise operators
    are subject to the "usual arithmetic conversions".  This means that the
    flags, which have uint16_t values, are promoted to int.  MISRA-C:2012 R10.1
    forbids using signed integers in bitwise operations, so we cast to uint32_t
    to avoid the integer promotion, then back to uint16_t to reflect the actual
    type.
*/
#define BFLAG_META_MASK (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_META_IMAP | BFLAG_META_INODE | BFLAG_META_INDIR | BFLAG_META_DINDIR)
#define BFLAG_MASK (uint16_t)((uint32_t)BFLAG_DIRTY | BFLAG_NEW | BFLAG_META_MASK)


/*  An invalid block number.  Used to indicate buffers which are not currently
    in use.
*/
#define BBLK_INVALID UINT32_MAX


/** @brief Metadata stored for each block buffer.

    To make better use of CPU caching when searching the BUFFERHEAD array, this
    structure should be kept small.
*/
typedef struct
{
    uint32_t    ulBlock;    /**< Block number the buffer is associated with; BBLK_INVALID if unused. */
    uint8_t     bVolNum;    /**< Volume the block resides on. */
    uint8_t     bRefCount;  /**< Number of references. */
    uint16_t    uFlags;     /**< Buffer flags: mask of BFLAG_* values. */
} BUFFERHEAD;


/** @brief State information for the block buffer module.
*/
typedef struct
{
    /** Number of buffers which are referenced (have a bRefCount > 0).
    */
    uint16_t    uNumUsed;

    /** MRU array.  Each element of the array stores a buffer index; each buffer
        index appears in the array once and only once.  The first element of the
        array is the most-recently-used (MRU) buffer, followed by the next most
        recently used, and so on, till the last element, which is the least-
        recently-used (LRU) buffer.
    */
    uint8_t     abMRU[REDCONF_BUFFER_COUNT];

    /** Buffer heads, storing metadata for each buffer.
    */
    BUFFERHEAD  aHead[REDCONF_BUFFER_COUNT];

    /** Array of memory for the block buffers themselves.

        Force 64-bit alignment of the aabBuffer array to ensure that it is safe
        to cast buffer pointers to node structure pointers.
    */
    ALIGNED_2D_BYTE_ARRAY(b, aabBuffer, REDCONF_BUFFER_COUNT, REDCONF_BLOCK_SIZE);
} BUFFERCTX;


static bool BufferIsValid(const uint8_t  *pbBuffer, uint16_t uFlags);
static bool BufferToIdx(const void *pBuffer, uint8_t *pbIdx);
#if REDCONF_READ_ONLY == 0
static REDSTATUS BufferWrite(uint8_t bIdx);
static REDSTATUS BufferFinalize(uint8_t *pbBuffer, uint16_t uFlags);
#endif
static void BufferMakeLRU(uint8_t bIdx);
static void BufferMakeMRU(uint8_t bIdx);
static bool BufferFind(uint32_t ulBlock, uint8_t *pbIdx);

#ifdef REDCONF_ENDIAN_SWAP
static void BufferEndianSwap(const void *pBuffer, uint16_t uFlags);
static void BufferEndianSwapHeader(NODEHEADER *pHeader);
static void BufferEndianSwapMaster(MASTERBLOCK *pMaster);
static void BufferEndianSwapMetaRoot(METAROOT *pMetaRoot);
static void BufferEndianSwapInode(INODE *pInode);
static void BufferEndianSwapIndir(INDIR *pIndir);
#endif


static BUFFERCTX gBufCtx;


/** @brief Initialize the buffers.
*/
void RedBufferInit(void)
{
    uint8_t bIdx;

    RedMemSet(&gBufCtx, 0U, sizeof(gBufCtx));

    for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)
    {
        /*  When the buffers have been freshly initialized, acquire the buffers
            in the order in which they appear in the array.
        */
        gBufCtx.abMRU[bIdx] = (uint8_t)((REDCONF_BUFFER_COUNT - bIdx) - 1U);
        gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID;
    }
}


/** @brief Acquire a buffer.

    @param ulBlock  Block number to acquire.
    @param uFlags   BFLAG_ values for the operation.
    @param ppBuffer On success, populated with the acquired buffer.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
    @retval -RED_EINVAL Invalid parameters.
    @retval -RED_EBUSY  All buffers are referenced.
*/
REDSTATUS RedBufferGet(
    uint32_t    ulBlock,
    uint16_t    uFlags,
    void      **ppBuffer)
{
    REDSTATUS   ret = 0;
    uint8_t     bIdx;

    if((ulBlock >= gpRedVolume->ulBlockCount) || ((uFlags & BFLAG_MASK) != uFlags) || (ppBuffer == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        if(BufferFind(ulBlock, &bIdx))
        {
            /*  Error if the buffer exists and BFLAG_NEW was specified, since
                the new flag is used when a block is newly allocated/created, so
                the block was previously free and and there should never be an
                existing buffer for a free block.

                Error if the buffer exists but does not have the same type as
                was requested.
            */
            if(    ((uFlags & BFLAG_NEW) != 0U)
                || ((uFlags & BFLAG_META_MASK) != (gBufCtx.aHead[bIdx].uFlags & BFLAG_META_MASK)))
            {
                CRITICAL_ERROR();
                ret = -RED_EFUBAR;
            }
        }
        else if(gBufCtx.uNumUsed == REDCONF_BUFFER_COUNT)
        {
            /*  The MINIMUM_BUFFER_COUNT is supposed to ensure that no operation
                ever runs out of buffers, so this should never happen.
            */
            CRITICAL_ERROR();
            ret = -RED_EBUSY;
        }
        else
        {
            BUFFERHEAD *pHead;

            /*  Search for the least recently used buffer which is not
                referenced.
            */
            for(bIdx = (uint8_t)(REDCONF_BUFFER_COUNT - 1U); bIdx > 0U; bIdx--)
            {
                if(gBufCtx.aHead[gBufCtx.abMRU[bIdx]].bRefCount == 0U)
                {
                    break;
                }
            }

            bIdx = gBufCtx.abMRU[bIdx];
            pHead = &gBufCtx.aHead[bIdx];

            if(pHead->bRefCount == 0U)
            {
                /*  If the LRU buffer is valid and dirty, write it out before
                    repurposing it.
                */
                if(((pHead->uFlags & BFLAG_DIRTY) != 0U) && (pHead->ulBlock != BBLK_INVALID))
                {
                  #if REDCONF_READ_ONLY == 1
                    CRITICAL_ERROR();
                    ret = -RED_EFUBAR;
                  #else
                    ret = BufferWrite(bIdx);
                  #endif
                }
            }
            else
            {
                /*  All the buffers are used, which should have been caught by
                    checking gBufCtx.uNumUsed.
                */
                CRITICAL_ERROR();
                ret = -RED_EBUSY;
            }

            if(ret == 0)
            {
                if((uFlags & BFLAG_NEW) == 0U)
                {
                    /*  Invalidate the LRU buffer.  If the read fails, we do not
                        want the buffer head to continue to refer to the old
                        block number, since the read, even if it fails, may have
                        partially overwritten the buffer data (consider the case
                        where block size exceeds sector size, and some but not
                        all of the sectors are read successfully), and if the
                        buffer were to be used subsequently with its partially
                        erroneous contents, bad things could happen.
                    */
                    pHead->ulBlock = BBLK_INVALID;

                    ret = RedIoRead(gbRedVolNum, ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]);

                    if((ret == 0) && ((uFlags & BFLAG_META) != 0U))
                    {
                        if(!BufferIsValid(gBufCtx.b.aabBuffer[bIdx], uFlags))
                        {
                            /*  A corrupt metadata node is usually a critical
                                error.  The master block is an exception since
                                it might be invalid because the volume is not
                                mounted; that condition is expected and should
                                not result in an assertion.
                            */
                            CRITICAL_ASSERT((uFlags & BFLAG_META_MASTER) != 0U);
                            ret = -RED_EIO;
                        }
                    }

                  #ifdef REDCONF_ENDIAN_SWAP
                    if(ret == 0)
                    {
                        BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], uFlags);
                    }
                  #endif
                }
                else
                {
                    RedMemSet(gBufCtx.b.aabBuffer[bIdx], 0U, REDCONF_BLOCK_SIZE);
                }
            }

            if(ret == 0)
            {
                pHead->bVolNum = gbRedVolNum;
                pHead->ulBlock = ulBlock;
                pHead->uFlags = 0U;
            }
        }

        /*  Reference the buffer, update its flags, and promote it to MRU.  This
            happens both when BufferFind() found an existing buffer for the
            block and when the LRU buffer was repurposed to create a buffer for
            the block.
        */
        if(ret == 0)
        {
            BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

            pHead->bRefCount++;

            if(pHead->bRefCount == 1U)
            {
                gBufCtx.uNumUsed++;
            }

            /*  BFLAG_NEW tells this function to zero the buffer instead of
                reading it from disk; it has no meaning later on, and thus is
                not saved.
            */
            pHead->uFlags |= (uFlags & (~BFLAG_NEW));

            BufferMakeMRU(bIdx);

            *ppBuffer = gBufCtx.b.aabBuffer[bIdx];
        }
    }

    return ret;
}


/** @brief Release a buffer.

    @param pBuffer  The buffer to release.
 */
void RedBufferPut(
    const void *pBuffer)
{
    uint8_t     bIdx;

    if(!BufferToIdx(pBuffer, &bIdx))
    {
        REDERROR();
    }
    else
    {
        REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U);
        gBufCtx.aHead[bIdx].bRefCount--;

        if(gBufCtx.aHead[bIdx].bRefCount == 0U)
        {
            REDASSERT(gBufCtx.uNumUsed > 0U);
            gBufCtx.uNumUsed--;
        }
    }
}


#if REDCONF_READ_ONLY == 0
/** @brief Flush all buffers for the active volume in the given range of blocks.

    @param ulBlockStart Starting block number to flush.
    @param ulBlockCount Count of blocks, starting at @p ulBlockStart, to flush.
                        Must not be zero.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
    @retval -RED_EINVAL Invalid parameters.
*/
REDSTATUS RedBufferFlush(
    uint32_t    ulBlockStart,
    uint32_t    ulBlockCount)
{
    REDSTATUS   ret = 0;

    if(    (ulBlockStart >= gpRedVolume->ulBlockCount)
        || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount)
        || (ulBlockCount == 0U))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t bIdx;

        for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)
        {
            BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

            if(    (pHead->bVolNum == gbRedVolNum)
                && (pHead->ulBlock != BBLK_INVALID)
                && ((pHead->uFlags & BFLAG_DIRTY) != 0U)
                && (pHead->ulBlock >= ulBlockStart)
                && (pHead->ulBlock < (ulBlockStart + ulBlockCount)))
            {
                ret = BufferWrite(bIdx);

                if(ret == 0)
                {
                    pHead->uFlags &= (~BFLAG_DIRTY);
                }
                else
                {
                    break;
                }
            }
        }
    }

    return ret;
}


/** @brief Mark a buffer dirty

    @param pBuffer  The buffer to mark dirty.
*/
void RedBufferDirty(
    const void *pBuffer)
{
    uint8_t     bIdx;

    if(!BufferToIdx(pBuffer, &bIdx))
    {
        REDERROR();
    }
    else
    {
        REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U);

        gBufCtx.aHead[bIdx].uFlags |= BFLAG_DIRTY;
    }
}


/** @brief Branch a buffer, marking it dirty and assigning a new block number.

    @param pBuffer      The buffer to branch.
    @param ulBlockNew   The new block number for the buffer.
*/
void RedBufferBranch(
    const void *pBuffer,
    uint32_t    ulBlockNew)
{
    uint8_t     bIdx;

    if(    !BufferToIdx(pBuffer, &bIdx)
        || (ulBlockNew >= gpRedVolume->ulBlockCount))
    {
        REDERROR();
    }
    else
    {
        BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

        REDASSERT(pHead->bRefCount > 0U);
        REDASSERT((pHead->uFlags & BFLAG_DIRTY) == 0U);

        pHead->uFlags |= BFLAG_DIRTY;
        pHead->ulBlock = ulBlockNew;
    }
}


#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED
/** @brief Discard a buffer, releasing it and marking it invalid.

    @param pBuffer  The buffer to discard.
*/
void RedBufferDiscard(
    const void *pBuffer)
{
    uint8_t     bIdx;

    if(!BufferToIdx(pBuffer, &bIdx))
    {
        REDERROR();
    }
    else
    {
        REDASSERT(gBufCtx.aHead[bIdx].bRefCount == 1U);
        REDASSERT(gBufCtx.uNumUsed > 0U);

        gBufCtx.aHead[bIdx].bRefCount = 0U;
        gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID;

        gBufCtx.uNumUsed--;

        BufferMakeLRU(bIdx);
    }
}
#endif
#endif /* REDCONF_READ_ONLY == 0 */


/** @brief Discard a range of buffers, marking them invalid.

    @param ulBlockStart The starting block number to discard
    @param ulBlockCount The number of blocks, starting at @p ulBlockStart, to
                        discard.  Must not be zero.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL Invalid parameters.
    @retval -RED_EBUSY  A block in the desired range is referenced.
*/
REDSTATUS RedBufferDiscardRange(
    uint32_t    ulBlockStart,
    uint32_t    ulBlockCount)
{
    REDSTATUS   ret = 0;

    if(    (ulBlockStart >= gpRedVolume->ulBlockCount)
        || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount)
        || (ulBlockCount == 0U))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t bIdx;

        for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)
        {
            BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

            if(    (pHead->bVolNum == gbRedVolNum)
                && (pHead->ulBlock != BBLK_INVALID)
                && (pHead->ulBlock >= ulBlockStart)
                && (pHead->ulBlock < (ulBlockStart + ulBlockCount)))
            {
                if(pHead->bRefCount == 0U)
                {
                    pHead->ulBlock = BBLK_INVALID;

                    BufferMakeLRU(bIdx);
                }
                else
                {
                    /*  This should never happen.  There are three general cases
                        when this function is used:

                        1) Discarding every block, as happens during unmount
                           and at the end of format.  There should no longer be
                           any referenced buffers at those points.
                        2) Discarding a block which has become free.  All
                           buffers for such blocks should be put or branched
                           beforehand.
                        3) Discarding of blocks that were just written straight
                           to disk, leaving stale data in the buffer.  The write
                           code should never reference buffers for these blocks,
                           since they would not be needed or used.
                    */
                    CRITICAL_ERROR();
                    ret = -RED_EBUSY;
                    break;
                }
            }
        }
    }

    return ret;
}


/** Determine whether a metadata buffer is valid.

    This includes checking its signature, CRC, and sequence number.

    @param pbBuffer Pointer to the metadata buffer to validate.
    @param uFlags   The buffer flags provided by the caller.  Used to determine
                    the expected signature.

    @return Whether the metadata buffer is valid.

    @retval true    The metadata buffer is valid.
    @retval false   The metadata buffer is invalid.
*/
static bool BufferIsValid(
    const uint8_t  *pbBuffer,
    uint16_t        uFlags)
{
    bool            fValid;

    if((pbBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags))
    {
        REDERROR();
        fValid = false;
    }
    else
    {
        NODEHEADER  buf;
        uint16_t    uMetaFlags = uFlags & BFLAG_META_MASK;

        /*  Casting pbBuffer to (NODEHEADER *) would run afoul MISRA-C:2012
            R11.3, so instead copy the fields out.
        */
        RedMemCpy(&buf.ulSignature, &pbBuffer[NODEHEADER_OFFSET_SIG], sizeof(buf.ulSignature));
        RedMemCpy(&buf.ulCRC,       &pbBuffer[NODEHEADER_OFFSET_CRC], sizeof(buf.ulCRC));
        RedMemCpy(&buf.ullSequence, &pbBuffer[NODEHEADER_OFFSET_SEQ], sizeof(buf.ullSequence));

      #ifdef REDCONF_ENDIAN_SWAP
        buf.ulCRC = RedRev32(buf.ulCRC);
        buf.ulSignature = RedRev32(buf.ulSignature);
        buf.ullSequence = RedRev64(buf.ullSequence);
      #endif

        /*  Make sure the signature is correct for the type of metadata block
            requested by the caller.
        */
        switch(buf.ulSignature)
        {
            case META_SIG_MASTER:
                fValid = (uMetaFlags == BFLAG_META_MASTER);
                break;
          #if REDCONF_IMAP_EXTERNAL == 1
            case META_SIG_IMAP:
                fValid = (uMetaFlags == BFLAG_META_IMAP);
                break;
          #endif
            case META_SIG_INODE:
                fValid = (uMetaFlags == BFLAG_META_INODE);
                break;
          #if DINDIR_POINTERS > 0U
            case META_SIG_DINDIR:
                fValid = (uMetaFlags == BFLAG_META_DINDIR);
                break;
          #endif
          #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
            case META_SIG_INDIR:
                fValid = (uMetaFlags == BFLAG_META_INDIR);
                break;
          #endif
            default:
                fValid = false;
                break;
        }

        if(fValid)
        {
            uint32_t ulComputedCrc;

            /*  Check for disk corruption by comparing the stored CRC with one
                computed from the data.

                Also check the sequence number: if it is greater than the
                current sequence number, the block is from a previous format
                or the disk is writing blocks out of order.  During mount,
                before the metaroots have been read, the sequence number will
                be unknown, and the check is skipped.
            */
            ulComputedCrc = RedCrcNode(pbBuffer);
            if(buf.ulCRC != ulComputedCrc)
            {
                fValid = false;
            }
            else if(gpRedVolume->fMounted && (buf.ullSequence >= gpRedVolume->ullSequence))
            {
                fValid = false;
            }
            else
            {
                /*  Buffer is valid.  No action, fValid is already true.
                */
            }
        }
    }

    return fValid;
}


/** @brief Derive the index of the buffer.

    @param pBuffer  The buffer to derive the index of.
    @param pbIdx    On success, populated with the index of the buffer.

    @return Boolean indicating result.

    @retval true    Success.
    @retval false   Failure.  @p pBuffer is not a valid buffer pointer.
*/
static bool BufferToIdx(
    const void *pBuffer,
    uint8_t    *pbIdx)
{
    bool        fRet = false;

    if((pBuffer != NULL) && (pbIdx != NULL))
    {
        uint8_t bIdx;

        /*  pBuffer should be a pointer to one of the block buffers.

            A good compiler should optimize this loop into a bounds check and an
            alignment check, although GCC has been observed to not do so; if the
            number of buffers is small, it should not make much difference.  The
            alternative is to use pointer comparisons, but this both deviates
            from MISRA-C:2012 and involves undefined behavior.
        */
        for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)
        {
            if(pBuffer == &gBufCtx.b.aabBuffer[bIdx][0U])
            {
                break;
            }
        }

        if(    (bIdx < REDCONF_BUFFER_COUNT)
            && (gBufCtx.aHead[bIdx].ulBlock != BBLK_INVALID)
            && (gBufCtx.aHead[bIdx].bVolNum == gbRedVolNum))
        {
            *pbIdx = bIdx;
            fRet = true;
        }
    }

    return fRet;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write out a dirty buffer.

    @param bIdx The index of the buffer to write.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
    @retval -RED_EINVAL Invalid parameters.
*/
static REDSTATUS BufferWrite(
    uint8_t     bIdx)
{
    REDSTATUS   ret = 0;

    if(bIdx < REDCONF_BUFFER_COUNT)
    {
        const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

        REDASSERT((pHead->uFlags & BFLAG_DIRTY) != 0U);

        if((pHead->uFlags & BFLAG_META) != 0U)
        {
            ret = BufferFinalize(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags);
        }

        if(ret == 0)
        {
            ret = RedIoWrite(pHead->bVolNum, pHead->ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]);

          #ifdef REDCONF_ENDIAN_SWAP
            BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags);
          #endif
        }
    }
    else
    {
        REDERROR();
        ret = -RED_EINVAL;
    }

    return ret;
}


/** @brief Finalize a metadata buffer.

    This updates the CRC and the sequence number.  It also sets the signature,
    though this is only truly needed if the buffer is new.

    @param pbBuffer Pointer to the metadata buffer to finalize.
    @param uFlags   The associated buffer flags.  Used to determine the expected
                    signature.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL Invalid parameter; or maximum sequence number reached.
*/
static REDSTATUS BufferFinalize(
    uint8_t    *pbBuffer,
    uint16_t    uFlags)
{
    REDSTATUS   ret = 0;

    if((pbBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint32_t ulSignature;

        switch(uFlags & BFLAG_META_MASK)
        {
            case BFLAG_META_MASTER:
                ulSignature = META_SIG_MASTER;
                break;
          #if REDCONF_IMAP_EXTERNAL == 1
            case BFLAG_META_IMAP:
                ulSignature = META_SIG_IMAP;
                break;
          #endif
            case BFLAG_META_INODE:
                ulSignature = META_SIG_INODE;
                break;
          #if DINDIR_POINTERS > 0U
            case BFLAG_META_DINDIR:
                ulSignature = META_SIG_DINDIR;
                break;
          #endif
          #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
            case BFLAG_META_INDIR:
                ulSignature = META_SIG_INDIR;
                break;
          #endif
            default:
                ulSignature = 0U;
                break;
        }

        if(ulSignature == 0U)
        {
            REDERROR();
            ret = -RED_EINVAL;
        }
        else
        {
            uint64_t ullSeqNum = gpRedVolume->ullSequence;

            ret = RedVolSeqNumIncrement();
            if(ret == 0)
            {
                uint32_t ulCrc;

                RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SIG], &ulSignature, sizeof(ulSignature));
                RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SEQ], &ullSeqNum, sizeof(ullSeqNum));

              #ifdef REDCONF_ENDIAN_SWAP
                BufferEndianSwap(pbBuffer, uFlags);
              #endif

                ulCrc = RedCrcNode(pbBuffer);
              #ifdef REDCONF_ENDIAN_SWAP
                ulCrc = RedRev32(ulCrc);
              #endif
                RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_CRC], &ulCrc, sizeof(ulCrc));
            }
        }
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */


#ifdef REDCONF_ENDIAN_SWAP
/** @brief Swap the byte order of a metadata buffer

    Does nothing if the buffer is not a metadata node.  Also does nothing for
    meta roots, which don't go through the buffers anyways.

    @param pBuffer  Pointer to the metadata buffer to swap
    @param uFlags   The associated buffer flags.  Used to determin the type of
                    metadata node.
*/
static void BufferEndianSwap(
    void       *pBuffer,
    uint16_t    uFlags)
{
    if((pBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags))
    {
        REDERROR();
    }
    else if((uFlags & BFLAG_META_MASK) != 0)
    {
        BufferEndianSwapHeader(pBuffer);

        switch(uFlags & BFLAG_META_MASK)
        {
            case BFLAG_META_MASTER:
                BufferEndianSwapMaster(pBuffer);
                break;
            case BFLAG_META_INODE:
                BufferEndianSwapInode(pBuffer);
                break;
          #if DINDIR_POINTERS > 0U
            case BFLAG_META_DINDIR:
                BufferEndianSwapIndir(pBuffer);
                break;
          #endif
          #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
            case BFLAG_META_INDIR:
                BufferEndianSwapIndir(pBuffer);
                break;
          #endif
            default:
                break;
        }
    }
    else
    {
        /*  File data buffers do not need to be swapped.
        */
    }
}


/** @brief Swap the byte order of a metadata node header

    @param pHeader  Pointer to the metadata node header to swap
*/
static void BufferEndianSwapHeader(
    NODEHEADER *pHeader)
{
    if(pHeader == NULL)
    {
        REDERROR();
    }
    else
    {
        pHeader->ulSignature = RedRev32(pHeader->ulSignature);
        pHeader->ulCRC = RedRev32(pHeader->ulCRC);
        pHeader->ullSequence = RedRev64(pHeader->ullSequence);
    }
}


/** @brief Swap the byte order of a master block

    @param pMaster  Pointer to the master block to swap
*/
static void BufferEndianSwapMaster(
    MASTERBLOCK *pMaster)
{
    if(pMaster == NULL)
    {
        REDERROR();
    }
    else
    {
        pMaster->ulVersion = RedRev32(pMaster->ulVersion);
        pMaster->ulFormatTime = RedRev32(pMaster->ulFormatTime);
        pMaster->ulInodeCount = RedRev32(pMaster->ulInodeCount);
        pMaster->ulBlockCount = RedRev32(pMaster->ulBlockCount);
        pMaster->uMaxNameLen = RedRev16(pMaster->uMaxNameLen);
        pMaster->uDirectPointers = RedRev16(pMaster->uDirectPointers);
        pMaster->uIndirectPointers = RedRev16(pMaster->uIndirectPointers);
    }
}


/** @brief Swap the byte order of an inode

    @param pInode   Pointer to the inode to swap
*/
static void BufferEndianSwapInode(
    INODE  *pInode)
{
    if(pInode == NULL)
    {
        REDERROR();
    }
    else
    {
        uint32_t ulIdx;

        pInode->ullSize = RedRev64(pInode->ullSize);

      #if REDCONF_INODE_BLOCKS == 1
        pInode->ulBlocks = RedRev32(pInode->ulBlocks);
      #endif

      #if REDCONF_INODE_TIMESTAMPS == 1
        pInode->ulATime = RedRev32(pInode->ulATime);
        pInode->ulMTime = RedRev32(pInode->ulMTime);
        pInode->ulCTime = RedRev32(pInode->ulCTime);
      #endif

        pInode->uMode = RedRev16(pInode->uMode);

      #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
        pInode->uNLink = RedRev16(pInode->uNLink);
      #endif

      #if REDCONF_API_POSIX == 1
        pInode->ulPInode = RedRev32(pInode->ulPInode);
      #endif

        for(ulIdx = 0; ulIdx < INODE_ENTRIES; ulIdx++)
        {
            pInode->aulEntries[ulIdx] = RedRev32(pInode->aulEntries[ulIdx]);
        }
    }
}


#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
/** @brief Swap the byte order of an indirect or double indirect node

    @param pIndir   Pointer to the node to swap
*/
static void BufferEndianSwapIndir(
    INDIR  *pIndir)
{
    if(pIndir == NULL)
    {
        REDERROR();
    }
    else
    {
        uint32_t ulIdx;

        pIndir->ulInode = RedRev32(pIndir->ulInode);

        for(ulIdx = 0; ulIdx < INDIR_ENTRIES; ulIdx++)
        {
            pIndir->aulEntries[ulIdx] = RedRev32(pIndir->aulEntries[ulIdx]);
        }
    }
}

#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */
#endif /* #ifdef REDCONF_ENDIAN_SWAP */


/** @brief Mark a buffer as least recently used.

    @param bIdx The index of the buffer to make LRU.
*/
static void BufferMakeLRU(
    uint8_t bIdx)
{
    if(bIdx >= REDCONF_BUFFER_COUNT)
    {
        REDERROR();
    }
    else if(bIdx != gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U])
    {
        uint8_t bMruIdx;

        /*  Find the current position of the buffer in the MRU array.  We do not
            need to check the last slot, since we already know from the above
            check that the index is not there.
        */
        for(bMruIdx = 0U; bMruIdx < (REDCONF_BUFFER_COUNT - 1U); bMruIdx++)
        {
            if(bIdx == gBufCtx.abMRU[bMruIdx])
            {
                break;
            }
        }

        if(bMruIdx < (REDCONF_BUFFER_COUNT - 1U))
        {
            /*  Move the buffer index to the back of the MRU array, making it
                the LRU buffer.
            */
            RedMemMove(&gBufCtx.abMRU[bMruIdx], &gBufCtx.abMRU[bMruIdx + 1U], REDCONF_BUFFER_COUNT - ((uint32_t)bMruIdx + 1U));
            gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U] = bIdx;
        }
        else
        {
            REDERROR();
        }
    }
    else
    {
        /*  Buffer already LRU, nothing to do.
        */
    }
}


/** @brief Mark a buffer as most recently used.

    @param bIdx The index of the buffer to make MRU.
*/
static void BufferMakeMRU(
    uint8_t bIdx)
{
    if(bIdx >= REDCONF_BUFFER_COUNT)
    {
        REDERROR();
    }
    else if(bIdx != gBufCtx.abMRU[0U])
    {
        uint8_t bMruIdx;

        /*  Find the current position of the buffer in the MRU array.  We do not
            need to check the first slot, since we already know from the above
            check that the index is not there.
        */
        for(bMruIdx = 1U; bMruIdx < REDCONF_BUFFER_COUNT; bMruIdx++)
        {
            if(bIdx == gBufCtx.abMRU[bMruIdx])
            {
                break;
            }
        }

        if(bMruIdx < REDCONF_BUFFER_COUNT)
        {
            /*  Move the buffer index to the front of the MRU array, making it
                the MRU buffer.
            */
            RedMemMove(&gBufCtx.abMRU[1U], &gBufCtx.abMRU[0U], bMruIdx);
            gBufCtx.abMRU[0U] = bIdx;
        }
        else
        {
            REDERROR();
        }
    }
    else
    {
        /*  Buffer already MRU, nothing to do.
        */
    }
}


/** @brief Find a block in the buffers.

    @param ulBlock  The block number to find.
    @param pbIdx    If the block is buffered (true is returned), populated with
                    the index of the buffer.

    @return Boolean indicating whether or not the block is buffered.

    @retval true    @p ulBlock is buffered, and its index has been stored in
                    @p pbIdx.
    @retval false   @p ulBlock is not buffered.
*/
static bool BufferFind(
    uint32_t ulBlock,
    uint8_t *pbIdx)
{
    bool     ret = false;

    if((ulBlock >= gpRedVolume->ulBlockCount) || (pbIdx == NULL))
    {
        REDERROR();
    }
    else
    {
        uint8_t bIdx;

        for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)
        {
            const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

            if((pHead->bVolNum == gbRedVolNum) && (pHead->ulBlock == ulBlock))
            {
                *pbIdx = bIdx;
                ret = true;
                break;
            }
        }
    }

    return ret;
}

