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

📄 fdi_recl.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300c0000 */);
         break;
      }
      /*
       * write the logical block number of the reclaim block into the spare's
       * block information logical_block_number field
       */
      errors = FlashDevWrite((BYTE_PTR)&block_info.logical_block_number,
                            Rip.spare_block_addr + BOTTOM_OF_UNITS +
                            offsetof(BLOCK_INFO, logical_block_number),
                            mFDI_MemberSize(BLOCK_INFO, logical_block_number));

      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300d0000 */);
         break;
      }
      /* if we are reclaiming a block because of wear leveling, we want to */
      /* increment more than one because otherwise we could get into a */
      /* situation where we are wear leveling often. Need to give space */
      /* for natural wear leveling to begin again. */

      if ((most_erased_count - block_info.erase_count) > WEARLEVELING_LIMIT)
         block_info.erase_count += RECL_WEARLEVEL_DIFFERENTIAL;
      else
         block_info.erase_count++;     /* increment the erase count before */
      /*
       * write the reclaim block's erase count into the spare's block
       * information physical_erase_count field
       */
      errors = FlashDevWrite((BYTE_PTR) & block_info.erase_count,
                            Rip.spare_block_addr + BOTTOM_OF_UNITS +
                            offsetof(BLOCK_INFO, physical_erase_count),
                            mFDI_MemberSize(BLOCK_INFO, physical_erase_count));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300e0000 */);
         break;
      }
      /*
       * Prepare to erase the reclaim block by marking the spare block
       * BLK_ERASING.
       */
      /* write the spare block's block information status field to 'erasing' */
      block.status = BLK_ERASING;      /* set the status to 'erasing' */

      errors = FlashDevWrite(&block.status,
                             Rip.spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, status),
                             mFDI_MemberSize(BLOCK_INFO, status));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300f0000 */);
         break;
      }
      /*
       * NOTE!!!!: We will update the LogicalBlockTable here so that other
       * processes can use the data in the spare block while the reclaim block
       * is being erased....
       */
#if (CONSISTENT_ACCESS_TIME == TRUE) 
      /* wait for DLT access */
      SEM_MTX_WAIT(SEM_LookupTable);
#endif 
      SEM_MTX_WAIT(SEM_BlockTable);    /* wait for block table access */


#if (CONSISTENT_ACCESS_TIME == TRUE)
      /* update DLT */
      errors = FlashDevUpdateDLT(Rip.spare_block_addr);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30150000 */);
         break;
      }
#endif

      /*
       * update the physical_block_number field of the FDI_LogicalBlockTable
       * with the spare's physical block number
       */
      FDI_LogicalBlockTable[this_blk.logical_block].physical_block_number =
       FDI_SpareBlock;
      /*
       * update the free_space field of the FDI_LogicalBlockTable with spare's
       * free space
       */
      FDI_LogicalBlockTable[this_blk.logical_block].free_space = (Rip.spare_free /
                                                              sizeof(DWORD));

      /* initialize the dirty_space field of the FDI_LogicalBlockTable */
      FDI_LogicalBlockTable[this_blk.logical_block].dirty_space =
       (Rip.spare_dirty / sizeof(DWORD));

      /* Set the last_header_offset field of LBT */
      SET_LAST_HEADER_OFFSET(this_blk.logical_block, Rip.spare_header_offset);
      /*
       * assign FDI_SpareBlock global variable to the reclaim block's physical
       * block number
       */
      FDI_SpareBlock = RECL_ReclaimBlock;

      SEM_MTX_POST(SEM_BlockTable);    /* finished with block table access */

#if (CONSISTENT_ACCESS_TIME == TRUE)
      SEM_MTX_POST(SEM_LookupTable);
