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

📄 zfsformat.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
字号:
/*
 * File       : ZFSFormat.c
 * Description: This file contains the implementation of ZFSFormat API
 * Author     : Mahadev K C
 * Created on : 30-APR-2003
 *
 * Copyright 2004 ZiLOG Inc.  ALL RIGHTS RESERVED.
 *
 * This file contains unpublished confidential and proprietary information
 * of ZiLOG, Inc.
 * NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED 
 * IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
 * This is not a license and no use of any kind of this work is authorized
 * in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's 
 * sole discretion 
 */


#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "glextern.h"
extern RZK_SEMAPHOREHANDLE_t hSem_FS;

//Function Name: ZFSFormat
//Description: This API formats the appropriate volume. It also formats all volumes present in the system
ZFS_STATUS_t ZFSFormat( IN INT8 *volname )
{
	PZFS_VOL_INFO_t pvol_info ;
	UINT single_vol_fmt ;
	UINT idx ;
	UINT free_sec_cnt ;
	PZFS_DIR_LIST_t pdir_node, pcur_node ;
	ZFS_SEC_ID_t new_sec_id ;
	ZFS_SEC_HDR_t sec_hdr ;

	ZFS_BLK_HDR_t blk_hdr ;
	PZFS_BLK_INFO_t pblk_info ;
	UINT32 blk_size ;
	INT tbblk_num ;
	UINT8 data_to_write = 0xFE ;
	UINT8 *blk_addr ;
	UINT8 *tb_blk_addr ;
	UINT num_blks ;
	UINT16 byte_to_write = ZFS_SEC_HDR_WRITTEN ;
	PZFS_CONFIG_t pzfs_cfg ;
	UINT8 *sec_addr ;
	PZFS_DIR_LIST_t dir_node ;

	// if ZFS is not initialized, return error
	if( !IsZFSInited() )
		return ZFSERR_NOT_INITIALIZED ;

	// check whether the given volume name is valid or not.
	for( single_vol_fmt = 0 ; single_vol_fmt < g_max_volumes ; single_vol_fmt++ )
		{
		if( strcmp( (const INT8 *)g_zfs_vol_info[ single_vol_fmt].pcfg->vol_name,(const INT8 *) volname ) == 0 )
			{
			pvol_info = &g_zfs_vol_info[ single_vol_fmt ] ;
			pzfs_cfg = &g_zfs_cfg[single_vol_fmt] ;
			break ;
			}
		}

	if( single_vol_fmt == g_max_volumes )
		{
		// no volume is found, just return an error
		return ZFSERR_INVALID_VOLUME_NAME ;
		}

//	preempt_status = DisablePreemption();
	RZKAcquireSemaphore(hSem_FS,INFINITE_SUSPEND);

	// now check if any thread is opened any file in the volume
	for( idx = 0 ; idx < g_max_or_entries ; idx++ )
		{
		if( g_zfs_or[ idx].pvol == pvol_info && g_zfs_or[idx].status == ZFS_OR_MAGIC_NUM )
			{
			// a file is opened in the volume,
			RZKReleaseSemaphore(hSem_FS);
//			EnablePreemption( preempt_status ) ;
			return ZFSERR_VOLUME_IS_IN_USE ;
			}
		}

	// now check if any thread made directory present in this volume as its cwd
	for( idx = 0 ; idx < g_max_threads ; idx ++ )
		{
		// Get the thread handle with the id.
		if( GetCwdNodeForThreadId( idx, &pcur_node )  == ZFS_TRUE )
			{
			if( pcur_node == pvol_info->proot_node )
				continue ;
			for( ; pcur_node->up_list != NULL ; pcur_node = pcur_node->up_list ) ;
			if( pcur_node == pvol_info->proot_node )
				{
				// some thread made this directory as its cwd, so return an error
				RZKReleaseSemaphore(hSem_FS);
//				EnablePreemption( preempt_status ) ;
				return ZFSERR_VOLUME_IS_IN_USE ;
				}
			}

		}


	// now volume is not used, just start formatting process
	if( pvol_info->pcfg->vol_type == ZFS_RAM_DEV_TYPE )
		{
		
		FreeDirNodesForVol( pvol_info ) ;
		pzfs_cfg->pfn_drv_erase( ( void * ) pzfs_cfg->vol_addr, pzfs_cfg->vol_size ) ;

		// update vol_info structure
		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 ;

		pblk_info = pvol_info->blk_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 ;


		// now allocate a Block Header for RAM dev.
		new_sec_id = AllocSector( pvol_info, 0, ZFS_SEC_TYPE_AB );
		InitializeHeader( &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
		blk_hdr.sec_hdr.sec_num = new_sec_id ;
		blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_AB ;
		blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
		blk_hdr.sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN;
		blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM;
		blk_hdr.blk_num = 0;

		sec_addr = GetSecAddr( pvol_info,  new_sec_id ) ;
		pzfs_cfg->pfn_drv_write( sec_addr, &blk_hdr, sizeof( ZFS_BLK_HDR_t  ) ) ;

		
		// now allocate a sector
		new_sec_id = AllocSector( pvol_info, 0, ZFS_SEC_TYPE_FIT ) ;

		InitializeHeader( &sec_hdr, sizeof( ZFS_SEC_HDR_t ) ) ;
		sec_hdr.sec_num = new_sec_id ;
		sec_hdr.sec_type = ~ZFS_SEC_TYPE_FIT ;
		sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
		sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN;

		// write the sector header
		sec_addr = GetSecAddr( pvol_info,  new_sec_id ) ;
		pzfs_cfg->pfn_drv_write( sec_addr, &sec_hdr, sizeof( ZFS_SEC_HDR_t ) ) ;
	
		// now allocate a dir_node for a root directory and store the address into pvol_info table
		dir_node = AllocDirNode( ) ;
		dir_node->sec_num = new_sec_id ;
		strcpy( ( INT8 * ) &dir_node->dir_name[ 0 ], ( const INT8 * ) pzfs_cfg->vol_name) ;
		pvol_info->root_sec_num = new_sec_id ;
		pvol_info->proot_node = dir_node ;
		pvol_info->new_format_flag = ZFS_TRUE;

		}
	else		// if volume is flash
		{
		// format the flash.

		num_blks = pvol_info->pcfg->vol_blks ;
	
		
		FreeDirNodesForVol( pvol_info ) ;

		// now overwrite whole memory with FF's
		//Erase whole memory
		// now write fmt started bit in TB.
		tbblk_num = GetTB( pvol_info ) ;
		if( tbblk_num == -1 )
			{
			// error in flash media, just make the last block as TB and format it
			tbblk_num = num_blks - 1 ;
			}

		if( g_fmt_from_init == ZFS_TRUE )
			tbblk_num = num_blks -1 ;

		pblk_info = pvol_info->blk_info ;
		blk_size = pvol_info->pcfg->vol_size / pvol_info->pcfg->vol_blks ;

			{
			UINT8 *addr = (((UINT8 *)pvol_info->pcfg->vol_addr) + (tbblk_num * blk_size )) + sizeof( ZFS_BLK_HDR_t) - 6 ;
			pvol_info->pcfg->pfn_drv_write( addr, &data_to_write, 1 ) ;
			}

		free_sec_cnt = ( (UINT) ( blk_size / ZFS_SEC_SIZE ) - 1 ) ;

		for( idx = 0 ; idx < num_blks ; idx++, pblk_info++ )
			{

			blk_addr = ( (UINT8 *)(pvol_info->pcfg->vol_addr) + ( idx * blk_size ));
			if( idx != tbblk_num )
				{
				pvol_info->pcfg->pfn_drv_erase( blk_addr, blk_size ) ;
				}
			else
				{
				continue ;
				}

			// write block header
			if( idx != ( num_blks - 1 ) )
				{
				// if it is not a last block

				InitializeHeader( &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
				blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_AB ;
				blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
				blk_hdr.blk_num = idx ;
				blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;

				pvol_info->pcfg->pfn_drv_write( blk_addr, 
										&blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;

				// write sec_hdr.sec_data_bit = 0xFE to say that the block header is written properly
				pvol_info->pcfg->pfn_drv_write( 
						blk_addr + SEC_DATA_BIT_OFFSET, 
						&byte_to_write, 
						2) ;
				
				memcpy( &pblk_info->blk_hdr, &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
				pblk_info->blk_start_addr = pvol_info->pcfg->vol_addr + ( idx * blk_size ) ;
				pblk_info->dirty_sec_count = 0 ;
				pblk_info->free_sec_count = free_sec_cnt ;
				pblk_info->next_free_sec_addr = (UINT8 * ) pblk_info->blk_start_addr + ZFS_SEC_SIZE ;
					
				}
			}

		// TB block address			
		tb_blk_addr =((UINT8*)(pvol_info->pcfg->vol_addr) + ( tbblk_num * blk_size )) ;

		// now ERASE TB and write the blk header.
		pvol_info->pcfg->pfn_drv_erase( tb_blk_addr, blk_size ) ;

		if( tbblk_num == ( idx -1 ) )
			{
			// if TB block is the last block, then write the header onto it.
			
			pblk_info-- ;
			
			InitializeHeader( &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_TB ;
			blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
			blk_hdr.blk_num = tbblk_num ;
			blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;
			
			pvol_info->pcfg->pfn_drv_write( tb_blk_addr, 
								&blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			
			pvol_info->pcfg->pfn_drv_write( 
					tb_blk_addr + SEC_DATA_BIT_OFFSET, 
					&byte_to_write, 
					2 ) ;

			memcpy( &pblk_info->blk_hdr, &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			pblk_info->blk_start_addr = tb_blk_addr;
			pblk_info->dirty_sec_count = 0 ;
			pblk_info->free_sec_count = 0 ;
			pblk_info->next_free_sec_addr = 0 ;
			}
		else		// if TB is in middle
			{
			// now the last block is erased, but block header is not written. So, first erase the TB and write
			// AB header.
			
			// now make this TB as AB
			InitializeHeader( &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_AB ;
			blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
			blk_hdr.blk_num = tbblk_num ;
			blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;
			pvol_info->pcfg->pfn_drv_write( tb_blk_addr, 
							&blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			pvol_info->pcfg->pfn_drv_write( 
					tb_blk_addr + SEC_DATA_BIT_OFFSET, 
					&byte_to_write, 
					2 ) ;

			memcpy( &pblk_info->blk_hdr, &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			pblk_info->blk_start_addr = tb_blk_addr ;
			pblk_info->dirty_sec_count = 0 ;
			pblk_info->free_sec_count = free_sec_cnt ;
			pblk_info->next_free_sec_addr = tb_blk_addr + ZFS_SEC_SIZE ;

			// make last block as TB, this block is already erased but need to write the blk header
			InitializeHeader( &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			blk_hdr.sec_hdr.sec_type = ~ZFS_SEC_TYPE_TB ;
			blk_hdr.sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
			blk_hdr.blk_num = idx -1 ;
			blk_hdr.zfs_magic_num = ZFS_BLOCK_MAGIC_NUM ;

			blk_addr = ((UINT8*)pvol_info->pcfg->vol_addr) + ( ( idx - 1 )* blk_size ) ;
			pvol_info->pcfg->pfn_drv_write( blk_addr, 
							&blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			
			pvol_info->pcfg->pfn_drv_write( 
					blk_addr + SEC_DATA_BIT_OFFSET, 
					&byte_to_write, 
					2 ) ;

			memcpy( &pblk_info->blk_hdr, &blk_hdr, sizeof( ZFS_BLK_HDR_t ) ) ;
			pblk_info->blk_start_addr = blk_addr;
			pblk_info->dirty_sec_count = 0 ;
			pblk_info->free_sec_count = 0 ;
			pblk_info->next_free_sec_addr = (pblk_info->blk_start_addr) + ZFS_SEC_SIZE ;				
			
			}
			
		// now clear the SAT for this volume
		memset( pvol_info->pvol_sat, 0x00, pvol_info->pcfg->vol_secs * sizeof(UINT) ) ;

		// now allocate a sector
		new_sec_id = AllocSector( pvol_info, 0, ZFS_SEC_TYPE_FIT ) ;
		// now allocate a pdir_node for a root directory and store the address into pvol_info table
		pdir_node = AllocDirNode() ;
		strcpy( (INT8 *)&pdir_node->dir_name[0], (const INT8 *) pvol_info->pcfg->vol_name ) ;
		pdir_node->sec_num = new_sec_id ;
		pvol_info->proot_node = pdir_node ;


		}

	pvol_info->is_valid = ZFS_TRUE ;

	RZKReleaseSemaphore(hSem_FS);
//	EnablePreemption( preempt_status ) ;
	return ZFSERR_SUCCESS ;
}




⌨️ 快捷键说明

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