davpagerecl.c

来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,381 行 · 第 1/4 页

C
1,381
字号

   numberBlocks = rtEndBlock2 - rtStartBlock + 1;
   status = CFGTBL_Allocate_RTTBL(rtEndBlock2, numberBlocks, &rtOprRequired[0]);
   if(status != ERR_NONE)
   {
      return status;
   }

   return status;
}

 /*#################################################################
  ### RECLAIM_PAGE_AnyFreeOrDirtyOrWipHeaders
  ###
  ### DESCRIPTION:
  ###    This function performs a work to do search to determine if
  ###    there is something for the page reclaim to to do.
  ###
  ### PARAMETERS:
  ###   aRef -- IN: Parameter used throughout the page reclaim.
  ###
  ### 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 RECLAIM_PAGE_AnyFreeOrDirtyOrWipHeaders(PAGE_RECLAIM_Address* aRefPtr)
{
   ERR_CODE           status = ERR_NONE;

   SEARCH_SearchInfo  infoResult;
   SEARCH_CompareInfo compare_info;
   HDR_Header         hdrhdr;
   BOOLEAN            foundInvalid = FALSE;

   infoResult.CurrObj.HeaderAddress = 0;
   infoResult.CurrObj.ObjectAddress = 0;
   infoResult.CurrObj.ObjectSize    = 0;
   infoResult.HeaderPtr             = &hdrhdr;

   /* Get headers from normal paragraph area */
   status = SEARCH_GetNextHeader(&infoResult, SEARCH_ByNextObject, &compare_info, aRefPtr->plrRestart);

   while(status != ERR_NO_MORE_ENTRIES)
   {
      /* Is the header valid? */
      if(FHDR_GetHeaderStatus(&infoResult.HeaderPtr->FHdr) == HDR_HEADER_VALID)
      {
         if(FHDR_GetAllocationStatus(&infoResult.HeaderPtr->FHdr) == HDR_ALLOC_WRITE_IN_PROGRESS)
         {
            status = ERR_NODEFRAGWHILEWIP;
            break;
         }

         /* Yes. Is this a normal object? */
         if (FHDR_GetType(&infoResult.HeaderPtr->FHdr) == FDI_HT_NormalObject)
         {
            if(
              (FHDR_IsDirtyChunk(&infoResult.HeaderPtr->FHdr) == TRUE) ||
              (FHDR_IsFreeChunk(&infoResult.HeaderPtr->FHdr)  == TRUE)
              )
            {
               foundInvalid = TRUE;
            }
         }
      }
      status = SEARCH_GetNextHeader(&infoResult, SEARCH_ByNextObject, &compare_info, aRefPtr->plrRestart);
   }

   if(status == ERR_NO_MORE_ENTRIES)
   {
      if(foundInvalid == FALSE)
      {
         return ERR_NOTNEEDED;
      }
      status = ERR_NONE;
   }

   return status;

}

 /*#################################################################
  ### RECLAIM_PAGE_ValidateBackupSpace
  ###
  ### DESCRIPTION:
  ###    This function validates that there is enough memory space
  ###    to provide a backup for the reallocation object. If the
  ###    the defrag is not started.
  ###
  ### PARAMETERS:
  ###   aRef          - IN: Parameter used throughout the page reclaim.
  ###
  ### 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 RECLAIM_PAGE_ValidateBackupSpace(PAGE_RECLAIM_Address* aRef)
{
   ERR_CODE           status = ERR_NONE;

   FDI_Handle         backupHandle;
   UINT32             NumAvailablePages;

   SEARCH_SearchInfo  result;
   SEARCH_CompareInfo compare_info;
   HDR_Header         hdrhdr;

   /* Find all headers that are backups */
   result.CurrObj.HeaderAddress = 0;
   result.CurrObj.ObjectAddress = 0;
   result.CurrObj.ObjectSize    = 0;
   result.HeaderPtr             = &hdrhdr;
   status = SEARCH_GetNextHeader(&result, SEARCH_ByNextValidPageObject, &compare_info, FALSE);
   while (status != ERR_NO_MORE_ENTRIES)
   {
      /* Did we get something? */
      if(status == ERR_NONE)
      {
         /* Yes. Is this a backup? */
         if(FHDR_GetReallocationStatus(&result.HeaderPtr->FHdr) != HDR_REALLOC_BACKUP_COMPLETE)
         {
            /* Yes. Doe it match our relocate object? */
            if(result.CurrObj.ObjectAddress == aRef->relocObjHandle)
            {
               /* Yes. This is the object that will be backed up or invalidated */
               break;
            }
         }
      }
      status = SEARCH_GetNextHeader(&result, SEARCH_ByNextValidPageObject, &compare_info, FALSE);
   } /* while */

   /* Compute memory space */
   status = MEM_FindLargestUnpinnedFreeChunkInPageSpace(&backupHandle, &NumAvailablePages);
   if (status != ERR_NO_MORE_ENTRIES)
   {
      if(status != ERR_NONE)
      {
         return status;
      }
   }

   /* compare the available size */
   if(NumAvailablePages < FHDR_GetSize(&result.HeaderPtr->FHdr))
   {
      status = ERR_FLASH_FULL;
   }

   return status;
}

 /*#################################################################
  ### RECLAIM_PAGE_RemoveAllFreeChunckAtTopOfMemory
  ###
  ### DESCRIPTION:
  ###    This function performs does harmeless prework by release
  ###    free on top of the page space.
  ###
  ### PARAMETERS:
  ###   aRef -- IN: Parameter used throughout the page reclaim.
  ###
  ### 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 RECLAIM_PAGE_RemoveAllFreeChunckAtTopOfMemory(PAGE_RECLAIM_Address* aRefPtr)
{
   ERR_CODE status = ERR_NONE;

   FDI_Handle      handle;
   BOOLEAN         moreFreeChuncks = TRUE;
   HDR_FixedHeader fixHeader;

   UTIL_ClearVariable((UINT8*)&fixHeader, sizeof(HDR_FixedHeader), 0xFF);

   /* Start with the last header */
   status = SEARCH_CalcLastUserObjectHdrAddr(&handle);
   if(status != ERR_NONE)
   {
      return status;
   }
 
   while(moreFreeChuncks == TRUE  &&  status != ERR_NO_MORE_ENTRIES)
   {
      status = FHDR_ReadFixedHeader(handle, &fixHeader, aRefPtr->plrRestart);
      if(status != ERR_NONE)
      {
         return status;
      }

      if(FHDR_IsFreeChunk(&fixHeader) == TRUE)
      {
         status = FHDR_AbsorbedHeaderInFlash(handle, &fixHeader);
         if (status)
         {
            return status;
         }

         /* When we absorbe, the search is put in an unknown state. Start over. */
         status = SEARCH_CalcLastUserObjectHdrAddr(&handle);
         if(status != ERR_NONE)
         {
            return status;
         }
      }
      else
      {
         /* We stop at the first non-free chunck */
         status = ERR_NO_MORE_ENTRIES;
      }

   } /* while */

   status = ERR_NONE;
   return status;
}

