📄 davrcvr.c
字号:
/* Copyright (c) 1995-2002 Intel Corporation */
/* Intel Confidential */
/* ###########################################################################
### DAVRCVR
###
### Module: davrcvr.c - Power Loss Recovery Module
###
### $Workfile: davrcvr.c $
### $Revision: 81 $
### $NoKeywords: $
########################################################################### */
/*
*****************************************************************
* NOTICE OF LICENSE AGREEMENT
*
* This code is provided by Intel Corp., and the use is governed
* under the terms of a license agreement. See license agreement
* for complete terms of license.
*
* YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS. YOUR
* USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY
* PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN
* INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE
* FROM INTEL LICENSING ANY SUCH USE.
*****************************************************************
*/
/*### Include Files
#########################*/
#include "dav.h"
#if (DIRECT_ACCESS_VOLUME == TRUE)
#include "DavBkup.h"
#include "DavEvent.h"
#include "DavRtTbl.h"
#include "DavRatTbl.h"
#include "DavPaRecl.h"
#include "DavMem.h"
#include "davrcvr.h"
/*### Local Declarations
#########################*/
/*### Global Declarations
#########################*/
/*### Local Functions
#########################*/
/*### Global Functions
#########################*/
/*########################################################################*/
/*### Functions for repairing write in progress and absorbing objects */
/*########################################################################*/
/*#################################################################
### RECOVER_HandleAbsorbingPageObject
###
### DESCRIPTION:
### This function will fix an absorbing objects found
### during a scan of the fixed headers for PLR.
### Note that the implementation of this function is dependent
### on the implementation of davalloc, davrealloc, and dav
### defrag and makes certain assumptions about what we will
### find in terms of coverage of an absorbing object.
###
### PARAMETERS
### none.
###
### RETURNS:
### When this function passes with no errors a value of 0 is
### returned otherwise, it returns a status of type ERR_CODE.
###*/
ERR_CODE RECOVER_HandleAbsorbingPageObject(FDI_Handle aHeaderHandle,
HDR_FixedHeaderPtr aHeaderPtr,
BOOLEAN restart)
{
ERR_CODE status = ERR_NONE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
HDR_FixedHeader currHeader;
UINT32 pageSpaceCovered = 0;
UINT32 beginningAbsorbingObjectOffset;
UINT32 beginningCandidateObjectOffset;
UINT32 endingAbsorbingObjectOffset;
UINT32 endingCandidateObjectOffset;
UINT32 absorbingObjectSize;
UINT32 candidateObjectSize;
if (currHeaderHandle == aHeaderHandle)
{
/* skip to the next header */
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
}
/* calculate absorbing object characteristics */
beginningAbsorbingObjectOffset = FHDR_GetHeaderIndexOffset(aHeaderPtr);
absorbingObjectSize = FHDR_GetSize(aHeaderPtr);
endingAbsorbingObjectOffset = beginningAbsorbingObjectOffset + absorbingObjectSize - 1;
do
{
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, FALSE);
/* E5.5.970 Start */
mDEBUG_CHECK_ERRCODE(status);
/* E5.5.970 End */
/* if candidate header is for an object, dirty chunk, or free chunk in page space */
if (FHDR_IsPageObject(&currHeader))
{
/* if candidate header is not absorbed */
if (
(status == ERR_NONE) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_NOT_ABSORBED)
)
{
/* calculate candidate object characteristics */
beginningCandidateObjectOffset = FHDR_GetHeaderIndexOffset(&currHeader);
candidateObjectSize = FHDR_GetSize(&currHeader);
endingCandidateObjectOffset = beginningCandidateObjectOffset + candidateObjectSize - 1;
/* is the absorbing object within the candidate object? */
if (beginningAbsorbingObjectOffset >= beginningCandidateObjectOffset && endingAbsorbingObjectOffset <= endingCandidateObjectOffset)
{
/* absorbing object is entirely within the candidate object */
pageSpaceCovered += absorbingObjectSize;
break;
}
/* is the candidate object entirely within the absorbing object? */
else if (beginningCandidateObjectOffset >= beginningAbsorbingObjectOffset && endingCandidateObjectOffset <= endingAbsorbingObjectOffset)
{
/* candidate object is entirely within the absorbing object */
pageSpaceCovered += candidateObjectSize;
break;
}
/* is candidate object overlapping with the absorbing object? */
else if (beginningCandidateObjectOffset >= beginningAbsorbingObjectOffset && beginningCandidateObjectOffset <= endingAbsorbingObjectOffset)
{
pageSpaceCovered += (endingAbsorbingObjectOffset - beginningCandidateObjectOffset + 1);
}
else if (endingCandidateObjectOffset >= beginningAbsorbingObjectOffset && endingCandidateObjectOffset <= endingAbsorbingObjectOffset)
{
pageSpaceCovered += (endingCandidateObjectOffset - beginningAbsorbingObjectOffset - + 1);
}
}
}
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
if (currHeaderHandle == aHeaderHandle)
{
/* skip to the next header */
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
}
} while ((status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) != HDR_HEADER_UNUSED));
if (status == ERR_NO_MORE_ENTRIES)
{
status = ERR_NONE;
}
if (pageSpaceCovered == absorbingObjectSize)
{
/* we're done, and this header can be absorbed */
status = FHDR_AbsorbedHeaderInFlash(aHeaderHandle, aHeaderPtr);
return status;
}
else if (pageSpaceCovered == 0)
{
/* nothing replaces this object, so we need to create a brand new header for it */
FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;
FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
if (FHDR_GetAllocationStatus(aHeaderPtr) == HDR_ALLOC_EMPTY)
{
status = FHDR_CreateFreeChunkHeader(FDI_LastHeaderEntry,
beginningAbsorbingObjectOffset,
absorbingObjectSize);
if (status != ERR_NONE)
{
return status;
}
/* we're done, and this header can be absorbed */
status = FHDR_AbsorbedHeaderInFlash(aHeaderHandle, aHeaderPtr);
}
else if (FHDR_GetReallocationStatus(aHeaderPtr) == HDR_REALLOC_BACKUP_COMPLETE)
{
currHeader.Attr1 = aHeaderPtr->Attr1;
currHeader.Attr2 = aHeaderPtr->Attr2;
FHDR_SetAbsorbStatus(&currHeader, HDR_NOT_ABSORBED);
status = FHDR_CreateFixedHeaderBackup(FDI_LastHeaderEntry, &currHeader);
if (status != ERR_NONE)
{
return status;
}
/* validate the backup header in flash */
status = FHDR_ValidateHeaderInFlash(FDI_LastHeaderEntry, &currHeader);
if (status != ERR_NONE)
{
return status;
}
/* we're done, and this header can be absorbed */
status = FHDR_AbsorbedHeaderInFlash(aHeaderHandle, aHeaderPtr);
}
else
{
/* we should only find absorbing objects that are free chunks or backup objects */
status = ERR_STATE;
}
}
else
{
/* we've got partial coverage */
if (FHDR_GetAllocationStatus(aHeaderPtr) == HDR_ALLOC_EMPTY)
{
/* this is an absorbing free chunk */
/* create a free chunk header to cover the remaining area */
FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;
FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
status = FHDR_CreateFreeChunkHeader(FDI_LastHeaderEntry,
beginningAbsorbingObjectOffset + pageSpaceCovered,
absorbingObjectSize - pageSpaceCovered);
if (status != ERR_NONE)
{
return status;
}
/* we're done, and this header can be absorbed */
status = FHDR_AbsorbedHeaderInFlash(aHeaderHandle, aHeaderPtr);
}
else
{
/* this should never happen */
/* we should never have partial coverage on anything but a free chunk */
status = ERR_STATE;
}
}
return status;
}
/*#################################################################
### RECOVER_HandleWIPandAbsorbingPageObjects
###
### DESCRIPTION:
### This function will fix absorbing and WIP objects found
### during a scan of the fixed headers for PLR when not
### recovering from a reclaim. It will also restore original
### objects from backups if a backup object and original
### object are found.
###
### PARAMETERS
### none.
###
### RETURNS:
### When this function passes with no errors a value of 0 is
### returned otherwise, it returns a status of type ERR_CODE.
###*/
ERR_CODE RECOVER_HandleWIPandAbsorbingPageObjects(BOOLEAN restart)
{
ERR_CODE status = ERR_NONE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
HDR_FixedHeader currHeader;
/* walk through the headers */
do
{
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, restart);
/* E5.5.970 Start */
mDEBUG_CHECK_ERRCODE(status);
/* E5.5.970 End */
/* if header is for an object, dirty chunk, or free chunk in page space */
if (FHDR_IsPageObject(&currHeader))
{
/* if header is absorbing */
if (
(status == ERR_NONE) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_ABSORBING)
)
{
/* handle it */
status = RECOVER_HandleAbsorbingPageObject(currHeaderHandle, &currHeader, restart);
}
/* if header is WIP */
if (
(status == ERR_NONE) &&
(FHDR_GetAllocationStatus(&currHeader) == HDR_ALLOC_WRITE_IN_PROGRESS)
)
{
/* mark it as invalid */
status = FHDR_InvalidateHeaderInFlash(currHeaderHandle, &currHeader);
}
}
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
} while ((status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) != HDR_HEADER_UNUSED));
if (status == ERR_NO_MORE_ENTRIES)
{
status = ERR_NONE;
}
return status;
}
/*#################################################################
### RECOVER_HandleWIPandAbsorbingPageObjectsDuringReclaim
###
### DESCRIPTION:
### This function will fix absorbing and WIP objects found
### during a scan of the fixed headers for PLR from a reclaim.
###
### PARAMETERS
### none.
###
### RETURNS:
### When this function passes with no errors a value of 0 is
### returned otherwise, it returns a status of type ERR_CODE.
###*/
ERR_CODE RECOVER_HandleWIPandAbsorbingPageObjectsDuringReclaim(BOOLEAN restart)
{
ERR_CODE status = ERR_NONE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
HDR_FixedHeader currHeader;
/* walk through the headers */
do
{
/* E5.5.970 Start */
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, restart);
mDEBUG_CHECK_ERRCODE(status);
/* E5.5.970 End */
/* if header is for an object, dirty chunk, or free chunk in page space */
if (FHDR_IsPageObject(&currHeader))
{
/* if header is absorbing */
if (
(status == ERR_NONE) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_ABSORBING)
)
{
/* handle it */
status = RECOVER_HandleAbsorbingPageObject(currHeaderHandle, &currHeader, restart);
}
/* if header is WIP and not a backup object */
if (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -