/*             ----> 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 directory operations.
*/
#include <redfs.h>

#if REDCONF_API_POSIX == 1

#include <redcore.h>


#define DIR_INDEX_INVALID   UINT32_MAX

#if (REDCONF_NAME_MAX % 4U) != 0U
#define DIRENT_PADDING      (4U - (REDCONF_NAME_MAX % 4U))
#else
#define DIRENT_PADDING      (0U)
#endif
#define DIRENT_SIZE         (4U + REDCONF_NAME_MAX + DIRENT_PADDING)
#define DIRENTS_PER_BLOCK   (REDCONF_BLOCK_SIZE / DIRENT_SIZE)
#define DIRENTS_MAX         (uint32_t)REDMIN(UINT32_MAX, UINT64_SUFFIX(1) * INODE_DATA_BLOCKS * DIRENTS_PER_BLOCK)


/** @brief On-disk directory entry.
*/
typedef struct
{
    /** The inode number that the directory entry points at.  If the directory
        entry is available, this holds INODE_INVALID.
    */
    uint32_t    ulInode;

    /** The name of the directory entry.  For names shorter than
        REDCONF_NAME_MAX, unused bytes in the array are zeroed.  For names of
        the maximum length, the string is not null terminated.
    */
    char        acName[REDCONF_NAME_MAX];

  #if DIRENT_PADDING > 0U
    /** Unused padding so that ulInode is always aligned on a four-byte
        boundary.
    */
    uint8_t     abPadding[DIRENT_PADDING];
  #endif
} DIRENT;


#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
static REDSTATUS DirCyclicRenameCheck(uint32_t ulSrcInode, const CINODE *pDstPInode);
#endif
#if REDCONF_READ_ONLY == 0
static REDSTATUS DirEntryWrite(CINODE *pPInode, uint32_t ulIdx, uint32_t ulInode, const char *pszName, uint32_t ulNameLen);
static uint64_t DirEntryIndexToOffset(uint32_t ulIdx);
#endif
static uint32_t DirOffsetToEntryIndex(uint64_t ullOffset);


