in FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c [154:270]
REDSTATUS RedVolMountMetaroot(void)
{
REDSTATUS ret;
ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT, 1U, &gpRedCoreVol->aMR[0U]);
if(ret == 0)
{
ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + 1U, 1U, &gpRedCoreVol->aMR[1U]);
}
/* Determine which metaroot is the most recent copy that was written
completely.
*/
if(ret == 0)
{
uint8_t bMR = UINT8_MAX;
bool fSectorCRCIsValid;
if(MetarootIsValid(&gpRedCoreVol->aMR[0U], &fSectorCRCIsValid))
{
bMR = 0U;
#ifdef REDCONF_ENDIAN_SWAP
MetaRootEndianSwap(&gpRedCoreVol->aMR[0U]);
#endif
}
else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)
{
ret = -RED_EIO;
}
else
{
/* Metaroot is not valid, so it is ignored and there's nothing
to do here.
*/
}
if(ret == 0)
{
if(MetarootIsValid(&gpRedCoreVol->aMR[1U], &fSectorCRCIsValid))
{
#ifdef REDCONF_ENDIAN_SWAP
MetaRootEndianSwap(&gpRedCoreVol->aMR[1U]);
#endif
if((bMR != 0U) || (gpRedCoreVol->aMR[1U].hdr.ullSequence > gpRedCoreVol->aMR[0U].hdr.ullSequence))
{
bMR = 1U;
}
}
else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)
{
ret = -RED_EIO;
}
else
{
/* Metaroot is not valid, so it is ignored and there's nothing
to do here.
*/
}
}
if(ret == 0)
{
if(bMR == UINT8_MAX)
{
/* Neither metaroot was valid.
*/
ret = -RED_EIO;
}
else
{
gpRedCoreVol->bCurMR = bMR;
gpRedMR = &gpRedCoreVol->aMR[bMR];
}
}
}
if(ret == 0)
{
/* Normally the metaroot contains the highest sequence number, but the
master block is the last block written during format, so on a
freshly formatted volume the master block sequence number (stored in
gpRedVolume->ullSequence) will be higher than that in the metaroot.
*/
if(gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence)
{
gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence;
}
/* gpRedVolume->ullSequence stores the *next* sequence number; to avoid
giving the next node written to disk the same sequence number as the
metaroot, increment it here.
*/
ret = RedVolSeqNumIncrement();
}
if(ret == 0)
{
gpRedVolume->fMounted = true;
#if REDCONF_READ_ONLY == 0
gpRedVolume->fReadOnly = false;
#endif
#if RESERVED_BLOCKS > 0U
gpRedCoreVol->fUseReservedBlocks = false;
#endif
gpRedCoreVol->ulAlmostFreeBlocks = 0U;
gpRedCoreVol->aMR[1U - gpRedCoreVol->bCurMR] = *gpRedMR;
gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR;
gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];
}
return ret;
}