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

📄 zfsinit.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
📖 第 1 页 / 共 4 页
字号:
		pblk_info->blk_start_addr = pblk_addr ;

		sec_data_bit = ~(pblk_info->blk_hdr.sec_hdr.sec_data_bit );
		sec_type = ~(pblk_info->blk_hdr.sec_hdr.sec_type ) ;
		sec_status = ~(pblk_info->blk_hdr.sec_hdr.status ) ;

		// now check whether the block is a valid block or not.
		if( !( sec_data_bit & 0x01 ) ||
			( pblk_info->blk_hdr.zfs_magic_num != ZFS_BLOCK_MAGIC_NUM ) ||
			!( sec_status & ZFS_SEC_ALLOCATED )  ||
			sec_type == ZFS_SEC_FREE )
			{
			// invalid block.
			*ppinval_blk = pblk_info ;
			continue ;
			}

		if( ( ( sec_type & ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB )) == (ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB) ) &&
			( pblk_info->blk_hdr.tb_gc_start == 0xFE ) && ( pblk_info->blk_hdr.tb_gc_end != 0xFE ) )

			{
			*pptmp_tb_blk = pblk_info ;
			}
		

		// now it is a valid block, just assign different blocks.
		if( ( sec_type & ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB )) == ZFS_SEC_TYPE_TB )
			{
			*pptb_blk = pblk_info ;
			}
		else	 if( ((( sec_type & ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB )) == ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB ) ) ||
				( sec_type & ZFS_SEC_TYPE_AB ) == ZFS_SEC_TYPE_AB  ) &&
				( pblk_info->blk_hdr.ab_gc_start == 0xFE ) )
			{
			// allocation block that was chosen for GC.
			*ppab_blk_gc_start = pblk_info ;
			}
		}

	return ;
}


UINT8 IsRootDirPresent( PZFS_VOL_INFO_t pvol_info )
{
	UINT secs_in_a_blk ;
	PZFS_BLK_INFO_t pblk_info ;
	PZFS_SEC_HDR_t psec_hdr ;
	ZFS_SEC_HDR_t sec_hdr ;
	UINT num_blks = pvol_info->pcfg->vol_blks ;
	UINT idx ;
	UINT32 blk_size ;
	UINT cnt ;
	UINT root_sec_cnt = 0 ;

	// This function will search for sector id = 0 and valid sector. If found,
	// returns ZFS_TRUE, else return ZFS_FALSE
	
	// now read through the sectors present in this volume and update the SAT with values.
	pblk_info = pvol_info->blk_info ;
	blk_size = pvol_info->pcfg->vol_size /pvol_info->pcfg->vol_blks ; 
	secs_in_a_blk = blk_size / ZFS_SEC_SIZE ;

	if( 	pvol_info->pcfg->vol_type != ZFS_RAM_DEV_TYPE )
		{			
	// for each block, get the status of each sectors and then update the SAT with the address and sector number
	for( idx = 0 ; idx < num_blks ; idx++, pblk_info++ )
		{
		if( ((UINT8)(~((UINT8)pblk_info->blk_hdr.sec_hdr.sec_type)) & ( ZFS_SEC_TYPE_TB | ZFS_SEC_TYPE_NEW_AB )) ==  ( ZFS_SEC_TYPE_TB ) )
			{
			// it is an TB, just continue with next block
			continue ;
			}

		// check for the sector for 0 id.
		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 whether the sector is a valid sector or not. If valid, check the sec_id and if it is 0, then return 
			// ZFS_TRUE. If not found, return ZFS_FALSE
			if( (~(sec_hdr.sec_data_bit) & 0x01 ) &&
				( ( ~sec_hdr.sec_type) & ZFS_SEC_TYPE_FIT ) &&
				( ( (~sec_hdr.status ) & ( ZFS_SEC_ALLOCATED | ZFS_SEC_DIRTY ) ) == ZFS_SEC_ALLOCATED ) )
				{
				// valid sector, check for the sector id. If the sector id is 0, then return ZFS_TRUE
				if( sec_hdr.sec_num == 0x00 )
					root_sec_cnt++ ;
				}
			psec_hdr = ( PZFS_SEC_HDR_t ) ( (( UINT8 * ) psec_hdr) + ZFS_SEC_SIZE ) ;
			}
		}
	}
	else
	{
		//The second sector is the Root Dir
		psec_hdr = (PZFS_SEC_HDR_t ) (((UINT8*)pvol_info->pcfg->vol_addr) + ZFS_SEC_SIZE);
		pvol_info->pcfg->pfn_drv_read(psec_hdr, &sec_hdr, sizeof(ZFS_SEC_HDR_t)) ;
		if( (~(sec_hdr.sec_data_bit) & 0x01 ) && ( ( ~sec_hdr.sec_type) & ZFS_SEC_TYPE_FIT ) &&
			( ( (~sec_hdr.status ) & ( ZFS_SEC_ALLOCATED | ZFS_SEC_DIRTY ) ) == ZFS_SEC_ALLOCATED ) )
			root_sec_cnt = 1;

	}

	if( root_sec_cnt == 1 )
		return ZFS_TRUE ;
	else
		return ZFS_FALSE ;
}


UINT8 GetBlkNum( PZFS_VOL_INFO_t pvol_info, PZFS_BLK_INFO_t pblk_info )
{
	UINT8 idx ;
	PZFS_BLK_INFO_t ptmp_blk_info ;

	ptmp_blk_info = pvol_info->blk_info ;
	for( idx = 0 ; ptmp_blk_info != pblk_info ; idx++, ptmp_blk_info++ ) ;

	return idx ;
}


void SetVolParamsInvalid( PZFS_VOL_INFO_t pvol_info, PZFS_VOL_PARAMS_t pvol_params ) 
{
/*
 * copy the volume name and set the is_valid bit to false.
 */
	pvol_info->is_valid = ZFS_FALSE ;
	pvol_params->is_valid = ZFS_FALSE ;
	strcpy( ( INT8 * ) pvol_params->vol_name, ( const INT8 * ) pvol_info->pcfg->vol_name ) ;
	return ;
}

//Function Name: ZFSInit
//Description: This API initializes the file system
ZFS_STATUS_t ZFSInit( PZFS_VOL_PARAMS_t pvol_params  )
{
	UINT preempt_status ;
	UINT cnt ;
	UINT vol_cnt ;
	ZFS_SEC_HDR_t sec_hdr ;
	UINT8 *blk_addr ;
	UINT32 blk_size ;
	UINT idx ;
	UINT num_blks ;
	UINT blk_info_offset = 0 ;
	UINT sat_info_offset = 0 ;
	UINT secs_in_a_blk ;
	UINT num_dirty_secs ;
	UINT num_free_secs ;
	VOID *free_sec_addr ;

	PZFS_SEC_HDR_t ab_sec_hdr ;
	PZFS_FIR_t pfir_ab_addr ;
	ZFS_FIR_t fir_ab_hdr ;
	PZFS_BLK_INFO_t pblk_info ;
	PZFS_DIR_LIST_t root_dir_node ;
	PZFS_DIR_LIST_t new_dir_node ;
	PZFS_DIR_LIST_t parent_dir_node ;
	PZFS_SEC_HDR_t proot_sec_addr ;
	PZFS_SEC_HDR_t pdir_sec_addr ; 
	UINT firs_in_a_sec ;
	UINT len ;
	ZFS_SEC_ID_t pdir_sec_id ;

	PZFS_CONFIG_t pzfs_cfg ;
	PZFS_VOL_INFO_t pvol_info ;
	UINT8 **psat ; // for SAT address 
	UINT tmp_ab_cnt = 0, tmp_tb_cnt = 0, tmp_ib_cnt = 0;
	PZFS_BLK_INFO_t pinval_blk, ptb_blk, pab_blk_gc_start, ptmp_tb_blk ;
	UINT8 blk_num ;

	if( IsZFSInited())
		return ZFSERR_ALREADY_INITIALIZED ;


	// store the maximum number of threads and max CWD path len.
	g_max_threads = MAX_THREADS ;
	g_max_cwd_len = nRzkMaxCwdPathLen ;


	
	// make all arrays/data structures to zero.
	memset( &g_zfs_or[0], 0x00, sizeof(ZFS_OPEN_REC_t) * g_max_or_entries ) ;
	memset( &g_dir_list[0], 0x00, sizeof(ZFS_DIR_LIST_t) * g_max_dirs_supported ) ;
	memset(&g_zfs_vol_info[0], 0x00, sizeof(ZFS_VOL_INFO_t)*g_max_volumes) ;
	memset(&g_sec_gc[0], 0x00, ZFS_SEC_SIZE) ;
	memset(&g_sec_data_write[0], 0x00, ZFS_SEC_SIZE);
	memset(&g_blk_info[0], 0x00, sizeof(ZFS_BLK_INFO_t) * g_max_flash_blks) ;
	memset(&g_zfs_sat[0], 0x00, g_max_flash_sectors) ;

	
	// now ZFS is not initialized, just check for 
	preempt_status = DisablePreemption();
	
	InitializeRTC( ) ;


	// now loop through the configuration table and initialize appropriate volume.
	pzfs_cfg = &g_zfs_cfg[0] ;
	pvol_info = &g_zfs_vol_info[0] ;
	blk_info_offset = 0 ;
	sat_info_offset = 0 ;
	for( vol_cnt = 0 ; vol_cnt < g_max_volumes ; vol_cnt++, pzfs_cfg++, pvol_info++ )
		{
		
		if( pzfs_cfg->vol_type == ZFS_RAM_DEV_TYPE )
			{
			pblk_info = &g_blk_info[blk_info_offset] ;
			num_blks = pzfs_cfg->vol_blks ;
			// this is RAM device type, just format the RAM device and update appropraite OR structures
			pzfs_cfg->pfn_drv_init( ( void * ) pzfs_cfg->vol_addr, pzfs_cfg->vol_size );
			
			if( g_byEraseFlash == 1 )
			{
				pzfs_cfg->pfn_drv_erase( ( void * ) pzfs_cfg->vol_addr, pzfs_cfg->vol_size ) ;
			}

			pblk_info = &g_blk_info[blk_info_offset] ;
			pvol_info->pcfg = pzfs_cfg ;
			pvol_info->pvol_sat = ( UINT8 * ) NULL ;
			pvol_info->ttl_num_secs = pzfs_cfg->vol_secs ;
			pvol_info->dirty_sec_count = 0 ;
			pvol_info->free_sec_count = pzfs_cfg->vol_secs ;

			pvol_info->blk_info = pblk_info ;

			pblk_info->blk_start_addr = pzfs_cfg->vol_addr ;
			pblk_info->dirty_sec_count = 0 ;
			pblk_info->free_sec_count = pzfs_cfg->vol_secs ;
							
			tmp_ab_cnt = 0;
			GetBlkInfo( pzfs_cfg, pvol_info->blk_info, &tmp_ab_cnt, &tmp_tb_cnt, &tmp_ib_cnt ) ;
			if( tmp_ab_cnt !=1 )
				{
					SetVolParamsInvalid( pvol_info, pvol_params ) ;
					pvol_params++ ;
				}
			else
				{
					if( IsRootDirPresent( pvol_info ) == ZFS_FALSE )
						{
						SetVolParamsInvalid( pvol_info, pvol_params ) ;
						pvol_params++ ;
						}
					else
						{
						pvol_info->is_valid = ZFS_TRUE ;
						}
				}
			
			blk_info_offset++;
		}
	else if( pzfs_cfg->vol_type != ZFS_RAM_DEV_TYPE )
		{
		// FLASH 
		// Need to recover stuff from here.

		// first check whether all block headers are there properly or not by checking the 
		// bit sec_hdr.sec_data_bit 0xFE)

		// first get the count of blocks which do not have correct block header. If more than 1 block found with
		// bit not set, then we will format disk procedure again.
		blk_addr = (UINT8*) pzfs_cfg->vol_addr ;
		blk_size = pzfs_cfg->vol_size / pzfs_cfg->vol_blks ;
		num_blks = pzfs_cfg->vol_blks ;

		pzfs_cfg->pfn_drv_init( ( UINT8*) blk_addr, blk_size ) ;

		// only for testing - erasing the whole flash for the file system
		////////////////////////////////
		if( g_byEraseFlash == 1 )
			{
			for( idx = 0 ; idx < num_blks; idx++ )
				{
				pzfs_cfg->pfn_drv_erase( ( UINT8*) blk_addr, blk_size ) ;
				blk_addr += blk_size ;
				}
			}
		////////////////////////////////

		idx = 0 ;

		// update the vol_info table
		pvol_info->blk_info = &g_blk_info[blk_info_offset] ;
		pvol_info->pcfg = pzfs_cfg ;
		pvol_info->proot_node = ( PZFS_DIR_LIST_t ) NULL ;
		pvol_info->pvol_sat = (UINT8*)&g_zfs_sat[ sat_info_offset] ;

		// Get the block information.
		tmp_ab_cnt = tmp_tb_cnt = tmp_ib_cnt =0;
		GetBlkInfo( pzfs_cfg, pvol_info->blk_info, &tmp_ab_cnt, &tmp_tb_cnt, &tmp_ib_cnt ) ;

		if( tmp_tb_cnt > 1 || tmp_ib_cnt > 1 ) //|| tmp_ab_cnt == pvol_info->pcfg->vol_blks )
			{
			// If > 1 invalid blocks else
			// if > 1 TB
			// if AB = Total num of blocks
			
			// power off during writing the block header. re-format the stuff and continue from next volume
			SetVolParamsInvalid( pvol_info, pvol_params ) ;
			pvol_params++ ;
/*				
			g_fmt_from_init = ZFS_TRUE ;
			g_zfs_init = ZFS_TRUE ;
			ZFSFormat(pzfs_cfg->vol_name, ZFS_FALSE ) ;
			g_fmt_from_init = ZFS_FALSE ;
			g_zfs_init = ZFS_FALSE ;
			pvol_info->new_format_flag = ZFS_TRUE ;
*/				
			blk_info_offset += pvol_info->pcfg->vol_blks ;
			sat_info_offset += pvol_info->pcfg->vol_secs ;
			continue ;
			}                                        

		// ib_cnt = 1 || 0
		// tb_cnt = 1 || 0
		// In this case, just get what is the IB address, TB address.
		pinval_blk = GetInvalidBlk( pvol_info ) ;

		// Get the TB.
		ptb_blk = GetTBPtr( pvol_info ) ;


		// Get various blocks, invalid block, tb block, ab block with GC_STARTED
		GetDiffBlks( pvol_info, &pinval_blk, &ptb_blk, &pab_blk_gc_start, &ptmp_tb_blk ) ;

		// now you have got the info, check for below conditions.

		// If TB does not exist
		if( ptb_blk == NULL )
			{
			// TB block does not exist,
			// conditions

			// 1. If GC is completed, TB header written as ZFS_SEC_TYPE_NEW_AB and power is failed.
			if( ptmp_tb_blk != NULL &&  pab_blk_gc_start != NULL )
				{
				UINT8 gc_complete = 0xFE ;

				// write down the gc_complete bit.
				pzfs_cfg->pfn_drv_write( ptmp_tb_blk->blk_start_addr + BLK_TB_GC_START_OFFSET, &gc_complete, 1 ) ;
				
				//	so get the invalid block and erase the block and write the TB header.
				pzfs_cfg->pfn_drv_erase( pab_blk_gc_start->blk_start_addr, blk_size) ;
				
				// get the block number of pab_blk_gc_start.
				blk_num = GetBlkNum( pvol_info, pab_blk_gc_start ) ;
				InitializeHeader(&(pab_blk_gc_start->blk_hdr), sizeof( ZFS_BLK_HDR_t ) ) ;

				pab_blk_gc_start->blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;
				pab_blk_gc_start->blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_TB ;
				pab_blk_gc_start->blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
				pab_blk_gc_start->blk_hdr.blk_num = blk_num ;
				// write the block header.
				pzfs_cfg->pfn_drv_write( pab_blk_gc_start->blk_start_addr, &pab_blk_gc_start->blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;

				// write the bit
				pab_blk_gc_start->blk_hdr.sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN ;
				pzfs_cfg->pfn_drv_write( ( UINT8 *) pab_blk_gc_start->blk_start_addr + SEC_DATA_BIT_OFFSET, &pab_blk_gc_start->blk_hdr.sec_hdr.sec_data_bit, 2 ) ;
				pvol_info->is_valid = ZFS_TRUE ;
				

				}
			else
			
			// 1. GC finished, but the AB is not erased.  - erase the block and designate it as TB.
			if( pab_blk_gc_start != NULL && pinval_blk == NULL )
				{
				
				//	so get the invalid block and erase the block and write the TB header.
				pzfs_cfg->pfn_drv_erase( pab_blk_gc_start->blk_start_addr, blk_size) ;
				
				// get the block number of pab_blk_gc_start.
				blk_num = GetBlkNum( pvol_info, pab_blk_gc_start ) ;
				InitializeHeader(&(pab_blk_gc_start->blk_hdr), sizeof( ZFS_BLK_HDR_t ) ) ;

				pab_blk_gc_start->blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;
				pab_blk_gc_start->blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_TB ;
				pab_blk_gc_start->blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
				pab_blk_gc_start->blk_hdr.blk_num = blk_num ;
				// write the block header.
				pzfs_cfg->pfn_drv_write( pab_blk_gc_start->blk_start_addr, &pab_blk_gc_start->blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;

				// write the bit
				pab_blk_gc_start->blk_hdr.sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN ;
				pzfs_cfg->pfn_drv_write( ( UINT8 *) pab_blk_gc_start->blk_start_addr + SEC_DATA_BIT_OFFSET, &pab_blk_gc_start->blk_hdr.sec_hdr.sec_data_bit, 2 ) ;
				pvol_info->is_valid = ZFS_TRUE ;
				
				}
			else 
			// 2. GC finished, but the AB is erased or AB header is partly written - erase the block and designate it as TB.

				if( tmp_ib_cnt == 1 && tmp_ab_cnt == (pvol_info->pcfg->vol_blks - 1))
				{
				//	so get the invalid block and erase the block and write the TB header.
				pzfs_cfg->pfn_drv_erase( pinval_blk->blk_start_addr, blk_size) ;
				
				// get the block number of pab_blk_gc_start.
				blk_num = GetBlkNum( pvol_info, pinval_blk ) ;
				InitializeHeader(&(pinval_blk->blk_hdr), sizeof( ZFS_BLK_HDR_t ) ) ;

				pinval_blk->blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;
				pinval_blk->blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_TB ;
				pinval_blk->blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
				pinval_blk->blk_hdr.blk_num = blk_num ;
				// write the block header.
				pzfs_cfg->pfn_drv_write( pinval_blk->blk_start_addr, &pinval_blk->blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;

				// write the bit
				pinval_blk->blk_hdr.sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN ;
				pzfs_cfg->pfn_drv_write( ( UINT8 *) pinval_blk->blk_start_addr + SEC_DATA_BIT_OFFSET, &pinval_blk->blk_hdr.sec_hdr.sec_data_bit, 2 ) ;
				pvol_info->is_valid = ZFS_TRUE ;
				}
			else				
				{
				// 2. AB block headers are written, but not the TB, - format.
/*					
				g_fmt_from_init = ZFS_TRUE ;
				g_zfs_init = ZFS_TRUE ;

⌨️ 快捷键说明

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