#if REDCONF_READ_ONLY == 0
/** @brief Create a new entry in a directory.

    @param pPInode      A pointer to the cached inode structure of the directory
                        to which the new entry will be added.
    @param pszName      The name to be given to the new entry, terminated by a
                        null or a path separator.
    @param ulInode      The inode number the new name will point at.

    @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_ENOSPC         There is not enough space on the volume to
                                create the new directory entry; or the directory
                                is full.
    @retval -RED_ENOTDIR        @p pPInode is not a directory.
    @retval -RED_ENAMETOOLONG   @p pszName is too long.
    @retval -RED_EEXIST         @p pszName already exists in @p ulPInode.
    @retval -RED_EINVAL         @p pPInode is not a mounted dirty cached inode
                                structure; or @p pszName is not a valid name.
*/
REDSTATUS RedDirEntryCreate(
    CINODE     *pPInode,
    const char *pszName,
    uint32_t    ulInode)
{
    REDSTATUS   ret;

    if(!CINODE_IS_DIRTY(pPInode) || (pszName == NULL) || !INODE_IS_VALID(ulInode))
    {
        ret = -RED_EINVAL;
    }
    else if(!pPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else
    {
        uint32_t ulNameLen = RedNameLen(pszName);

        if(ulNameLen == 0U)
        {
            ret = -RED_EINVAL;
        }
        else if(ulNameLen > REDCONF_NAME_MAX)
        {
            ret = -RED_ENAMETOOLONG;
        }
        else
        {
            uint32_t ulEntryIdx;

            ret = RedDirEntryLookup(pPInode, pszName, &ulEntryIdx, NULL);
            if(ret == 0)
            {
                ret = -RED_EEXIST;
            }
            else if(ret == -RED_ENOENT)
            {
                if(ulEntryIdx == DIR_INDEX_INVALID)
                {
                    ret = -RED_ENOSPC;
                }
                else
                {
                    ret = 0;
                }
            }
            else
            {
                /*  Unexpected error, no action.
                */
            }

            if(ret == 0)
            {
                ret = DirEntryWrite(pPInode, ulEntryIdx, ulInode, pszName, ulNameLen);
            }
        }
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */


#if DELETE_SUPPORTED
/** @brief Delete an existing directory entry.

    @param pPInode      A pointer to the cached inode structure of the directory
                        containing the entry to be deleted.
    @param ulDeleteIdx  Position within the directory of the entry to be
                        deleted.

    @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_ENOSPC     The file system does not have enough space to modify
                            the parent directory to perform the deletion.
    @retval -RED_ENOTDIR    @p pPInode is not a directory.
    @retval -RED_EINVAL     @p pPInode is not a mounted dirty cached inode
                            structure; or @p ulIdx is out of range.
*/
REDSTATUS RedDirEntryDelete(
    CINODE     *pPInode,
    uint32_t    ulDeleteIdx)
{
    REDSTATUS   ret = 0;

    if(!CINODE_IS_DIRTY(pPInode) || (ulDeleteIdx >= DIRENTS_MAX))
    {
        ret = -RED_EINVAL;
    }
    else if(!pPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else if((DirEntryIndexToOffset(ulDeleteIdx) + DIRENT_SIZE) == pPInode->pInodeBuf->ullSize)
    {
        /*  Start searching one behind the index to be deleted.
        */
        uint32_t ulTruncIdx = ulDeleteIdx - 1U;
        bool     fDone = false;

        /*  We are deleting the last dirent in the directory, so search
            backwards to find the last populated dirent, allowing us to truncate
            the directory to that point.
        */
        while((ret == 0) && (ulTruncIdx != UINT32_MAX) && !fDone)
        {
            ret = RedInodeDataSeekAndRead(pPInode, ulTruncIdx / DIRENTS_PER_BLOCK);

            if(ret == 0)
            {
                const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
                uint32_t      ulBlockIdx = ulTruncIdx % DIRENTS_PER_BLOCK;

                do
                {
                    if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)
                    {
                        fDone = true;
                        break;
                    }

                    ulTruncIdx--;
                    ulBlockIdx--;
                } while(ulBlockIdx != UINT32_MAX);
            }
            else if(ret == -RED_ENODATA)
            {
                ret = 0;

                REDASSERT((ulTruncIdx % DIRENTS_PER_BLOCK) == 0U);
                ulTruncIdx -= DIRENTS_PER_BLOCK;
            }
            else
            {
                /*  Unexpected error, loop will terminate; nothing else
                    to be done.
                */
            }
        }

        /*  Currently ulTruncIdx represents the last valid dirent index, or
            UINT32_MAX if the directory is now empty.  Increment it so that it
            represents the first invalid entry, which will be truncated.
        */
        ulTruncIdx++;

        /*  Truncate the directory, deleting the requested entry and any empty
            dirents at the end of the directory.
        */
        if(ret == 0)
        {
            ret = RedInodeDataTruncate(pPInode, DirEntryIndexToOffset(ulTruncIdx));
        }
    }
    else
    {
        /*  The dirent to delete is not the last entry in the directory, so just
            zero it.
        */
        ret = DirEntryWrite(pPInode, ulDeleteIdx, INODE_INVALID, "", 0U);
    }

    return ret;
}
#endif /* DELETE_SUPPORTED */


/** @brief Perform a case-sensitive search of a directory for a given name.

    If found, then position of the entry within the directory and the inode
    number it points to are returned.  As an optimization for directory entry
    creation, in the case where the requested entry does not exist, the position
    of the first available (unused) entry is returned.

    @param pPInode      A pointer to the cached inode structure of the directory
                        to search.
    @param pszName      The name of the desired entry, terminated by either a
                        null or a path separator.
    @param pulEntryIdx  On successful return, meaning that the desired entry
                        exists, populated with the position of the entry.  If
                        returning an -RED_ENOENT error, populated with the
                        position of the first available entry, or set to
                        DIR_INDEX_INVALID if the directory is full.  Optional.
    @param pulInode     On successful return, populated with the inode number
                        that the name points to.  Optional; may be `NULL`.

    @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_ENOENT         @p pszName does not name an existing file or
                                directory.
    @retval -RED_ENOTDIR        @p pPInode is not a directory.
    @retval -RED_EINVAL         @p pPInode is not a mounted cached inode
                                structure; or @p pszName is not a valid name; or
                                @p pulEntryIdx is `NULL`.
    @retval -RED_ENAMETOOLONG   @p pszName is too long.
*/
REDSTATUS RedDirEntryLookup(
    CINODE     *pPInode,
    const char *pszName,
    uint32_t   *pulEntryIdx,
    uint32_t   *pulInode)
{
    REDSTATUS   ret = 0;

    if(!CINODE_IS_MOUNTED(pPInode) || (pszName == NULL))
    {
        ret = -RED_EINVAL;
    }
    else if(!pPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else
    {
        uint32_t ulNameLen = RedNameLen(pszName);

        if(ulNameLen == 0U)
        {
            ret = -RED_EINVAL;
        }
        else if(ulNameLen > REDCONF_NAME_MAX)
        {
            ret = -RED_ENAMETOOLONG;
        }
        else
        {
            uint32_t    ulIdx = 0U;
            uint32_t    ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);
            uint32_t    ulFreeIdx = DIR_INDEX_INVALID;  /* Index of first free dirent. */

            /*  Loop over the directory blocks, searching each block for a
                dirent that matches the given name.
            */
            while((ret == 0) && (ulIdx < ulDirentCount))
            {
                ret = RedInodeDataSeekAndRead(pPInode, ulIdx / DIRENTS_PER_BLOCK);

                if(ret == 0)
                {
                    const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
                    uint32_t      ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - ulIdx);
                    uint32_t      ulBlockIdx;

                    for(ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)
                    {
                        const DIRENT *pDirent = &pDirents[ulBlockIdx];

                        if(pDirent->ulInode != INODE_INVALID)
                        {
                            /*  The name in the dirent will not be null
                                terminated if it is of the maximum length, so
                                use a bounded string compare and then make sure
                                there is nothing more to the name.
                            */
                            if(    (RedStrNCmp(pDirent->acName, pszName, ulNameLen) == 0)
                                && ((ulNameLen == REDCONF_NAME_MAX) || (pDirent->acName[ulNameLen] == '\0')))
                            {
                                /*  Found a matching dirent, stop and return its
                                    information.
                                */
                                if(pulInode != NULL)
                                {
                                    *pulInode = pDirent->ulInode;

                                  #ifdef REDCONF_ENDIAN_SWAP
                                    *pulInode = RedRev32(*pulInode);
                                  #endif
                                }

                                ulIdx += ulBlockIdx;
                                break;
                            }
                        }
                        else if(ulFreeIdx == DIR_INDEX_INVALID)
                        {
                            ulFreeIdx = ulIdx + ulBlockIdx;
                        }
                        else
                        {
                            /*  The directory entry is free, but we already found a free one, so there's
                                nothing to do here.
                            */
                        }
                    }

                    if(ulBlockIdx < ulBlockLastIdx)
                    {
                        /*  If we broke out of the for loop, we found a matching
                            dirent and can stop the search.
                        */
                        break;
                    }

                    ulIdx += ulBlockLastIdx;
                }
                else if(ret == -RED_ENODATA)
                {
                    if(ulFreeIdx == DIR_INDEX_INVALID)
                    {
                        ulFreeIdx = ulIdx;
                    }

                    ret = 0;
                    ulIdx += DIRENTS_PER_BLOCK;
                }
                else
                {
                    /*  Unexpected error, let the loop terminate, no action
                        here.
                    */
                }
            }

            if(ret == 0)
            {
                /*  If we made it all the way to the end of the directory
                    without stopping, then the given name does not exist in the
                    directory.
                */
                if(ulIdx == ulDirentCount)
                {
                    /*  If the directory had no sparse dirents, then the first
                        free dirent is beyond the end of the directory.  If the
                        directory is already the maximum size, then there is no
                        free dirent.
                    */
                    if((ulFreeIdx == DIR_INDEX_INVALID) && (ulDirentCount < DIRENTS_MAX))
                    {
                        ulFreeIdx = ulDirentCount;
                    }

                    ulIdx = ulFreeIdx;

                    ret = -RED_ENOENT;
                }

                if(pulEntryIdx != NULL)
                {
                    *pulEntryIdx = ulIdx;
                }
            }
        }
    }

    return ret;
}


#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)
/** @brief Read the next entry from a directory, given a starting index.

    @param pPInode  A pointer to the cached inode structure of the directory to
                    read from.
    @param pulIdx   On entry, the directory index to start reading from.  On
                    successful return, populated with the directory index to use
                    for subsequent reads.  On -RED_ENOENT return, populated with
                    the directory index immediately following the last valid
                    one.
    @param pszName  On successful return, populated with the name of the next
                    directory entry.  Buffer must be at least
                    REDCONF_NAME_MAX + 1 in size, to store the maximum name
                    length plus a null terminator.
    @param pulInode On successful return, populated with the inode number
                    pointed at by the next directory entry.

    @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_ENOENT     There are no more entries in the directory.
    @retval -RED_ENOTDIR    @p pPInode is not a directory.
    @retval -RED_EINVAL     @p pPInode is not a mounted cached inode structure;
                            or @p pszName is `NULL`; or @p pulIdx is `NULL`; or
                            @p pulInode is `NULL`.
*/
REDSTATUS RedDirEntryRead(
    CINODE     *pPInode,
    uint32_t   *pulIdx,
    char       *pszName,
    uint32_t   *pulInode)
{
    REDSTATUS   ret = 0;

    if(!CINODE_IS_MOUNTED(pPInode) || (pulIdx == NULL) || (pszName == NULL) || (pulInode == NULL))
    {
        ret = -RED_EINVAL;
    }
    else if(!pPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else
    {
        uint32_t ulIdx = *pulIdx;
        uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);

        /*  Starting either at the beginning of the directory or where we left
            off, loop over the directory blocks, searching each block for a
            non-sparse dirent to return as the next entry in the directory.
        */
        while((ret == 0) && (ulIdx < ulDirentCount))
        {
            uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK;

            ret = RedInodeDataSeekAndRead(pPInode, ulBlockOffset);

            if(ret == 0)
            {
                const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
                uint32_t      ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - (ulBlockOffset * DIRENTS_PER_BLOCK));
                uint32_t      ulBlockIdx;

                for(ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)
                {
                    if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)
                    {
                        *pulIdx = ulIdx + 1U;
                        RedStrNCpy(pszName, pDirents[ulBlockIdx].acName, REDCONF_NAME_MAX);
                        pszName[REDCONF_NAME_MAX] = '\0';

                        *pulInode = pDirents[ulBlockIdx].ulInode;

                      #ifdef REDCONF_ENDIAN_SWAP
                        *pulInode = RedRev32(*pulInode);
                      #endif
                        break;
                    }

                    ulIdx++;
                }

                if(ulBlockIdx < ulBlockLastIdx)
                {
                    REDASSERT(ulIdx <= ulDirentCount);
                    break;
                }
            }
            else if(ret == -RED_ENODATA)
            {
                ulIdx += DIRENTS_PER_BLOCK - (ulIdx % DIRENTS_PER_BLOCK);
                ret = 0;
            }
            else
            {
                /*  Unexpected error, loop will terminate; nothing else to do.
                */
            }

            REDASSERT(ulIdx <= ulDirentCount);
        }

        if((ret == 0) && (ulIdx >= ulDirentCount))
        {
            *pulIdx = ulDirentCount;
            ret = -RED_ENOENT;
        }
    }

    return ret;
}
#endif