/*=================================== RECLAIM =============================*/
 /*#################################################################
  ### RECLAIM_PAGE_CopyOutObjectsToBlock
  ###
  ### DESCRIPTION:
  ###    This function performs does the acutal copy for a single
  ###    block. What is copied is defined in the ott table.
  ###
  ### PARAMETERS:
  ###   aRef    - Parameter used throughout the page reclaim.
  ###   rtIndex - The current single block.
  ###   aBlockBaseHandle - The bottom address to copy to
  ###   aOttIndexPtr     - The current index in the ott table
  ###   aOttIndexLast    - The last index int the ott table
  ###   aRtWriteCnt      - The number of writes we did.
  ###
  ### RETURNS:
  ###   When this function passes with no errors a value of 0 is
  ###   returned otherwise, it returns a status of type ERR_CODE.
  ###*/
/*Fix Start:SCR964 */
ERR_CODE RECLAIM_PAGE_CopyOutObjectsToBlock(PAGE_RECLAIM_Address* aRef, UINT16 rtIndex,
   FDI_Handle aBlockBaseHandle, UINT16* aOttIndexPtr, UINT16 aOttIndexLast, UINT16* aRtWriteCnt)
/*Fix End:SCR964 */
{
   ERR_CODE status;

   FDI_Handle      srcHandle;
   OTTTBL_EntryPtr ottEntryPtr;
   UINT32          ottTotalBytes = 0;
   UINT32          ottBytesProcessed = 0;
   UINT32          ottBytesCurrent = 0;
   UINT32          ottBytesRemaining = 0;

   FDI_Handle      dstHandle;
   UINT32          blockBytesSent = 0;
   UINT16          objHeaderToSend = 0;

   /* Write each object in the block to another block */
   blockBytesSent      = 0;

   /* Keep looping until we fill up the block   */
   /* We will exit within the while if,         */
   /* - No more bytes from an ott entry can fit */
   /* - No more ott entries for this block      */
   while(blockBytesSent < DAV_BLOCK_SIZE)
   {
      /* Get an OTT entry */
      ottEntryPtr     = &aRef->sramOttEntriesList[*aOttIndexPtr];

      /* Compute how many bytes we can send from the object*/
      ottTotalBytes   = OTTTBL_CalcDestinationBytesInBlock(ottEntryPtr, 
         rtIndex, &ottBytesProcessed, &ottBytesCurrent, &ottBytesRemaining);
      objHeaderToSend = 0;

      /* Compute the src and dst handle */
      srcHandle   = OTTTBL_CalcSourceHandle(ottEntryPtr) + ottBytesProcessed;
      dstHandle   = aBlockBaseHandle + blockBytesSent;
     
      /* COPY OBJECT */
      switch(OTTTBL_GetOttEntryType(ottEntryPtr))
      {
         /* Dirty and Free objects are not copied */
         case OTTTBL_OttEntryType_DirtyChunk:
         case OTTTBL_OttEntryType_FreeChunk:
            /* We need to count these as if we did */
            *aRtWriteCnt = *aRtWriteCnt + 1;
            break;
         /* Objects are copied */
         case OTTTBL_OttEntryType_UserObject:
            /* If the is object is pinned only to be erased */
            switch(OTTTBL_GetOttEntryPinStatus(ottEntryPtr))
            {
            case OTTTBL_OttEntryPinStatus_PinnedForErase:
               /* Computation to only to preserve the object header */
               if(ottBytesProcessed > 0)
               {
                  /* The header was in one the last blocks */
                  /* Due to page alignment, the header will never split across blocks */
                  /* Therefore, we know we got the entire header, Do not copy anymore */
                  objHeaderToSend = 0;
               }
               else if(ottBytesCurrent >= sizeof(HDR_ObjectHeader))
               {
                  /* The entire header is withing this block */
                  /* Preserve original header                */
                  objHeaderToSend = sizeof(HDR_ObjectHeader);
               }

               /* Copy on the object header */
               if(objHeaderToSend > 0)
               {
                  status    = FLASH_CopyFlash(srcHandle, dstHandle, objHeaderToSend); 
                  if(status != ERR_NONE)
                  {
                     return status;
                  }
               }
               break;
            case OTTTBL_OttEntryPinStatus_NotPinned:
            case OTTTBL_OttEntryPinStatus_Pinned:
               /* Copy user objects */
               /* Because we are pinned, does not mean we do not have anything to copy. */
               /* We see the portion that is not pinned */
               status    = FLASH_CopyFlash(srcHandle, dstHandle, ottBytesCurrent); 
               if(status != ERR_NONE)
               {
                  return status;
               }
               break;
            default:
               /* We should not get this */
               return ERR_STATE;
               break;
            } /* switch */
            *aRtWriteCnt = *aRtWriteCnt + 1;
            break;
         default:
            return ERR_STATE;
            break;
      } /* switch */


      /* Increment next ott entry */
      if(ottBytesCurrent == ottTotalBytes)
      {
         /* FULL OBJECT */
         *aOttIndexPtr = *aOttIndexPtr + 1;
      }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?