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 + -
显示快捷键?