#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
/** Rename a directory entry.

    @param pSrcPInode   The inode of the directory containing @p pszSrcName.
    @param pszSrcName   The name of the directory entry to be renamed.
    @param pSrcInode    On successful return, populated with the inode of the
                        source entry.
    @param pDstPInode   The inode of the directory in which @p pszDstName will
                        be created or replaced.
    @param pszDstName   The name of the directory entry to be created or
                        replaced.
    @param pDstInode    On successful return, if the destination previously
                        existed, populated with the inode previously pointed to
                        by the destination.  This may be the same as the source
                        inode.  If the destination did not exist, populated with
                        INODE_INVALID.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0                   Operation was successful.
    @retval -RED_EEXIST         #REDCONF_RENAME_ATOMIC is false and the
                                destination name exists.
    @retval -RED_EINVAL         @p pSrcPInode is not a mounted dirty cached
                                inode structure; or @p pSrcInode is `NULL`; or
                                @p pszSrcName is not a valid name; or
                                @p pDstPInode is not a mounted dirty cached
                                inode structure; or @p pDstInode is `NULL`; or
                                @p pszDstName is not a valid name.
    @retval -RED_EIO            A disk I/O error occurred.
    @retval -RED_EISDIR         The destination name exists and is a directory,
                                and the source name is a non-directory.
    @retval -RED_ENAMETOOLONG   Either @p pszSrcName or @p pszDstName is longer
                                than #REDCONF_NAME_MAX.
    @retval -RED_ENOENT         The source name is not an existing entry; or
                                either @p pszSrcName or @p pszDstName point to
                                an empty string.
    @retval -RED_ENOTDIR        @p pSrcPInode is not a directory; or
                                @p pDstPInode is not a directory; or the source
                                name is a directory and the destination name is
                                a file.
    @retval -RED_ENOTEMPTY      The destination name is a directory which is not
                                empty.
    @retval -RED_ENOSPC         The file system does not have enough space to
                                extend the @p ulDstPInode directory.
    @retval -RED_EROFS          The directory to be removed resides on a
                                read-only file system.
*/
REDSTATUS RedDirEntryRename(
    CINODE     *pSrcPInode,
    const char *pszSrcName,
    CINODE     *pSrcInode,
    CINODE     *pDstPInode,
    const char *pszDstName,
    CINODE     *pDstInode)
{
    REDSTATUS   ret;

    if(    !CINODE_IS_DIRTY(pSrcPInode)
        || (pszSrcName == NULL)
        || (pSrcInode == NULL)
        || !CINODE_IS_DIRTY(pDstPInode)
        || (pszDstName == NULL)
        || (pDstInode == NULL))
    {
        ret = -RED_EINVAL;
    }
    else if(!pSrcPInode->fDirectory || !pDstPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else
    {
        uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */
        uint32_t ulSrcIdx;

        /*  Look up the source and destination names.
        */
        ret = RedDirEntryLookup(pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode);

        if(ret == 0)
        {
            ret = RedDirEntryLookup(pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode);

            if(ret == -RED_ENOENT)
            {
                if(ulDstIdx == DIR_INDEX_INVALID)
                {
                    ret = -RED_ENOSPC;
                }
                else
                {
                  #if REDCONF_RENAME_ATOMIC == 1
                    pDstInode->ulInode = INODE_INVALID;
                  #endif
                    ret = 0;
                }
            }
          #if REDCONF_RENAME_ATOMIC == 0
            else if(ret == 0)
            {
                ret = -RED_EEXIST;
            }
            else
            {
                /*  Nothing to do here, just propagate the error.
                */
            }
          #endif
        }

      #if REDCONF_RENAME_ATOMIC == 1
        /*  If both names point to the same inode, POSIX says to do nothing to
            either name.
        */
        if((ret == 0) && (pSrcInode->ulInode != pDstInode->ulInode))
      #else
        if(ret == 0)
      #endif
        {
            ret = RedInodeMount(pSrcInode, FTYPE_EITHER, true);

          #if REDCONF_RENAME_ATOMIC == 1
            if((ret == 0) && (pDstInode->ulInode != INODE_INVALID))
            {
                /*  Source and destination must be the same type (file/dir).
                */
                ret = RedInodeMount(pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true);

                /*  If renaming directories, the destination must be empty.
                */
                if((ret == 0) && pDstInode->fDirectory && (pDstInode->pInodeBuf->ullSize > 0U))
                {
                    ret = -RED_ENOTEMPTY;
                }
            }
          #endif

            /*  If we are renaming a directory, make sure the rename isn't
                cyclic (e.g., renaming "foo" into "foo/bar").
            */
            if((ret == 0) && pSrcInode->fDirectory)
            {
                ret = DirCyclicRenameCheck(pSrcInode->ulInode, pDstPInode);
            }

            if(ret == 0)
            {
                ret = DirEntryWrite(pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen(pszDstName));
            }

            if(ret == 0)
            {
                ret = RedDirEntryDelete(pSrcPInode, ulSrcIdx);

                if(ret == -RED_ENOSPC)
                {
                    REDSTATUS ret2;

                    /*  If there was not enough space to branch the parent
                        directory inode and data block containin the source
                        entry, revert destination directory entry to its
                        previous state.
                    */
                  #if REDCONF_RENAME_ATOMIC == 1
                    if(pDstInode->ulInode != INODE_INVALID)
                    {
                        ret2 = DirEntryWrite(pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen(pszDstName));
                    }
                    else
                  #endif
                    {
                        ret2 = RedDirEntryDelete(pDstPInode, ulDstIdx);
                    }

                    if(ret2 != 0)
                    {
                        ret = ret2;
                        CRITICAL_ERROR();
                    }
                }
            }

            if(ret == 0)
            {
                pSrcInode->pInodeBuf->ulPInode = pDstPInode->ulInode;
            }
        }
    }

    return ret;
}


/** @brief Check for a cyclic rename.

    A cyclic rename is renaming a directory into a subdirectory of itself.  For
    example, renaming "a" into "a/b/c/d" is cyclic.  These renames must not be
    allowed since they would corrupt the directory tree.

    @param ulSrcInode   The inode number of the directory being renamed.
    @param pDstPInode   A pointer to the cached inode structure of the directory
                        into which the source is being renamed.

    @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     The rename is cyclic; or invalid parameters.
    @retval -RED_ENOTDIR    @p pDstPInode is not a directory.
*/
static REDSTATUS DirCyclicRenameCheck(
    uint32_t        ulSrcInode,
    const CINODE   *pDstPInode)
{
    REDSTATUS       ret = 0;

    if(!INODE_IS_VALID(ulSrcInode) || !CINODE_IS_MOUNTED(pDstPInode))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else if(ulSrcInode == pDstPInode->ulInode)
    {
        ret = -RED_EINVAL;
    }
    else if(!pDstPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else
    {
        CINODE NextParent;
        /*  Used to prevent infinite loop in case of corrupted directory
            structure.
        */
        uint32_t ulIteration = 0U;

        NextParent.ulInode = pDstPInode->pInodeBuf->ulPInode;

        while(     (NextParent.ulInode != ulSrcInode)
                && (NextParent.ulInode != INODE_ROOTDIR)
                && (NextParent.ulInode != INODE_INVALID)
                && (ulIteration < gpRedVolConf->ulInodeCount))
        {
            ret = RedInodeMount(&NextParent, FTYPE_DIR, false);
            if(ret != 0)
            {
                break;
            }

            NextParent.ulInode = NextParent.pInodeBuf->ulPInode;

            RedInodePut(&NextParent, 0U);

            ulIteration++;
        }

        if((ret == 0) && (ulIteration == gpRedVolConf->ulInodeCount))
        {
            CRITICAL_ERROR();
            ret = -RED_EFUBAR;
        }

        if((ret == 0) && (ulSrcInode == NextParent.ulInode))
        {
            ret = -RED_EINVAL;
        }
    }

    return ret;
}
#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */


#if REDCONF_READ_ONLY == 0
/** @brief Update the contents of a directory entry.

    @param pPInode      A pointer to the cached inode structure of the directory
                        whose entry is being written.
    @param ulIdx        The index of the directory entry to write.
    @param ulInode      The inode number the directory entry is to point at.
    @param pszName      The name of the directory entry.
    @param ulNameLen    The length of @p pszName.

    @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_ENOSPC     There is not enough space on the volume to write the
                            directory entry.
    @retval -RED_ENOTDIR    @p pPInode is not a directory.
    @retval -RED_EINVAL     Invalid parameters.
*/
static REDSTATUS DirEntryWrite(
    CINODE     *pPInode,
    uint32_t    ulIdx,
    uint32_t    ulInode,
    const char *pszName,
    uint32_t    ulNameLen)
{
    REDSTATUS   ret;

    if(    !CINODE_IS_DIRTY(pPInode)
        || (ulIdx >= DIRENTS_MAX)
        || (!INODE_IS_VALID(ulInode) && (ulInode != INODE_INVALID))
        || (pszName == NULL)
        || (ulNameLen > REDCONF_NAME_MAX)
        || ((ulNameLen == 0U) != (ulInode == INODE_INVALID)))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else if(!pPInode->fDirectory)
    {
        ret = -RED_ENOTDIR;
    }
    else
    {
        uint64_t        ullOffset = DirEntryIndexToOffset(ulIdx);
        uint32_t        ulLen = DIRENT_SIZE;
        static DIRENT   de;

        RedMemSet(&de, 0U, sizeof(de));

        de.ulInode = ulInode;

      #ifdef REDCONF_ENDIAN_SWAP
        de.ulInode = RedRev32(de.ulInode);
      #endif

        RedStrNCpy(de.acName, pszName, ulNameLen);

        ret = RedInodeDataWrite(pPInode, ullOffset, &ulLen, &de);
    }

    return ret;
}


/** @brief Convert a directory entry index to a byte offset.

    @param ulIdx    Directory entry index.

    @return Byte offset in the directory corresponding with ulIdx.
*/
static uint64_t DirEntryIndexToOffset(
    uint32_t ulIdx)
{
    uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK;
    uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK;
    uint64_t ullOffset;

    REDASSERT(ulIdx < DIRENTS_MAX);

    ullOffset = (uint64_t)ulBlock << BLOCK_SIZE_P2;
    ullOffset += (uint64_t)ulOffsetInBlock * DIRENT_SIZE;

    return ullOffset;
}
#endif /* REDCONF_READ_ONLY == 0 */


/** @brief Convert a byte offset to a directory entry index.

    @param ullOffset    Byte offset in the directory.

    @return Directory entry index corresponding with @p ullOffset.
*/
static uint32_t DirOffsetToEntryIndex(
    uint64_t ullOffset)
{
    uint32_t ulIdx;

    REDASSERT(ullOffset < INODE_SIZE_MAX);
    REDASSERT(((uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) % DIRENT_SIZE) == 0U);

    /*  Avoid doing any 64-bit divides.
    */
    ulIdx = (uint32_t)(ullOffset >> BLOCK_SIZE_P2) * DIRENTS_PER_BLOCK;
    ulIdx += (uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) / DIRENT_SIZE;

    return ulIdx;
}


#endif /* REDCONF_API_POSIX == 1 */

