davrecl.c
来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,664 行 · 第 1/5 页
C
1,664 行
/* by the allocate functions */
status = RECTBL_CreateTable(&SearchInfo,
(BOOLEAN)(method == ReclaimPageObjects), restart);
if(status)
{
return status;
}
EVT_Test4Crash(EVT_RECLAIM_StateB);
/* Save off the base address of the reclaim table and the */
/* address of the reclaim table header entry. */
/* NOTE: SearchInfo must reference the reclaim table object. */
ReclaimState.RecTblBaseAddr = SearchInfo.CurrObj.ObjectAddress;
ReclaimState.RecTblHdrAddr = SearchInfo.CurrObj.HeaderAddress;
/*lint -fallthrough*/
case RECRCVR_InitReclaimTable:
status = LocateFirstBlock(method, &blk_num, restart);
if ((status != ERR_NONE) && (status != ERR_NO_MORE_ENTRIES))
{
return(status);
}
if(status == ERR_NONE)
{
ReclaimState.TableInfo.FirstBlock = (UINT16)blk_num;
}
if(method == ReclaimPageObjects)
{
ReclaimState.TableInfo.TotalBlocks = (UINT16)
(Handle2Block((ReclaimState.RecTblBaseAddr +
RECTBL_PageRecTblSize - 1)) + 1) -
ReclaimState.TableInfo.FirstBlock;
}
else
{
ReclaimState.TableInfo.TotalBlocks = (UINT16)(
(ReclaimState.TableInfo.FirstBlock -
Handle2Block(ReclaimState.RecTblBaseAddr)) + 1);
}
status = RECTBL_WriteTableInfo(ReclaimState.RecTblBaseAddr, &ReclaimState.TableInfo,
(BOOLEAN)(method == ReclaimParagraphObjects));
if(status)
{
break;
}
EVT_Test4Crash(EVT_RECLAIM_StateC);
if(method == ReclaimParagraphObjects)
{
/* Write all of the block entries to the reclaim table. */
status = RECPARA_InitReclaimTable(&SearchInfo,
ReclaimState.RecTblBaseAddr,
&ReclaimState.TableInfo, restart);
if(status)
{
break;
}
EVT_Test4Crash(EVT_RECLAIM_StateD);
/* Write Reclaim Table offset + status of ReclaimInProgress */
/* to the configuration header. */
status = CFGHDR_WriteTableOffset(ReclaimState.ConfigIndex,
ReclaimState.RecTblHdrAddr);
if(status)
{
break;
}
/* If we haven't already set the free block map, then */
/* point it to the top of the current erase block. */
MemMap.FreeBlk.BaseAddr =
Block2Handle(ReclaimState.TableInfo.FirstBlock) +
FDI_BlockSize - 1;
}
else
{
EVT_Test4Crash(EVT_RECLAIM_StateD);
/* Initialize the page reclaim table */
status = RECPAGE_InitReclaimTable(restart);
if(status)
{
break;
}
/* If we haven't already set the free block map, then */
/* point it to the bottom of the current erase block. */
MemMap.FreeBlk.BaseAddr =
Block2Handle(ReclaimState.TableInfo.FirstBlock);
}
/* Start with first object in header space. */
SearchInfo.CurrObj.HeaderAddress = 0;
SearchInfo.CurrObj.ConfigEntry.Status = 0;
SearchInfo.CurrObj.ConfigEntry.Offset = 0;
ReclaimState.CurrentBlock2Reclaim =
ReclaimState.TableInfo.FirstBlock;
ReclaimState.CurrentDoneBlock =
ReclaimState.CurrentBlock2Reclaim;
EVT_Test4Crash(EVT_RECLAIM_StateE);
/*lint -fallthrough*/
case RECRCVR_StartStateMachine:
/* Process each block until the next state = ReclaimComplete. */
while(!status && (ReclaimState.NextState !=
(UINT16)RECLAIM_ST_ReclaimComplete))
{
if(method == ReclaimParagraphObjects)
{
status = RECPARA_SaveValidObjsInCurrBlock(restart);
ReclaimState.CurrentBlock2Reclaim--;
}
else
{
status = RECPAGE_SaveValidObjsInCurrBlock(restart);
ReclaimState.CurrentBlock2Reclaim++;
}
}
/* Bump the block back one due to loop method */
if(method == ReclaimParagraphObjects)
{
ReclaimState.CurrentBlock2Reclaim++;
}
else
{
ReclaimState.CurrentBlock2Reclaim--;
}
if(status)
{
break;
}
/*lint -fallthrough*/
case RECRCVR_RelocateReclaimTable:
/* Move the reclaim table to the reclaim block. */
status = RECLAIM_ReLocateReclaimTable((BOOLEAN)(method == ReclaimParagraphObjects), restart);
if(status)
{
break;
}
/*lint -fallthrough*/
case RECRCVR_FinishRemainingBlocks:
/* Erase the current block & copy back any reclaim block data. */
status = RECLAIM_FinishBlock(ReclaimState.CurrentBlock2Reclaim,
(BOOLEAN)(method == ReclaimParagraphObjects), FALSE, restart);
EVT_Test4Crash(EVT_RECLAIM_StateJ);
if(method == ReclaimParagraphObjects)
{
last_block_2_reclaim = ReclaimState.TableInfo.FirstBlock -
(ReclaimState.TableInfo.TotalBlocks - 1);
}
else
{
last_block_2_reclaim = ReclaimState.TableInfo.FirstBlock +
(ReclaimState.TableInfo.TotalBlocks - 1);
}
/* Erase any blocks that are spanned by the reclaim table. */
while((ReclaimState.CurrentBlock2Reclaim !=
last_block_2_reclaim) && !status)
{
if(method == ReclaimParagraphObjects)
{
if(ReclaimState.CurrentBlock2Reclaim == 0)
{
break;
}
ReclaimState.CurrentBlock2Reclaim--;
}
else
{
ReclaimState.CurrentBlock2Reclaim++;
}
/* If the reclaim table crossed into the next block, */
/* then erase the remaining portion right away. */
status = RECLAIM_EraseBlock(ReclaimState.CurrentBlock2Reclaim,
TRUE, (BOOLEAN)(method == ReclaimParagraphObjects), restart);
}
if(status)
{
break;
}
EVT_Test4Crash(EVT_RECLAIM_StateK);
/*lint -fallthrough*/
case RECRCVR_FinishUpReclaim:
/* Reset the flag that indicates the OTT table needs to be *
* initialized for future deallocates. */
OTT_flag = FALSE;
/*
* Must mark the TableId in the reclaim block to 0 to
* indicate that the reclaim block will be erased.
* Recovery will see that there is no table in the RB
* yet, there is still a reclaim table object, etc, etc.
*/
ReclaimState.TableInfo.TableId = RECTBL_TableDataInvalid;
status = FLASH_WriteBuffer((ReclaimState.RecTblBaseAddr + RECTBL_TableIdOffset),
(MemBufferPtr)&ReclaimState.TableInfo.TableId,
sizeof(ReclaimState.TableInfo.TableId));
if(status)
{
break;
}
if(method == ReclaimParagraphObjects)
{
/* Erase the reclaim block. */
status = FLASH_EraseBlock(FDI_ReclaimBlockAddress, FALSE);
if(status)
{
return status;
}
EVT_Test4Crash(EVT_RECLAIM_StateL);
/* Mark the configuration header entry ReclaimComplete. */
status = CFGHDR_WriteReclaimComplete(ReclaimState.ConfigIndex);
if(status)
{
return status;
}
}
else
{
/* Mark all invalid page header entries to Absorbed. */
status = HDR_AbsorbInvalidHeaders(&SearchInfo, restart);
if(status)
{
return status;
}
/* Erase the reclaim block. */
status = FLASH_EraseBlock(FDI_ReclaimBlockAddress, FALSE);
if(status)
{
return status;
}
EVT_Test4Crash(EVT_RECLAIM_StateL);
/* Mark the reclaim table header to absorbed. */
status = HDR_AbsorbHeader(SearchInfo.CurrObj.HeaderAddress,
SearchInfo.HeaderPtr);
EVT_Test4Crash(EVT_RECLAIM_StateL_SP1);
if(status)
{
return(status);
}
/* Mark the reclaim table header to Invalid. ??? */
status = HDR_InvalidateHeader(SearchInfo.CurrObj.HeaderAddress,
SearchInfo.HeaderPtr);
if(status)
{
return status;
}
}
/*lint -fallthrough*/
case RECRCVR_ModifyMovedObjects:
if(method == ReclaimPageObjects)
{
/* Reset the object counter to 0. */
ReclaimState.CurrentObject2Modify = 0;
/* Read the OTT table. */
status = OTTTBL_GetTableInfo(ReclaimState.OTTTblBaseAddr,
&ReclaimState.OTTTableInfo, restart);
if(status)
{
return status;
}
/* If the src_addr and the dest_addr fields are valid,
* it means that some objects might have to be reallocated.
*/
if((ReclaimState.OTTTableInfo.dest_addr != DWORDMAX) &&
(ReclaimState.OTTTableInfo.src_addr != DWORDMAX))
{
if(restart)
{
/* Read the current object entry. */
status = OTTTBL_ReadTable(ReclaimState.OTTTblBaseAddr,
ReclaimState.CurrentObject2Modify,
&ReclaimState.OTTTblEntry, restart);
if(status != ERR_NONE)
{
return status;
}
/* If OTT entry is finished, update dest and src addresses to point
* to addresses following this object.
*/
while(OTTTBL_IsOTTEntryInvalid(ReclaimState.OTTTblEntry.status))
{
/* Update dest address based on this item's object size */
ReclaimState.OTTTableInfo.dest_addr +=
ReclaimState.OTTTblEntry.objsize;
/* Update src address based on this item's object size */
ReclaimState.OTTTableInfo.src_addr +=
ReclaimState.OTTTblEntry.objsize;
/* Increment the CurrentObject2Modify so that the next scan of the
* OTT table will find the next item.
*/
ReclaimState.CurrentObject2Modify++;
/* Read the next object entry. */
status = OTTTBL_ReadTable(ReclaimState.OTTTblBaseAddr,
ReclaimState.CurrentObject2Modify,
&ReclaimState.OTTTblEntry, restart);
if(status != ERR_NONE)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?