REDSTATUS RedInodeCreate()

in FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c [192:312]


REDSTATUS RedInodeCreate(
    CINODE     *pInode,
    uint32_t    ulPInode,
    uint16_t    uMode)
{
    REDSTATUS   ret;

  #if REDCONF_API_POSIX == 1
    /*  ulPInode must be a valid inode number, unless we are creating the root
        directory, in which case ulPInode must be INODE_INVALID (the root
        directory has no parent).
    */
    if(    (pInode == NULL)
        || (!INODE_IS_VALID(ulPInode) && ((ulPInode != INODE_INVALID) || (pInode->ulInode != INODE_ROOTDIR))))
  #else
    if(pInode == NULL)
  #endif
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint32_t ulInode = pInode->ulInode;

        RedMemSet(pInode, 0U, sizeof(*pInode));

      #if REDCONF_API_POSIX == 1
        if(ulInode == INODE_INVALID)
        {
            /*  Caller requested that an inode number be allocated.  Search for
                an unused inode number, error if there isn't one.
            */
            ret = InodeFindFree(&pInode->ulInode);
        }
        else
      #endif
        {
            /*  Caller requested creation of a specific inode number.  Make sure
                it's valid and doesn't already exist.
            */
            if(INODE_IS_VALID(ulInode))
            {
                bool fFree;

                ret = RedInodeIsFree(ulInode, &fFree);
                if(ret == 0)
                {
                    if(fFree)
                    {
                        pInode->ulInode = ulInode;
                    }
                    else
                    {
                        ret = -RED_EEXIST;
                    }
                }
            }
            else
            {
                ret = -RED_EBADF;
            }
        }

        if(ret == 0)
        {
            uint8_t bWriteableWhich;

            ret = InodeGetWriteableCopy(pInode->ulInode, &bWriteableWhich);

            if(ret == 0)
            {
                ret = RedBufferGet(InodeBlock(pInode->ulInode, bWriteableWhich),
                    (uint16_t)((uint32_t)BFLAG_META_INODE | BFLAG_DIRTY | BFLAG_NEW), CAST_VOID_PTR_PTR(&pInode->pInodeBuf));

                if(ret == 0)
                {
                    /*  Mark the inode block as allocated.
                    */
                    ret = InodeBitSet(pInode->ulInode, bWriteableWhich, true);

                    if(ret != 0)
                    {
                        RedBufferPut(pInode->pInodeBuf);
                    }
                }
            }
        }

        if(ret == 0)
        {
          #if REDCONF_INODE_TIMESTAMPS == 1
            uint32_t ulNow = RedOsClockGetTime();

            pInode->pInodeBuf->ulATime = ulNow;
            pInode->pInodeBuf->ulMTime = ulNow;
            pInode->pInodeBuf->ulCTime = ulNow;
          #endif

            pInode->pInodeBuf->uMode = uMode;

          #if REDCONF_API_POSIX == 1
          #if REDCONF_API_POSIX_LINK == 1
            pInode->pInodeBuf->uNLink = 1U;
          #endif
            pInode->pInodeBuf->ulPInode = ulPInode;
          #else
            (void)ulPInode;
          #endif

            pInode->fBranched = true;
            pInode->fDirty = true;

          #if REDCONF_API_POSIX == 1
            gpRedMR->ulFreeInodes--;
          #endif
        }
    }

    return ret;
}