in FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c [987:1130]
static void SeekCoord(
CINODE *pInode,
uint32_t ulBlock)
{
if(!CINODE_IS_MOUNTED(pInode) || (ulBlock >= INODE_DATA_BLOCKS))
{
REDERROR();
}
else if((pInode->ulLogicalBlock != ulBlock) || !pInode->fCoordInited)
{
RedInodePutData(pInode);
pInode->ulLogicalBlock = ulBlock;
#if REDCONF_DIRECT_POINTERS > 0U
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
if(ulBlock < REDCONF_DIRECT_POINTERS)
#endif
{
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
RedInodePutCoord(pInode);
#endif
pInode->uInodeEntry = (uint16_t)ulBlock;
pInode->ulDataBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry];
#if DINDIR_POINTERS > 0U
pInode->uDindirEntry = COORD_ENTRY_INVALID;
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
pInode->uIndirEntry = COORD_ENTRY_INVALID;
#endif
}
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
else
#endif
#endif
#if REDCONF_INDIRECT_POINTERS > 0U
#if REDCONF_INDIRECT_POINTERS < INODE_ENTRIES
if(ulBlock < (INODE_INDIR_BLOCKS + REDCONF_DIRECT_POINTERS))
#endif
{
uint32_t ulIndirRangeOffset = ulBlock - REDCONF_DIRECT_POINTERS;
uint16_t uInodeEntry = (uint16_t)((ulIndirRangeOffset / INDIR_ENTRIES) + REDCONF_DIRECT_POINTERS);
uint16_t uIndirEntry = (uint16_t)(ulIndirRangeOffset % INDIR_ENTRIES);
#if DINDIR_POINTERS > 0U
RedInodePutDindir(pInode);
#endif
/* If the inode entry is not changing, then the previous indirect
is still the correct one. Otherwise, the old indirect will be
released and the new one will be read later.
*/
if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited)
{
RedInodePutIndir(pInode);
pInode->uInodeEntry = uInodeEntry;
pInode->ulIndirBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry];
}
#if DINDIR_POINTERS > 0U
pInode->uDindirEntry = COORD_ENTRY_INVALID;
#endif
pInode->uIndirEntry = uIndirEntry;
/* At this point, the following pInode members are needed but not
yet populated:
- pIndir
- ulDataBlock
*/
}
#if DINDIR_POINTERS > 0U
else
#endif
#endif
#if DINDIR_POINTERS > 0U
{
uint32_t ulDindirRangeOffset = (ulBlock - REDCONF_DIRECT_POINTERS) - INODE_INDIR_BLOCKS;
uint16_t uInodeEntry = (uint16_t)((ulDindirRangeOffset / DINDIR_DATA_BLOCKS) + REDCONF_DIRECT_POINTERS + REDCONF_INDIRECT_POINTERS);
uint32_t ulDindirNodeOffset = ulDindirRangeOffset % DINDIR_DATA_BLOCKS;
uint16_t uDindirEntry = (uint16_t)(ulDindirNodeOffset / INDIR_ENTRIES);
uint16_t uIndirEntry = (uint16_t)(ulDindirNodeOffset % INDIR_ENTRIES);
/* If the inode entry is not changing, then the previous double
indirect is still the correct one. Otherwise, the old double
indirect will be released and the new one will be read later.
*/
if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited)
{
RedInodePutIndir(pInode);
RedInodePutDindir(pInode);
pInode->uInodeEntry = uInodeEntry;
pInode->ulDindirBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry];
}
/* If neither the inode entry nor double indirect entry are
changing, then the previous indirect is still the correct one.
Otherwise, it old indirect will be released and the new one will
be read later.
*/
else if(pInode->uDindirEntry != uDindirEntry)
{
RedInodePutIndir(pInode);
}
else
{
/* Data buffer has already been put, nothing to do.
*/
}
pInode->uDindirEntry = uDindirEntry;
pInode->uIndirEntry = uIndirEntry;
/* At this point, the following pInode members are needed but not
yet populated:
- pDindir
- pIndir
- ulIndirBlock
- ulDataBlock
*/
}
#elif (REDCONF_DIRECT_POINTERS > 0U) && (REDCONF_INDIRECT_POINTERS > 0U)
else
{
/* There are no double indirects, so the block should have been in
the direct or indirect range.
*/
REDERROR();
}
#endif
pInode->fCoordInited = true;
}
else
{
/* Seeking to the current position, nothing to do.
*/
}
}