#endif

      SEM_MTX_WAIT(SEM_WriteInProg);   /* pend on writes in progress */
      SEM_MTX_WAIT(SEM_OpenStream);    /* Take the open stream semaphore */
      for(index =0; index < OPEN_ARRAY_SIZE; index++)
      {
        if(FDI_OpenParam[index].identifier == WORDMAX)
          continue;
        RIP_OpenStreamUpdate(&FDI_OpenParam[index]);
      }
      SEM_MTX_POST(SEM_OpenStream);    /* Give the open stream semaphore */
      SEM_MTX_POST(SEM_WriteInProg);   /* finished blocking writes */

      RECL_SetState(RECL_ERASING);     /* reclaim state flag */
      /*
       * reset these globals to keep the background from using them even when
       * reclaim has finished.
       */
      Rip.recl_in_prog_flag = FALSE;   /* done with the copy phase */
      reclaim_block_addr = Rip.reclaim_block_addr; /* save local copy */
      Rip.reclaim_block_addr = DWORDMAX;
      spare_block_addr = Rip.spare_block_addr;  /* save local copy */
      Rip.spare_block_addr = DWORDMAX;
      Rip.reclaim_header_offset = FIRST_HEADER_OFFSET;

      /*invalidate the reclaim block's integrity */
      block_info.current_state = BLK_INTEGRITY_INVALID;
      errors = FlashDevWrite((BYTE_PTR) & block_info.current_state,
                             reclaim_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, current_state),
                             sizeof(block_info.current_state));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30100000 */);
         break;
      }

      SEM_MTX_POST(SEM_ReclaimInProg); /* finished blocking writes */


      /* ERASE the reclaim block now.... ############################### */
      errors = FlashDevEraseBlock(reclaim_block_addr);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30110000 */);
         break;
      }

      /* write spare block's block information status field to 'updating' */
      block.status = BLK_UPDATING;     /* set the status to 'updating' */
      errors = FlashDevWrite(&block.status,
                             spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, status),
                             mFDI_MemberSize(BLOCK_INFO, status));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30120000 */);
         break;
      }
      /*
       * update the spare block erase count in the parameter where it is
       * maintained
       */
      errors = WriteData((BYTE_PTR) & block_info.erase_count, 0,
                         ERASE_COUNT_ID, sizeof(DWORD), ERASE_COUNT_TYPE,
                         WRITE_REPLACE);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30130000 */);
         break;
      }

      /* write the spare block's block information status field to 'write' */
      block.status = BLK_WRITE;        /* set the status to 'write' */
      errors = FlashDevWrite(&block.status,
                             spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, status),
                             mFDI_MemberSize(BLOCK_INFO, status));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30140000 */);
         break;
      }

      /* read the reclaim block's block information */

      /*
       * Unlock the ReclaimDone semaphore for the background task to know that
       * the reclamation has completed.
       */
      RECL_ReclaimBlock = WORDMAX;
      RECL_SetState(RECL_DONE);        /* state flag */
#ifdef TEST_MSGS
      logMsg("reclaim done\n", 0, 0, 0, 0, 0, 0);
#endif
      SEM_POST(RECL_Done);


#ifdef TIMING
      /* Get timestamp for start of update */
      COMM_getTimestamp(&RECL_End);
   #ifdef writeToFile
      fprintf(rw,"time to reclaim block %d is %1.0d usecs \n",
       FDI_SpareBlock, ((int)(RECL_End.low - RECL_Start.low)) * 163);
   #endif
#ifdef TEST_MSGS

      logMsg("time to reclaim block %d is %d ticks\n",
             FDI_SpareBlock, (int) (RECL_End.low - RECL_Start.low),
             0, 0, 0, 0);
#endif
#endif

   }                                   /* ENDDO FOREVER */

   RECL_TaskId = 0;
   RECL_SetState(RECL_BAILED);         /* state flag */
#ifdef TEST_MSGS
   logMsg("reclaim bailed! reclm %d spare %d error %d\n", RECL_ReclaimBlock,
          FDI_SpareBlock, (int) errors, 0, 0, 0);
#endif

}                                      /* END FDI_Reclamation */


