📄 fsintrnl.c
字号:
int s = *sp;
/*-------------------------------------------------------------------*/
/* Keep looping until either we go past maximum value or we find a */
/* used sector. */
/*-------------------------------------------------------------------*/
while (++sector)
{
/*-----------------------------------------------------------------*/
/* If we've reached the end of a block in the erase set, move to */
/* next block. */
/*-----------------------------------------------------------------*/
if (sector == (Flash->erase_set[s] + 1) * Flash->block_sects)
{
/*---------------------------------------------------------------*/
/* If no more blocks in erase set, no more used sectors. */
/*---------------------------------------------------------------*/
if (++s >= Flash->set_blocks || Flash->erase_set[s] == -1)
return (uint)-1;
sector = Flash->erase_set[s] * Flash->block_sects;
}
/*-----------------------------------------------------------------*/
/* If a used sector is found, stop and return it. */
/*-----------------------------------------------------------------*/
if (used_sect(sector))
break;
}
*sp = s;
return sector;
}
/***********************************************************************/
/* to_offst: Transform a pointer into a ui32 offset so that it can */
/* be stored in flash */
/* */
/* Input: entry = pointer to entry in the table */
/* */
/* Returns: offset equivalent of pointer */
/* */
/***********************************************************************/
static ui32 to_offst(const void *entry)
{
ui16 table_num = 1;
FFSEnts *tbl;
union
{
OffLoc entry_loc;
ui32 result;
} obj;
/*-------------------------------------------------------------------*/
/* For NULL pointers, return -1 as offset location. */
/*-------------------------------------------------------------------*/
if (entry == NULL)
return (ui32)-1;
/*-------------------------------------------------------------------*/
/* Store the special value, REMOVED_LINK, as OFF_REMOVED_LINK. */
/*-------------------------------------------------------------------*/
if (entry == (void *)REMOVED_LINK)
return (OFF_REMOVED_LINK << 16) | OFF_REMOVED_LINK; /*lint !e648*/
/*-------------------------------------------------------------------*/
/* Figure out which table this entry belongs to. */
/*-------------------------------------------------------------------*/
for (tbl = Flash->files_tbl; tbl; tbl = tbl->next_tbl, ++table_num)
if ((tbl->tbl + FNUM_ENT > (FFSEnt *)entry) &&
(tbl->tbl <= (FFSEnt *)entry))
break;
/*-------------------------------------------------------------------*/
/* The entry must belong to some table. */
/*-------------------------------------------------------------------*/
PfAssert(tbl);
/*-------------------------------------------------------------------*/
/* Figure out the offset within the table for this entry. */
/*-------------------------------------------------------------------*/
obj.entry_loc.offset = (ui16)((FFSEnt *)entry - tbl->tbl);
/*-------------------------------------------------------------------*/
/* Return ui32 containing table number and entry offset. */
/*-------------------------------------------------------------------*/
obj.entry_loc.sector = table_num;
return obj.result;
}
/***********************************************************************/
/* count_ctrl_size: Count control info size (bytes and sectors) */
/* */
/* Inputs: adjust_erase = flag to adjust erase set size */
/* check_recycle = flag to check recycles in adjust set */
/* */
/* Returns: number of ctrl shorts to be checked against actual val */
/* */
/***********************************************************************/
static ui32 count_ctrl_size(int adjust_erase, int check_recycle)
{
ui32 table_size, i, ctrl_num_shorts, ctrl_size, ctrl_sects;
ui32 free_ctrl_sects, incr;
ui16 sector, last_in_segment, curr_sect, next_sect;
/*-------------------------------------------------------------------*/
/* Figure out how much space is needed to store the sectors table. */
/* Start with the free list. */
/*-------------------------------------------------------------------*/
ctrl_num_shorts = 2;
for (sector = Flash->free_sect;; sector = next_sect)
{
/*-----------------------------------------------------------------*/
/* Determine current free block. */
/*-----------------------------------------------------------------*/
i = sector / Flash->block_sects;
/*-----------------------------------------------------------------*/
/* Determine first sector in next free block. */
/*-----------------------------------------------------------------*/
next_sect = Flash->sect_tbl[(i + 1) * Flash->block_sects - 1].next;
/*-----------------------------------------------------------------*/
/* If no more blocks, stop and account for current segment. */
/*-----------------------------------------------------------------*/
if (next_sect == FLAST_SECT)
{
ctrl_num_shorts += 2;
break;
}
/*-----------------------------------------------------------------*/
/* Skip all bad blocks following current block. */
/*-----------------------------------------------------------------*/
for (++i; i < Flash->num_blocks && Flash->blocks[i].bad_block; ++i) ;
/*-----------------------------------------------------------------*/
/* If end of contiguous segment, account for it. */
/*-----------------------------------------------------------------*/
if (i != next_sect / Flash->block_sects)
ctrl_num_shorts += 2;
}
/*-------------------------------------------------------------------*/
/* Now count the space for the used sectors (per file). */
/*-------------------------------------------------------------------*/
for (sector = 0; sector < Flash->num_sects;)
{
/*-----------------------------------------------------------------*/
/* If sector is beginning of file, count whole file sector list. */
/*-----------------------------------------------------------------*/
if (Flash->sect_tbl[sector].prev == FLAST_SECT && used_sect(sector))
{
/*---------------------------------------------------------------*/
/* Count head of list. */
/*---------------------------------------------------------------*/
ctrl_num_shorts += 1;
/*---------------------------------------------------------------*/
/* Walk the list a contiguous segment at a time. */
/*---------------------------------------------------------------*/
for (curr_sect = sector; curr_sect != FLAST_SECT;)
{
/*-------------------------------------------------------------*/
/* Count current contiguous segment. For NOR skip headers. */
/*-------------------------------------------------------------*/
if (Flash->type == FFS_NOR)
for (last_in_segment = curr_sect;; last_in_segment = next_sect)
{
next_sect = last_in_segment + 1;
if (next_sect < Flash->num_sects &&
Flash->sect_tbl[next_sect].prev == FHDER_SECT)
next_sect += Flash->hdr_sects;
if (Flash->sect_tbl[last_in_segment].next != next_sect)
break;
}
else
for (last_in_segment = curr_sect;
Flash->sect_tbl[last_in_segment].next == last_in_segment + 1;
++last_in_segment) ;
/*-------------------------------------------------------------*/
/* If more than 1 sect in segment, count label and last sect. */
/*-------------------------------------------------------------*/
if (curr_sect != last_in_segment)
ctrl_num_shorts += 2;
/*-------------------------------------------------------------*/
/* Count next pointer. */
/*-------------------------------------------------------------*/
ctrl_num_shorts += 1;
/*-------------------------------------------------------------*/
/* Increment sector counter if first segment in file list. */
/*-------------------------------------------------------------*/
if (curr_sect == sector)
sector = last_in_segment + 1;
/*-------------------------------------------------------------*/
/* Move to new segment. */
/*-------------------------------------------------------------*/
curr_sect = Flash->sect_tbl[last_in_segment].next;
}
}
/*-----------------------------------------------------------------*/
/* Else move to next sector to look at. */
/*-----------------------------------------------------------------*/
else
++sector;
}
/*-------------------------------------------------------------------*/
/* Account for the last FLAST_SECT marking for end of table. */
/*-------------------------------------------------------------------*/
ctrl_num_shorts += 1;
/*-------------------------------------------------------------------*/
/* Add space for the files tables. */
/*-------------------------------------------------------------------*/
table_size = Flash->tbls_size + Flash->total * sizeof(ui8);
/*-------------------------------------------------------------------*/
/* The ctrl size consists of the size of the files tables + the fixed*/
/* number of ui32s + size of sectors table (in shorts) + wear count */
/* offsets for every block (2 offsets -> byte) + CRC and bad blocks */
/* (NAND only) or fast mount byte (NOR only) or CRC(MLC only). */
/*-------------------------------------------------------------------*/
ctrl_num_shorts += 10;
ctrl_size = table_size + FLASH_CTRL_UI32s * sizeof(ui32) +
sizeof(ui16) * ctrl_num_shorts + (Flash->num_blocks + 1) /
2 * sizeof(ui8);
if (Flash->type == FFS_NAND)
ctrl_size += (Flash->num_blocks + 7) / 8 + 4;
else
ctrl_size += 1;
#if QUOTA_ENABLED
/*-------------------------------------------------------------------*/
/* Count the quota enabled flag. */
/*-------------------------------------------------------------------*/
ctrl_size += 1;
#endif /* QUOTA_ENABLED */
/*-------------------------------------------------------------------*/
/* Add the size taken by writing the ctrl blocks. */
/*-------------------------------------------------------------------*/
ctrl_size += sizeof(ui16);
ctrl_sects = (ctrl_size + Flash->sect_sz - 1) / Flash->sect_sz;
free_ctrl_sects = (ui32)((Flash->free_ctrl_sect == (ui32)-1) ? 0 :
(Flash->block_sects -
Flash->free_ctrl_sect % Flash->block_sects));
if (ctrl_sects > free_ctrl_sects)
{
incr = (ctrl_sects - free_ctrl_sects + Flash->block_sects - 1)
/ Flash->block_sects + 1;
ctrl_size += 8 * incr;
ctrl_num_shorts += 4 * incr;
}
/*-------------------------------------------------------------------*/
/* Save update control information byte size and sector count. */
/*-------------------------------------------------------------------*/
Flash->ctrl_size = ctrl_size;
Flash->ctrl_sects = (Flash->ctrl_size + Flash->sect_sz - 1) /
Flash->sect_sz;
/*-------------------------------------------------------------------*/
/* Readjust the erase set size based on new ctrl info size. */
/*-------------------------------------------------------------------*/
adjust_set_size(adjust_erase, check_recycle);
/*-------------------------------------------------------------------*/
/* Return the number of ui16's it takes to write sect_tbl. */
/*-------------------------------------------------------------------*/
return ctrl_num_shorts;
}
/***********************************************************************/
/* free_block: Attempt to free block and add it to free list */
/* */
/* Inputs: block = block to be erased */
/* last_dirty = last dirty sector in corrupt free list */
/* adjust_set = flag to indicate if erase set has changed */
/* modified = flag to sync if state changes */
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -