⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 davbkup.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 1995-2004 Intel Corporation */
/* Intel Confidential                        */

/* ###########################################################################
###  BKUP
###
###  Module: davbkup.c - functions for allocating and creating object backups
###
###  $Workfile: davbkup.c $
###  $Revision: 11 $
###  $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 "DavLib.h"

#if (DIRECT_ACCESS_VOLUME == TRUE)

#include "davext.h"
#include "davbkup.h"

/*### Local Declarations
#########################*/

/*### Global Declarations
#########################*/

/*### Local Functions
#########################*/

#define ExitOnError(status) \
   if (status != ERR_NONE) \
   {  return status;  }

/* E5.5.962 Begin */   
#define CleanupAndExitOnError(status)   \
   if(status != ERR_NONE)               \
   {                                    \
      mDEBUG_CHECK_ERRCODE(status)      \
      MEM_CalcMemoryStatistics(FALSE);  \
      return status;                    \
  }
/* E5.5.962 End */ 

/*### Global Functions
#########################*/

 /*#################################################################
  ### BKUP_FindBackupFreeChunk
  ###
  ### DESCRIPTION:
  ###   This function finds a contiguous area of free space in page
  ###   space for backup operations.  It will, if needed, create
  ###   free chunks in order to block-align the backup area if
  ###   requested or if a pinning issue exists.
  ###
  ### PARAMETERS:
  ###   aRequestedSizeInPages -- size of chunk needed for backup
  ###   aHandlePtr  -- OUT: a handle to the backup area
  ###   aBlockAlign -- flag to indicate if block alignment is preferred.
  ###   restart     -- Flag used to for PLR.
  ###
  ### 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 BKUP_FindBackupFreeChunk( UINT32 aRequestedSizeInPages, 
                                   FDI_HandlePtr aHandlePtr, 
                                   BOOLEAN aBlockAlign,
                                   BOOLEAN restart)
{
   ERR_CODE status = ERR_NONE;
   FDI_Handle freePoolHandle;
   UINT32 freePoolOffset;
   FDI_Handle blockAlignedFreePoolHandle;
   UINT32 freePoolSizeInPages;
   UINT32 blockAlignedFreePoolSizeInPages;

   FDI_Handle freeChunkHandle;
   UINT32 freeChunkOffset;
   UINT32 freeChunkEndOffset;
   UINT32 freeChunkFirstBlock;
   UINT32 freeChunkLastBlock;
   FDI_Handle blockAlignedFreeChunkHandle;
   UINT32 blockAlignedFreeChunkOffset;
   UINT32 freeChunkSizeInPages;
   UINT32 blockAlignedFreeChunkSizeInPages;

   SEARCH_SearchInfo  searchInfo;
   SEARCH_CompareInfo compareInfo;

   /* initialize the returned handle to an invalid address */
   *aHandlePtr = FDI_InvalidObjAddress;

	/* FIRST and SECOND CHOICES: use the free pool */
	/* get the FreePoolHandle and FreePoolSize */
   status = MEM_CalcSizeAndHandleOfFreePoolInPageSpace(&freePoolSizeInPages, &freePoolHandle);
   ExitOnError(status);

	/* if FreePoolSize >= aRequestedSize */
   if (freePoolSizeInPages >= aRequestedSizeInPages)
   {
      /* if the free pool isn't block aligned and (block alignment was requested or free pool is pinned) */
      freePoolOffset = (freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize;
      if (((freePoolOffset*FDI_PageSize) % FDI_BlockSize) != 0 && 
         (aBlockAlign == TRUE || (PIN_LIST_IsObjectPinned((freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize, 1) != enNotPinned)))
      {
         /* if the free pool spans more than one block boundary, see */
         /*   if we can align on the next block boundary and use it  */
         if ((freePoolSizeInPages*FDI_PageSize) > FDI_BlockSize)
         {
	   	   /* compute adjustedFreePoolHandle based on next block boundary */
            blockAlignedFreePoolHandle = FDI_FirstObjectAddress + 
               ((UTIL_CalcBlockNumberForOffset(freePoolOffset)+1) * FDI_BlockSize);
		      /* compute adjustedFreePoolSize based on new handle */
            blockAlignedFreePoolSizeInPages = 
               (FDI_ParaSpaceAddressBottom - blockAlignedFreePoolHandle) / FDI_PageSize;
		      /* if adjustedFreePoolSize > aRequestedSize */
            if (blockAlignedFreePoolSizeInPages > aRequestedSizeInPages)
            {
			      /* FIRST CHOICE */
			      /* would prefer contiguous free chunk in free pool, */
			      /*   the beginning of which is aligned on a block boundary */
				   /* create free chunk header to hold space between */
               /*   current free pool start and the block boundary */
               *aHandlePtr = blockAlignedFreePoolHandle;
               /* create a free chunk to fill in between the last object */
               /*   and the beginning of the block-aligned free pool     */
               FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;                    
               FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
               status = FHDR_CreateFreeChunkHeader(
                            FDI_LastHeaderEntry,
                            freePoolOffset, 
                            freePoolSizeInPages - blockAlignedFreePoolSizeInPages);
               ExitOnError(status);
            }
            else
            {
			      /* SECOND CHOICE */
			      /* if first choice not available, can we use the free pool as-is? */
			      /* only if last object in page space isn't pinned */
               if (PIN_LIST_IsObjectPinned((freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize, 1) == enNotPinned)
               {
                  /* *aFreeChunkHandlePtr = FreePoolHandle */
                  *aHandlePtr = freePoolHandle;
               }/* end if */
            }
         }
         else
         {
            /* SECOND CHOICE */
            /* free pool is less than a single block in size, but */
            /*   the size is big enough, if it's not pinned       */
            if (PIN_LIST_IsObjectPinned((freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize, 1) == enNotPinned)
            {
               /* *aFreeChunkHandlePtr = FreePoolHandle */
               *aHandlePtr = freePoolHandle;
            }/* end if */
         }
      }
      else
      {
			/* FIRST CHOICE */
			/* The free pool is block aligned, and it's big enough, so */
         /*   use it as is.  Since it's block aligned, we don't have */
         /*   to worry about pinning. */
         /* *aFreeChunkHandlePtr = FreePoolHandle */
         *aHandlePtr = freePoolHandle;
      }/* end if */
   }/* end if */

   /* if we couldn't get a good handle from the free pool, */
   /*   then try a free chunk within page space            */
   if (*aHandlePtr == FDI_InvalidObjAddress)
   {
	   /* look for an unpinned free chunk in page space that fits the requested size */
	   status = MEM_FindLargestUnpinnedFreeChunkInPageSpace(&freeChunkHandle, &freeChunkSizeInPages);
      ExitOnError(status);
      if (freeChunkSizeInPages >= aRequestedSizeInPages)
      {
         /* if the free chunk spans a block boundary and isn't block aligned and block alignment was requested */
         freeChunkOffset = (freeChunkHandle-FDI_FirstObjectAddress) / FDI_PageSize;
         freeChunkEndOffset = freeChunkOffset+freeChunkSizeInPages;
         freeChunkFirstBlock = UTIL_CalcBlockNumberForOffset(freeChunkOffset);
         freeChunkLastBlock = UTIL_CalcBlockNumberForOffset(freeChunkOffset+freeChunkSizeInPages - 1);
         if ((freeChunkFirstBlock < freeChunkLastBlock) && 
            (((freeChunkOffset*FDI_PageSize) % FDI_BlockSize) != 0) && aBlockAlign == TRUE)
         {
	   	   /* compute adjustedFreeChunkHandle based on next block boundary, */
            blockAlignedFreeChunkHandle = FDI_FirstObjectAddress + 
               ((freeChunkFirstBlock+1) * FDI_BlockSize);
		      /* compute adjustedFreeChunkSize based on new handle */
            blockAlignedFreeChunkSizeInPages = freeChunkSizeInPages - ((blockAlignedFreeChunkHandle - freeChunkHandle) / FDI_PageSize);
            if (blockAlignedFreeChunkSizeInPages >= aRequestedSizeInPages)
            {
			      /* THIRD CHOICE */
			      /* use a block-aligned free chunk in the page space */
               *aHandlePtr = blockAlignedFreeChunkHandle;

               blockAlignedFreeChunkOffset = (blockAlignedFreeChunkHandle - FDI_FirstObjectAddress) / FDI_PageSize;

               /* find the original free chunk header */
               SEARCH_Header2SearchInfo((&searchInfo), (&FDI_SearchHeader));
               compareInfo.CompareValue = freeChunkHandle;                   
               compareInfo.NamePtr      = 0;
               compareInfo.NameSize     = 0;
               status = SEARCH_GetNextHeader(&searchInfo, SEARCH_ByObjectHeaderAddress, &compareInfo, FALSE); 
               if (status == ERR_NONE)
               {
                  /* Found an existing object, but is it a free chunk? */
                  if (FHDR_GetAllocationStatus(&(searchInfo.HeaderPtr->FHdr)) != HDR_ALLOC_EMPTY)
                  {
                     status = ERR_STATE;
                     ExitOnError(status);
                  }
                  /* mark the original free chunk as absorbing */
                  status = FHDR_AbsorbingHeaderInFlash(
                     searchInfo.CurrObj.HeaderAddress,
                     &(searchInfo.HeaderPtr->FHdr));
                  ExitOnError(status);
               }
               else
               {
                  /* couldn't find a header, so something is corrupted */
                  status = ERR_STATE;
                  ExitOnError(status);
               }

               /* create two new free chunk headers to replace the original */
               FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;                    
               FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
               status = FHDR_CreateFreeChunkHeader(
                            FDI_LastHeaderEntry,
                            freeChunkOffset, 
                            freeChunkSizeInPages - blockAlignedFreeChunkSizeInPages);
               ExitOnError(status);

               FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;                    
               FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
               status = FHDR_CreateFreeChunkHeader(
                            FDI_LastHeaderEntry,
                            blockAlignedFreeChunkOffset, 
                            blockAlignedFreeChunkSizeInPages);
               ExitOnError(status);

               /* mark the original free chunk as absorbed */
               status = FHDR_AbsorbedHeaderInFlash(
                  searchInfo.CurrObj.HeaderAddress,
                  &(searchInfo.HeaderPtr->FHdr));
               ExitOnError(status);
            }
            else
            {
			      /* FOURTH CHOICE */
			      /* if first choice not available, use the free chunk as is */
			      /* if last object in page space isn't pinned */
               *aHandlePtr = freeChunkHandle;
            }
         }
         else
         {
			   /* FOURTH CHOICE */
			   /* either the free chunk doesn't span a block boundary, */
            /*   or it's already block aligned.  Use it as-is.      */
            *aHandlePtr = freeChunkHandle;
         }/* end if */
      }/* end if */
   }/* end if */

   /* at this point, if we haven't got a good handle, */
   /*   then we've run out of options                 */
   if (*aHandlePtr == FDI_InvalidObjAddress)
   {
      status = ERR_NO_MORE_ENTRIES;
   }

   return status;
}

/*#################################################################
  ### BKUP_CreateBackupObject
  ###
  ### DESCRIPTION:
  ###   This function creates a backup copy (including header) of
  ###   the object specified by the search info parameter.
  ###
  ### PARAMETERS:
  ###   aSearchInfo -- search structure containing information
  ###                  about the object to be backed up.  This
  ###                  must be initialized prior to calling this
  ###                  function.
  ###   aBkupHandle -- location in page space to create the backup.
  ###   restart     -- Flag used to for PLR.

⌨️ 快捷键说明

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