📄 zfsformat.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 + -