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

📄 zfsinit.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -