?? garbagecollector.c
字號:
#include "OSModule_MemoryManagement.h"
#include "Common.h"
#include "GarbageCollector.h"
#include "HardwareAdaptationlayer.h"
#include "FalUserDirective.h"
#include "BadBlockManagement.h"
#include "WearLeveling.h"
#include "StructureManager.h"
//static UINT8 pageInBlock;
static UINT16 NumPageWritten;
/******************************************************************************
* MinimizeStructure *
*******************************************************************************
* Perform the erase of the block contained in a structure *
*******************************************************************************
* PARAMETERS *
* blockNumbers: containt the list of blocks that compose the sector *
* history data structure *
* len: indicate the size of blockNumbers *
* mainElem: is the pointer to sector history data structure to defrag *
* physicalBlockNumber: indicate the new phisical block number where *
* the valid data will be saved *
* newSector:indicate the sector that has caused the defrag operation*
* It is setted -1 if there is not *
* *
* RETURN VALUES *
* SUCCESS: the defrag has been executed *
* FAILURE : an error is occured *
* *
*******************************************************************************/
NFTL_Return MinimizeStructure(UINT16 *blockNumbers, UINT8 len, void *mainElem,
UINT16 physicalBlockNumber, INT8 newSector)
{
int i;
UINT8 Buffer[SECTOR_SIZE + BUFFER_SPARE_SIZE];
UINT8 tempBuffer[BUFFER_SPARE_SIZE];
//NFTL_Return result = FAILURE;
SectorMap SectorMRoot;
SectorMap SectorMLeaf;
SectorMap NewSectorMap;
UINT16 SourceBlock;
UINT8 SourcePage;
UINT8 SourceSector;
UINT8 NumPageWritten = 0;
UINT8 RootCounter = 0;
UINT8 NoSectorLeaf, NoSectorRoot;
UINT8 isInCache = 0;
UINT8 SectorNumber = 0;
//initialize SectorMap
SectorMLeaf.PhysicalBlockNumber = 0;
SectorMLeaf.OffsetValidation = -1;
SectorMRoot.PhysicalBlockNumber = 0;
SectorMRoot.OffsetValidation = -1;
NewSectorMap.PhysicalBlockNumber = physicalBlockNumber;
NewSectorMap.OffsetValidation = -1;
for (i = 0; i < MAX_SECTOR_NUMBER; i++)
{
SectorMRoot.Sector[i] = 0;
SectorMLeaf.Sector[i] = 0;
NewSectorMap.Sector[i] = 0;
}
#ifdef NFTL_DEBUG
if (physicalBlockNumber > UD_END_PARTITION)
return FAILURE;
if (blockNumbers == NULL)
return FAILURE;
if (pageInBlock == 0)
{
pageInBlock = 32;
}
#endif
if (FindSectorMap(blockNumbers[0],&SectorMRoot) != SUCCESS)
{
return FAILURE;
}
//the garbage involving two blocks, Root and Leaf
if (len > 1)
{
if (FindSectorMap(blockNumbers[1],&SectorMLeaf) != SUCCESS)
{
return FAILURE;
}
}
for (i = 0; i < MAX_SECTOR_NUMBER; i++)
{
SourceBlock = 0;
SourcePage = 0;
SourceSector = 0;
NoSectorLeaf = 1;
NoSectorRoot = 1;
if (i == newSector)
{
continue;
}
else
{
if ((SectorMLeaf.Sector[i] != 0) ||
((SectorMLeaf.OffsetValidation == i) && (SectorMLeaf.Sector[i] == 0)))
{
SourceBlock = SectorMLeaf.PhysicalBlockNumber;
SourcePage = SectorMLeaf.Sector[i];
SourceSector = i;
NoSectorLeaf = 0;
}
else
{
if ((SectorMRoot.Sector[i] != 0) ||
((SectorMRoot.OffsetValidation == i) && (SectorMRoot.Sector[i] == 0)))
{
SourceBlock = SectorMRoot.PhysicalBlockNumber;
SourcePage = SectorMRoot.Sector[i];
SourceSector = i;
NoSectorRoot = 0;
}
}//end else
}//end else (i == newSector)
if ((NoSectorRoot == 0) || (NoSectorLeaf == 0))
{
//if (ReadPage(SourceBlock,SourcePage,Buffer) != NAND_PASS)
if (Read(SourceBlock,SourcePage,Buffer) != NAND_PASS)
return FAILURE;
RootCounter = (Buffer[SECTOR_SIZE + ROOT_COUNTER_BYTE]);
//Set spare data of page
Buffer[SECTOR_SIZE + TREE_POSITION_BYTE] = ROOT_POSITION;
Buffer[SECTOR_SIZE + COPY_TREE_POSITION_BYTE] = ROOT_POSITION;
if (RootCounter == 255)
{
Buffer[SECTOR_SIZE + ROOT_COUNTER_BYTE] = 0;
}
else
{
RootCounter++;
Buffer[SECTOR_SIZE + ROOT_COUNTER_BYTE] = RootCounter;
}
//if (WritePage(physicalBlockNumber,NumPageWritten,Buffer) != SUCCESS)
if (Write528(physicalBlockNumber,NumPageWritten,Buffer) != SUCCESS)
{
return FAILURE;
}
SectorNumber = Buffer[SECTOR_SIZE + SECTOR_NUMBER] |
Buffer[SECTOR_SIZE + COPY_SECTOR_NUMBER]; //sudeep::Bug
if (NumPageWritten == 0)
{
NewSectorMap.OffsetValidation = SectorNumber;
}
NewSectorMap.Sector[SectorNumber] = NumPageWritten;
NumPageWritten++;
}
}
if (NumPageWritten != 0)
{
SetGCNumPageWritten(NumPageWritten - 1);
}
else
{
SetGCNumPageWritten(0);
//if (ReadPage(SectorMLeaf.PhysicalBlockNumber,0,Buffer)!= NAND_PASS)
if (Read(SectorMLeaf.PhysicalBlockNumber,0,Buffer)!= NAND_PASS)
return FAILURE ;
RootCounter = (Buffer[SECTOR_SIZE + ROOT_COUNTER_BYTE]);
//Set spare data of page
Buffer[SECTOR_SIZE + TREE_POSITION_BYTE] = ROOT_POSITION;
Buffer[SECTOR_SIZE + COPY_TREE_POSITION_BYTE] = ROOT_POSITION;
if (RootCounter == 255)
{
Buffer[SECTOR_SIZE + ROOT_COUNTER_BYTE] = 0;
}
else
{
RootCounter++;
Buffer[SECTOR_SIZE + ROOT_COUNTER_BYTE] = RootCounter;
}
//if (WritePage(physicalBlockNumber,NumPageWritten,Buffer) != SUCCESS)
if (Write528(physicalBlockNumber,NumPageWritten,Buffer) != SUCCESS)
{
return FAILURE;
}
SectorNumber = Buffer[SECTOR_SIZE + SECTOR_NUMBER] |
Buffer[SECTOR_SIZE + COPY_SECTOR_NUMBER]; //sudeep::Bug
if (NumPageWritten == 0)
{
NewSectorMap.OffsetValidation = SectorNumber;
}
NewSectorMap.Sector[SectorNumber] = NumPageWritten;
NumPageWritten++;
}
//angelo bug
for (i = 0; i < len; i++)
{
if (CopyAndEraseSectorMapToCache(blockNumbers[i],&NewSectorMap) == SUCCESS)
{
isInCache = 1;
}
}
OS_MemSet(tempBuffer,0xFF,BUFFER_SPARE_SIZE);
tempBuffer[INVALID_BLOCK_BYTE] = 0x00;
for (i = 0; i < len; i++)
{
if (SetPageStatus(blockNumbers[i],1,tempBuffer) != SUCCESS)
{
return FAILURE;
}
AddInvalidBlock(blockNumbers[i]);
}
if (isInCache == 0)
{
IncrementIndexCache();
SetSMFreeCache(GetSMIndexCache(),1);
CopySectorMap(NewSectorMap,GetSMIndexCache());
}
SetSMUsedBlocks(GetSMUsedBlocks() + 1);
return SUCCESS;
}
UINT16 GetGCNumPageWritten()
{
return NumPageWritten;
}
void SetGCNumPageWritten(UINT16 value)
{
NumPageWritten = value;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -