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

📄 fdi_int.c

📁 Flash file system
💻 C
📖 第 1 页 / 共 5 页
字号:
                  /* Round the size up to the nearest granularity */
                  *data_size_ptr = TO_BYTES(TO_SIZE(*data_size_ptr,
                     UNIT_GRANULARITY));
               }

               found = APPEND_IN_Q;

            }
            /*
             * If a delete of matching id, and type is pending set the flag to
             * true
             */
            else if (command_ptr->sub_command == WRITE_DELETE)
            {
               *data_size_ptr = 0;
               found = DELETE_IN_Q;
            }
            else
               found = REPLACE_IN_Q;
         }
      }
      if (((found & FOUND_IN_Q_MASK) != 0) || (found == NONE_IN_Q))
         break;
   }

   if ((*data_size_ptr != 0) || (found == DELETE_IN_Q))
      return ERR_NONE;

   SEM_MTX_WAIT(SEM_LookupTable);
   /*
    * Get the physical block address and the header offset from the
    * FDI_DataLookupTable.
    */
   hw_status = LookupToHeader(&block_address, &unit_address,
                              &header_offset,
                              &unit_header_buffer, & index,
                              identifier, type);


   if (hw_status == HW_ERR_NONE)
   {
      /*
       * Calculate the address of the unit that the unit header points to, and
       * read the unit header information into a buffer.
       */
      if (NIBBLE_LOW(unit_header_buffer.type_attribute) ==
          ATTR_SINGL_INST)
      {
         /*
          * If the data attribute is single instance unit, return the unit
          * size in bytes as the total data size.
          */
         *data_size_ptr = unit_header_buffer.g_unit_size * UNIT_GRANULARITY;
      }
      else if (NIBBLE_LOW(unit_header_buffer.type_attribute) ==
               ATTR_MULTI_INST)
      {

         /* Read the multiple instance structure. */
         if (FlashDevRead((BYTE_PTR) & q_size, unit_address, sizeof(WORD)) ==
             HW_ERR_NONE)
         {
            /*
             * If the data attribute is multiple instance unit, return the
             * instance size in bytes as the total data size.
             */
            *data_size_ptr = q_size;
         }
         else
         {
            SEM_MTX_POST(SEM_LookupTable);
            return ERR_READ;
         }
      }
      else if (NIBBLE_LOW(unit_header_buffer.type_attribute) == ATTR_GRP_TABLE)
      {

#if (INCLUDE_FRAGMENTED_DATA == TRUE)

        mof_index = (BYTE)LOOKUP_TABLE_OSFIELD(type,identifier);

         /*
          * IF this identifier is using the FDI_OpenParam structure
          * THEN get the data's total size from FDI_OpenTotalSize
          */
         if ((BYTE)mof_index != BYTEMAX)
         {
            SEM_MTX_WAIT(SEM_TotalSize);
            *data_size_ptr = FDI_OpenTotalSize[(BYTE)mof_index];
            SEM_MTX_POST(SEM_TotalSize);
         }
         else
         {
            local_read_info.block_addr = block_address;
            local_read_info.identifier = identifier;
            local_read_info.type_attribute = unit_header_buffer.type_attribute;
            /* calculate the unit's address from the unit_offset */
            local_read_info.b_begin_unit_offset = ((FDV_BLOCK_SIZE -
               sizeof(BLOCK_INFO)) -
               TO_BYTES(unit_header_buffer.g_unit_offset_bottom));

            local_read_info.b_grp_table_entry_offset =
               local_read_info.b_begin_unit_offset;
            /*
             * find the total data size by reading all the group and sequence
             * table entries
             */
            if (BKGD_GetTableEntry(&local_read_info,
                                   &index, (BYTE_PTR) & index, &index,
                                  (BYTE_PTR) & index, DWORDMAX,
                                  TO_BYTES(unit_header_buffer.g_unit_size) /
                                  (WORD) sizeof(ENTRY_TABLE)) != HW_ERR_NONE)
            {
               SEM_MTX_POST(SEM_LookupTable);
               return ERR_SYSTEM;
            }
            *data_size_ptr = local_read_info.b_total_size;
         }
#else                                  /* !INCLUDE_FRAGMENTED_DATA */
         SEM_MTX_POST(SEM_LookupTable);
         return ERR_FORMAT;
#endif                                 /* !INCLUDE_FRAGMENTED_DATA */

      }
      else
      {
         SEM_MTX_POST(SEM_LookupTable);
         return ERR_SYSTEM;
      }

      SEM_MTX_POST(SEM_LookupTable);
      return ERR_NONE;
   }

   SEM_MTX_POST(SEM_LookupTable);

   if (hw_status != HW_ERR_EMPTY_LKUP)
   {
      if (hw_status == HW_ERR_PARAM)
         return ERR_PARAM;
      else
         return ERR_SYSTEM;
   }
   return ERR_NONE;
}                                      /* END of GetDataSize */


#if (INCLUDE_FRAGMENTED_DATA == TRUE)

/*
 *############################################################################
 *### ScanEntryTables
 *###
 *### DESCRIPTION:
 *### Scans the group table to do necessary power loss recovery for the
 *### sequence table unit headers refered to by it. The steps involved in
 *### power loss recovery are the following.
 *### 1.invalidate the old sequence table unit headers refered by the
 *###   physical index field of the group table entry
 *### 2.invalidate all the old fragment unit headers refered by the
 *###   physical index and old_block_number fields of the sequence table entry,
 *###   and validate all the new fragment headers refered by the new sequence
 *###   table entries by calling the ScanSequenceTable function
 *### 3.validate the new sequence table unit headers refered by the
 *###   the new group table entries
 *###
 *### PARAMETERS:
 *### INPUT:
 *### UNIT_HDR_PTR new_grp_hdr_ptr - pointer to the new group table's
 *###                                UNIT_HEADER type
 *### DWORD new_grp_hdr_addr - address of the new group table's unit header
 *### WORD current_index
 *### WORD index
 *### BYTE seq_table_number
 *###
 *### OUTPUT:
 *###
 *### RETURNS:
 *###        ERR_NONE   ERR_NOTEXISTS
 *###
 */

#if (PACKET_DATA == TRUE)
ERR_CODE
#else /* PACKET_DATA */
static ERR_CODE
#endif /* PACKET_DATA */
ScanEntryTables(const UNIT_HEADER * new_tbl_hdr_ptr,
                DWORD new_tbl_hdr_addr,
                WORD current_index,
                WORD index,
                WORD seq_tbl_number)
{

   UNIT_HEADER unit_header_buffer;
   DWORD block_address = 0;
   DWORD new_tbl_addr = 0;
   /*
    * save the address of the first new sequence table entry with status
    * SEQ_VALID_ENTRY. If its corresponding fragment unit header status
    * is HDR_VALID_HDR, this entry will be marked SEQ_INVALID after all the
    * other new sequence table entries are marked SEQ_INVALID, because if
    * dual power loss happens, we need to know which sequence table entry
    * is the first new one to do plr again.
    */
   DWORD first_seq_tbl_entry_addr = DWORDMAX;
   WORD unit_index = 0;
   WORD tbl_index;
   WORD ENTRY_TABLE_size;
   ENTRY_TABLE new_tbl_buff;
   WORD block_index = 0;
   WORD data_instance = 0;
   ERR_CODE status = ERR_NONE;
   HW_ERROR hw_status = HW_ERR_NONE;

   /*
    * this flag will be set to TRUE when the status of the first new sequence
    * table entry's corresponding fragment is HDR_VALID_HDR. When it is TRUE,
    * it indicates that all the data hasn't been written, if we find any
    * fragment with status HDR_ALLOCATED for this data, it will be
    * invalidated then.
    */
   BYTE invalidate_flag = FALSE;

   /* valid group entry number */
   WORD grp_entry_number = 0;
   /* bump_seq_addr will be set to FALSE only if there are any
      intermediate states found. */
   BYTE bump_seq_addr;
   BYTE entry_state_mask;
   WORD header_state_mask;

   /* Calculate the actual address of the new group table unit. */
   new_tbl_addr = ((new_tbl_hdr_addr / FDV_BLOCK_SIZE) * FDV_BLOCK_SIZE) +
    ((FDV_BLOCK_SIZE - sizeof(BLOCK_INFO)) -
    TO_BYTES(new_tbl_hdr_ptr->g_unit_offset_bottom));

   /*
    * At this point the seq table unit header will be marked either valid or
    * allocated. If not returns an error.
    */
   ENTRY_TABLE_size = TO_BYTES(new_tbl_hdr_ptr->g_unit_size);
   tbl_index = 0;

   /* if header status is HDR_ALLOCATED, check all entries */
   if (new_tbl_hdr_ptr->status != HDR_VALID)
   {
      /* Until done scanning the entry table, */
      do
      {

         /* Read one new entry table information. */
         hw_status = FlashDevRead((BYTE_PTR) & new_tbl_buff, (new_tbl_addr +
                                  (tbl_index * sizeof(ENTRY_TABLE))),
                                  sizeof(ENTRY_TABLE));
         if (hw_status != HW_ERR_NONE)
         {
            return ERR_READ;
         }

         /* Exit if the end of the entry table has been reached. */
         if (new_tbl_buff.entry_status == SEQ_EMPTY)
         {
            break;
         }

         /*
          * If the new table entry has a valid physical index value
          */
         if (new_tbl_buff.physical_index != WORDMAX)
         {
            /* Validate the block_number and old_entry_block fields to check
               that they are within the valid range for logical block numbers
               in this configuration
            */
            if (!VALID_BLOCK_RANGE(new_tbl_buff.old_entry_block) ||
                !VALID_BLOCK_RANGE(new_tbl_buff.block_number))
                return ERR_FORMAT;
            /*
             * invalidate the table unit header refered by the physical index
             * field of the table entry.
             */
            block_index = FDI_LogicalBlockTable[new_tbl_buff.old_entry_block].
             physical_block_number;
            block_address = BLOCK_ADDRESS(block_index);

            /*
             * Read the unit header information of the header refered to by
             * the physical_index and old_block_number fields.
             */
            hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
                                     (block_address + FIRST_HEADER_OFFSET +
                                     (new_tbl_buff.physical_index *
                                     sizeof(UNIT_HEADER))),
                                     sizeof(UNIT_HEADER));
            if (hw_status != HW_ERR_NONE)
            {
               return ERR_READ;
            }

            if(CheckAddr((block_address + FIRST_HEADER_OFFSET +
                         (new_tbl_buff.physical_index * sizeof(UNIT_HEADER))),
                         current_index, index) == BYTEMAX)
               unit_header_buffer.g_unit_size = WORDMAX;


            /* Invalidate the table unit header. */
            status =
               WriteUnitHeaderStatus((block_address + FIRST_HEADER_OFFSET +
                                     (new_tbl_buff.physical_index *
                                      sizeof(UNIT_HEADER))), HDR_INVALID,
                                      unit_header_buffer.status,
                                      unit_header_buffer.g_unit_size, 1);
            mDEBUG_CHECK_ERRCODE(status)
            if (status != ERR_NONE)
               return ERR_WRITE;
         }                             /* ENDIF physical_index != WORDMAX */

         /* skip to next table entry. */
         tbl_index++;
         ENTRY_TABLE_size -= sizeof(ENTRY_TABLE);

      } while (ENTRY_TABLE_size >= sizeof(ENTRY_TABLE));
   } /* ENDIF new_tbl_hdr_ptr->status != HDR_VALID */

   /*
    * At this point the seq table unit header will be marked either valid or
    * allocated. If not returns an error.
    */
   ENTRY_TABLE_size = TO_BYTES(new_tbl_hdr_ptr->g_unit_size);
   tbl_index = 0;

   /* Until done scanning the table, */
   do
   {
      bump_seq_addr = TRUE;
      /* Read one new table entry information. */
      hw_status = FlashDevRead((BYTE_PTR) & new_tbl_buff, (new_tbl_addr +
                                (tbl_index * sizeof(ENTRY_TABLE))),
                               sizeof(ENTRY_TABLE));
      if (hw_status != HW_ERR_NONE)
      {

⌨️ 快捷键说明

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