/*############################################################################
 *### RIP_Write
 *###
 *### DESCRIPTION: writes unit or header information replacing FlashDevWrite.
 *###              If reclaim is in progress and reclaim has already reclaimed
 *###              the write_header_addr location, this function will write to
 *###              the spare block at the appropriate location using the
 *###              countBitMask function.
 *###
 *### PARAMETERS:
 *###    IN:
 *###       write_header_addr - address to beginning of unit header
 *###       write_unit_addr   - address to beginning of unit
 *###       data_buf_ptr      - pointer to the raw data to be written
 *###       write_offset      - byte offset from beginning of header or unit
 *###       data_size         - number of bytes to write
 *###    OUT:
 *###
 *### RETURNS:
 *###    Returns the following errors codes:
 *###       HW_ERR_NONE
 *###       HW_ERR_SYSTEM
 *###*/
HW_ERROR
RIP_Write(BYTE_PTR data_ptr,
          DWORD write_header_addr,
          DWORD write_unit_addr,
          DWORD write_offset,
          WORD data_size)
{
   UNIT_HEADER header;                 /* contains unit header information */
   DWORD write_block_addr;             /* first address of the block */
   WORD write_header_offset;           /* address less the block address */
   WORD header_count;                  /* tracks the number of headers */
   HW_ERROR status = HW_ERR_NONE;
   /*
    * test for input error
    */
   if (!write_unit_addr && (write_offset > sizeof(UNIT_HEADER)))
      return HW_ERR_PARAM;

   /* get target block address of this write */
   write_block_addr = write_header_addr & (DWORD) (~(FDV_BLOCK_SIZE - 1));
   /* get header offset of this write */
   write_header_offset = (write_header_addr - write_block_addr);
   /*
    * IF the reclaim process is busy copying from the reclaim block to the
    * spare block AND if the reclaim is the target block for this write AND if
    * we need to write to both the spare and reclaim block if reclaim is ahead
    * of this write.
    */
   if ((Rip.recl_in_prog_flag == TRUE) &&
       (write_block_addr == Rip.reclaim_block_addr) &&
       (write_header_offset < Rip.reclaim_header_offset))
   {
      /*
       * count the number of headers where this identifier exists in the spare
       * block
       */
      header_count = countBitMask(Rip.recl_header_mask,
                                  (WORD)write_header_offset /
                                  sizeof(UNIT_HEADER));
      /* write to unit data if write_data_addr is not zero */
      if (write_unit_addr)
      {
         status = FlashDevWrite(data_ptr, write_unit_addr + write_offset,
                                data_size);
         if (status == HW_ERR_NONE)
         {
            /*jad could use a variable for g_unit_offset_bottom rather than header struc */

            /* read the unit header in the spare block */
            status = FlashDevRead((BYTE_PTR) & header,
                                  Rip.spare_block_addr + FIRST_HEADER_OFFSET +
                                  (header_count * sizeof(UNIT_HEADER)),
                                  sizeof(UNIT_HEADER));
            if (status == HW_ERR_NONE)
            {
/* E.5.0.591 Begin */
               status = FlashDevWrite(data_ptr, Rip.spare_block_addr +
                                      (((FDV_BLOCK_SIZE - sizeof(BLOCK_INFO)) -
                                      TO_BYTES(header.g_unit_offset_bottom)) +
                                      write_offset), data_size);
/* E.5.0.591 End */
            }                          /* ENDIF spare header read okay */
         }                             /* ENDIF reclaim blk unit write okay */
      }                                /* ENDIF this is a unit write */
      /* else write to the unit header */
      else
      {
         status = FlashDevWrite(data_ptr, write_header_addr + write_offset,
                                data_size);
         if (status == HW_ERR_NONE)
         {
/* E.5.0.591 Begin */
            status = FlashDevWrite(data_ptr,
                                   Rip.spare_block_addr + ((FIRST_HEADER_OFFSET +
                                   (header_count * sizeof(UNIT_HEADER))) +
                                   write_offset), data_size);
/* E.5.0.591 End */
         }
      }                                /* ENDIF reclaim blk header write ok */
   }                                   /* ENDIF recl_in_prog_flag == TRUE */
   /*
    * ELSE reclaim is not copying data; write normally
    */
   else

⌨️ 快捷键说明

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