📄 zfsinit.c
字号:
firs_in_a_sec = ZFS_SEC_SIZE / sizeof( ZFS_FIR_t) - 1 ;
for( ; firs_in_a_sec > 0 ; firs_in_a_sec--, pfir++, tmp_data_bit <<= 1 )
{
// get the fir header
pvol_info->pcfg->pfn_drv_read( pfir, &fir_status, 1 ) ;
// now check whether the FIR is written properly or not, if not make this fir as dirty.
if( !(sec_data_bit & tmp_data_bit ) )
{
if( (fir_status != (UINT8)( ~ZFS_FIR_FREE )) )
{
fir_status &= ~ZFS_FIR_DIRTY ;
// write down the FIR onto the flash
pvol_info->pcfg->pfn_drv_write( pfir, &fir_status, 1 ) ;
}
}
else
{
// it is an valid record, just check whether it contains the duplicateItem is set or not,
if(( (~fir_status) & (ZFS_FIR_DUP | ZFS_FIR_NOT_DUP ) ) == ZFS_FIR_DUP )
{
// this FIR contains the duplicate entry, just check for a duplicate entry.
// 2nd item has written properly, but when deleting the 1st item, the power has failed.
// the entry is a valid entry.
CorrectDuplicateFIREntry( pvol_info, orig_sec_id, pfir ) ;
// continue with the search and call again if duplicate entry is found.
}
}
}
pvol_info->pcfg->pfn_drv_read( ( (UINT8*)GetSecAddr( pvol_info, pdir_sec_id)), &sec_hdr, sizeof(ZFS_SEC_HDR_t ) ) ;
pdir_sec_id = sec_hdr.nxtsecnum ;
pfir = (PZFS_FIR_t) ((UINT8*) GetSecAddr( pvol_info, pdir_sec_id ) + sizeof( ZFS_FIR_t ) ) ;
}
return ;
}
UINT8 CheckLinkChainOfSector( PZFS_VOL_INFO_t pvol_info, ZFS_SEC_ID_t pdir_sec_id, PZFS_SEC_HDR_t psec_hdr )
{
ZFS_SEC_ID_t new_sec_id ;
PZFS_SEC_HDR_t pold_sec_hdr ;
// Check the sector header for nxt_sec_data_bit. If it is set to 0xFC, then a valid link is present,
// otherwise the link is not fully written. So free this sector and allocate a new sector and write the
// sector header.
if( ( (~(psec_hdr->nxt_sec_data_bit)) & ( ZFS_SEC_LINK_START | ZFS_SEC_LINK_END ) ) == ZFS_SEC_LINK_START )
{
// read the sector contents.
pvol_info->pcfg->pfn_drv_read( GetSecAddr(pvol_info, pdir_sec_id ), &g_sec_buf[0], ZFS_SEC_SIZE ) ;
pold_sec_hdr = ( PZFS_SEC_HDR_t ) &g_sec_buf[0] ;
// invalid link record is written to the sector,
// Free the sector
FreeSector( pvol_info, pdir_sec_id ) ;
// Allocate a sector, this should give the same number.
new_sec_id = AllocSector( pvol_info, pdir_sec_id, (~psec_hdr->sec_type) &( ZFS_SEC_TYPE_DATA|ZFS_SEC_TYPE_FIT ) ) ;
if( new_sec_id != NULL )
{
pold_sec_hdr->nxtsecnum = ( ZFS_SEC_ID_t ) FREE_SECTOR ;
pold_sec_hdr->nxt_sec_data_bit = 0xFF ;
// new sector is allocated, just write the sector contents here
pvol_info->pcfg->pfn_drv_write( GetSecAddr( pvol_info, new_sec_id), &g_sec_buf[0],
ZFS_SEC_SIZE) ;
}
else
{
// problem over here as there may not be space exist. // What to do in this condition
return ZFS_FALSE ;
}
}
return ZFS_TRUE ;
}
void CheckIntegrityOfFile( PZFS_VOL_INFO_t pvol_info, PZFS_DIR_LIST_t parent_dir_node, PZFS_FIR_t pfir_ab_addr, PZFS_FIR_t pfir_ab_hdr )
{
// read the contents of sec id
PZFS_SEC_HDR_t psec_hdr ;
ZFS_SEC_ID_t pdir_sec_id ;
UINT32 ttl_size = 0 ;
UINT32 size = 0 ;
UINT idx ;
UINT8 *ptr ;
UINT8 bCheckFFs ;
// Get the size of the file. If the file size is not zero or not FFFFFF, then traverse through the sectors allocated for this
// file and calculate the size. If the calculated size is greater than the one present in the FIR, then make the old FIR as dirty
// and allocate a new FIR and write the FIR with new values.
if( pfir_ab_hdr->sec_datanum == ( ZFS_SEC_ID_t) FREE_SECTOR )
return ;
// traverse through the sectors allocated to this FIR to find the size.
bCheckFFs = ZFS_FALSE ;
pdir_sec_id = pfir_ab_hdr->sec_datanum ;
// BUG FIX 16_SEP
// If during deletion, first sector is deleted and power failed, we need to make the FIR as dirty.
if( GetSecAddr( pvol_info, pdir_sec_id ) == NULL )
{
FreeFIR( pvol_info, pfir_ab_addr ) ;
return ;
}
// BUG FIX 16_SEP
while( pdir_sec_id != ( ZFS_SEC_ID_t ) FREE_SECTOR )
{
pvol_info->pcfg->pfn_drv_read( GetSecAddr( pvol_info, pdir_sec_id), &g_sec_gc[0], ZFS_SEC_SIZE ) ;
psec_hdr = ( PZFS_SEC_HDR_t ) &g_sec_gc[0] ;
// BUG_FIX : 16_SEP
// Here we should check if the
// if a duplicate sector is found, what it means is that to overwrite this sector. So, call the OverWriteSector
// function to carry out the operation.
// otherwise, carry out the normal operation.
// BUG_FIX : 16_SEP
// Now traverse through the array and calculate the size.
ptr = &g_sec_gc[0] + sizeof(ZFS_SEC_HDR_t) ;
size = ZFS_SEC_DATA_SIZE ;
for( idx = 0 ; idx < ZFS_SEC_DATA_SIZE; idx++, ptr++ )
{
if( bCheckFFs == ZFS_TRUE )
{
// now check if the ptr is 0xFF or not, if not, make it is a normal count.
if( *ptr != 0xFF )
{
bCheckFFs = ZFS_FALSE ;
size = idx ;
}
}
else if( *ptr == 0xFF )
{
bCheckFFs = ZFS_TRUE ;
size = idx ;
}
}
ptr = ( UINT8 * ) NULL ;
if( bCheckFFs == ZFS_FALSE )
size = ZFS_SEC_DATA_SIZE ;
// BUG_FIX : 16_SEP
else if(psec_hdr->nxtsecnum != ( PZFS_SEC_HDR_t ) FREE_SECTOR )
size = ZFS_SEC_DATA_SIZE ;
// BUG_FIX : 16_SEP
ttl_size += size ;
CheckLinkChainOfSector( pvol_info, pdir_sec_id, ( PZFS_SEC_HDR_t ) &g_sec_gc[0] ) ;
// again read hte sec_header
pvol_info->pcfg->pfn_drv_read( GetSecAddr( pvol_info, pdir_sec_id), &g_sec_gc[0], ZFS_SEC_SIZE ) ;
psec_hdr = ( PZFS_SEC_HDR_t ) &g_sec_gc[0] ;
pdir_sec_id = psec_hdr->nxtsecnum ;
}
if( pfir_ab_hdr->size == FREE_SECTOR )
{
pfir_ab_hdr->size = 0 ;
}
// now compare the size of the file with the one present in the FIR.
if( pfir_ab_hdr->size >= ttl_size )
{
// the size in FIR is more than what we are calculated, so just retain the same
}
else
{
// the calculated size is more than the size present in the FIR. So destroy this FIR and alloc a new fir with valid
// contents.
pfir_ab_hdr->size = ttl_size ;
OverWriteFIR( pvol_info, ( PZFS_FIT_HDR_t ) parent_dir_node->sec_num, pfir_ab_addr, pfir_ab_hdr) ;
}
return ;
}
// BUG_FIX : 16_SEP
ZFS_STATUS_t IsNewOverWrittenSectorExist( PZFS_VOL_INFO_t pvol_info, PZFS_SEC_HDR_t pold_sec_hdr, PZFS_SEC_HDR_t pold_sec_addr )
{
UINT idx ;
UINT cnt ;
// UINT num_of_sec ;
UINT32 blk_size ;
PZFS_BLK_INFO_t pblk_info ;
PZFS_SEC_HDR_t psec_hdr ;
UINT secs_in_a_blk ;
ZFS_SEC_HDR_t sec_hdr ;
// now read through the sectors present in this volume and update the SAT with values.
// num_of_sec = pvol_info->pcfg->vol_secs ;
pblk_info = pvol_info->blk_info ;
blk_size = pvol_info->pcfg->vol_size /pvol_info->pcfg->vol_blks ;
// for each block, get the status of each sectors and then update the SAT with the address and sector number
for( idx = 0 ; idx < pvol_info->pcfg->vol_blks ; idx++, pblk_info++ )
{
// not it is an AB, just traverse through the blocks and update the SAT
secs_in_a_blk = blk_size / ZFS_SEC_SIZE ;
psec_hdr = (PZFS_SEC_HDR_t ) ((UINT8*)pblk_info->blk_start_addr + ZFS_SEC_SIZE );
for( cnt = 1 ; cnt < secs_in_a_blk ; cnt++ )
{
//read the sector header
pvol_info->pcfg->pfn_drv_read(psec_hdr, &sec_hdr, sizeof(ZFS_SEC_HDR_t)) ;
// check for the sector ID. If it is equal, then go ahead with the comparison.
if( sec_hdr.sec_num == pold_sec_hdr->sec_num )
{
// equal, just check whether it is same sector or not..
if( pold_sec_addr != psec_hdr )
{
// check for validity..
if( !((~((UINT8)(sec_hdr.sec_data_bit))) & 0x01 ) &&
(((UINT8)(~sec_hdr.status ) != ZFS_SEC_FREE ) ||
((UINT8)(~sec_hdr.sec_type) != ZFS_SEC_FREE ) ) )
{
// do nothing, invalid sector continue
}
else if( ( ~((UINT8)sec_hdr.status) & (ZFS_SEC_ALLOCATED | ZFS_SEC_DIRTY ) ) == ZFS_SEC_ALLOCATED )
{
// this is the sector which is newly allocated, just check about the contents...
// whether require info is present or not.
// free the new sector..
sec_hdr.status &= ~ZFS_SEC_DIRTY ;
pvol_info->pcfg->pfn_drv_write( ( UINT8 *) psec_hdr + 1, &sec_hdr.status, 1 ) ;
if( psec_hdr < pold_sec_addr )
{
// the newly allocated sector is stored at an address lower than the older one.
// So, just increase the count dirty_sectors in the lower address block.
pblk_info->dirty_sec_count++;
pblk_info->free_sec_count--;
}
return ZFS_FALSE ;
}
}
}
psec_hdr = ( PZFS_SEC_HDR_t ) ( (( UINT8 * ) psec_hdr) + ZFS_SEC_SIZE ) ;
}
}
return ZFS_FALSE ;
}
// BUG_FIX : 16_SEP
// BUG_FIX : 16_SEP
PZFS_SEC_HDR_t FindDupSector( PZFS_VOL_INFO_t pvol_info, PZFS_SEC_HDR_t pold_sec_hdr )
{
UINT idx ;
UINT cnt ;
// UINT num_of_sec ;
UINT32 blk_size ;
PZFS_BLK_INFO_t pblk_info ;
PZFS_SEC_HDR_t psec_hdr ;
UINT secs_in_a_blk ;
ZFS_SEC_HDR_t sec_hdr ;
// now read through the sectors present in this volume and update the SAT with values.
// num_of_sec = pvol_info->pcfg->vol_secs ;
pblk_info = pvol_info->blk_info ;
blk_size = pvol_info->pcfg->vol_size /pvol_info->pcfg->vol_blks ;
// for each block, get the status of each sectors and then update the SAT with the address and sector number
for( idx = 0 ; idx < pvol_info->pcfg->vol_blks ; idx++, pblk_info++ )
{
// not it is an AB, just traverse through the blocks and update the SAT
secs_in_a_blk = blk_size / ZFS_SEC_SIZE ;
psec_hdr = (PZFS_SEC_HDR_t ) ((UINT8*)pblk_info->blk_start_addr + ZFS_SEC_SIZE );
for( cnt = 1 ; cnt < secs_in_a_blk ; cnt++ )
{
//read the sector header
pvol_info->pcfg->pfn_drv_read(psec_hdr, &sec_hdr, sizeof(ZFS_SEC_HDR_t)) ;
// check for the sector ID. If it is equal, then go ahead with the comparison.
if( sec_hdr.sec_num == pold_sec_hdr->sec_num )
{
// equal, just check whether it is same sector or not..
if( ( ((~sec_hdr.sec_data_bit) & ((UINT8)0x01) ) != 0 ) &&
( (~(sec_hdr.status)) & (ZFS_SEC_DIRTY | ZFS_SEC_DUP | ZFS_SEC_NO_DUP ) ) == (ZFS_SEC_DIRTY | ZFS_SEC_DUP )
)
return psec_hdr ;
}
psec_hdr = ( PZFS_SEC_HDR_t ) ( (( UINT8 * ) psec_hdr) + ZFS_SEC_SIZE ) ;
}
}
return ( PZFS_SEC_HDR_t ) NULL ;
}
// BUG_FIX : 16_SEP
#endif // POWER_FAIL_SAFE
UINT8 GetBlkInfo( PZFS_CONFIG_t pzfs_cfg, PZFS_BLK_INFO_t pblk_info, UINT *pab_cnt, UINT *ptb_cnt, UINT *pib_cnt )
{
UINT8 *pblk_addr = pzfs_cfg->vol_addr ;
UINT32 blk_size = pzfs_cfg->vol_size / pzfs_cfg->vol_blks ;
UINT idx = 0 ;
UINT16 sec_data_bit ;
UINT8 sec_type ;
for(idx=0; idx < pzfs_cfg->vol_blks; idx++, pblk_info++, pblk_addr += blk_size)
{
// read the block sector data bit.
pzfs_cfg->pfn_drv_read(pblk_addr, &(pblk_info->blk_hdr), sizeof(ZFS_BLK_HDR_t) ) ;
pblk_info->blk_start_addr = blk_size * idx + pzfs_cfg->vol_addr ;
sec_data_bit = pblk_info->blk_hdr.sec_hdr.sec_data_bit ;
sec_type = pblk_info->blk_hdr.sec_hdr.sec_type ;
if( !(~(sec_data_bit) & 0x01 ) || pblk_info->blk_hdr.zfs_magic_num != ZFS_BLOCK_MAGIC_NUM)
{
(*pib_cnt)++ ;
continue ;
}
if( pblk_info->blk_hdr.blk_num != idx )
{
(*pib_cnt)++ ;
continue ;
}
if( (~pblk_info->blk_hdr.sec_hdr.status ) & (ZFS_SEC_ALLOCATED ) )
{
if( ( (~sec_type ) & ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB )) == ZFS_SEC_TYPE_TB )
{
(*ptb_cnt)++ ;
}
else if(( (~sec_type ) & ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB )) == ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB ) )
{
(*pab_cnt)++ ;
}
else if(( (~sec_type ) & ( ZFS_SEC_TYPE_AB )) == ( ZFS_SEC_TYPE_AB ) )
{
(*pab_cnt)++ ;
}
}
else
{
(*pib_cnt)++ ;
}
}
return ZFS_TRUE ;
}
PZFS_BLK_INFO_t GetInvalidBlk( PZFS_VOL_INFO_t pvol_info )
{
PZFS_BLK_INFO_t pblk_info = pvol_info->blk_info ;
UINT idx = 0 ;
UINT num_blks = pvol_info->pcfg->vol_blks ;
UINT8 sec_type ;
for(idx=0; idx < num_blks; idx++, pblk_info++)
{
sec_type = ~pblk_info->blk_hdr.sec_hdr.sec_type ;
// check whether the block is a invalid block or not. If yes, store its address.
if( !( sec_type & (ZFS_SEC_TYPE_AB | ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB ) ) &&
( pblk_info->blk_hdr.zfs_magic_num != ZFS_BLOCK_MAGIC_NUM ) )
{
// this is an invalid block. store this.
return pblk_info ;
}
}
return ( PZFS_BLK_INFO_t ) NULL;
}
void GetDiffBlks( PZFS_VOL_INFO_t pvol_info,
PZFS_BLK_INFO_t *ppinval_blk,
PZFS_BLK_INFO_t *pptb_blk,
PZFS_BLK_INFO_t *ppab_blk_gc_start,
PZFS_BLK_INFO_t *pptmp_tb_blk )
{
UINT8 *pblk_addr = pvol_info->pcfg->vol_addr ;
PZFS_BLK_INFO_t pblk_info = pvol_info->blk_info;
UINT32 blk_size = pvol_info->pcfg->vol_size / pvol_info->pcfg->vol_blks ;
UINT num_blks = pvol_info->pcfg->vol_blks ;
UINT idx = 0 ;
UINT16 sec_data_bit ;
UINT8 sec_status ;
UINT8 sec_type ;
// initialize the parameters to NULL.
*ppinval_blk = ( PZFS_BLK_INFO_t ) NULL ;
*pptb_blk = ( PZFS_BLK_INFO_t ) NULL ;
*ppab_blk_gc_start = ( PZFS_BLK_INFO_t ) NULL ;
*pptmp_tb_blk = ( PZFS_BLK_INFO_t ) NULL ;
for(idx=0; idx < num_blks; idx++, pblk_info++, pblk_addr += blk_size)
{
// read the block sector data bit.
pvol_info->pcfg->pfn_drv_read(pblk_addr, &(pblk_info->blk_hdr), sizeof(ZFS_BLK_HDR_t) ) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -