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

📄 zfssec.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * File       : ZFSSec.c
 * Description: This file contains the implementations of the required sector related
 *				operations.
 * 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 
 */

/*
 * Revision History
 *
 * CR 6245, MKC
 * The sector after deleted was not filled up with 0xFFs causing invalid length
 * of the file.
 *
 * CR 6500, MK on 3-OCT-2005
 * While erasing the flash incase of RAM file system, the sector header information also
 * was made FF, which was erasing the first sector only when delete is called as the
 * rest of the sectors information is lost from the header of the first sector.
 * Now it is corrected to erase only the data portion, not the sector header.
 * The status of each header is made ZFS_SEC_FREE.
 */

#include "glextern.h"

extern ZFS_STATUS_t GC( PZFS_VOL_INFO_t pvol_info ) ;
extern UINT8 GetTimeData( UINT32 *date_time, UINT8 *time_century ) ;
extern PZFS_SEC_HDR_t  FindDupSector( PZFS_VOL_INFO_t pvol_info, PZFS_SEC_HDR_t pold_sec_hdr  ) ;
//Function definitions

//Function: GetBlkWithFreeSector
//Description: This function will return the block which has free sector (Valid only in FLASH)
PZFS_BLK_INFO_t GetBlkWithFreeSector( PZFS_VOL_INFO_t pvol_info )
{
	UINT blk_num = pvol_info->pcfg->vol_blks ;
	PZFS_BLK_INFO_t pblk ;
	UINT cnt = 0 ;

	pblk = pvol_info->blk_info ;

	for( cnt = 0 ; cnt < blk_num; cnt++)
		{
		if( ( pblk->free_sec_count > 0 ) && 
			(~(pblk->blk_hdr.sec_hdr.sec_type) & ( ZFS_SEC_TYPE_AB | ZFS_SEC_TYPE_NEW_AB ) ) )
			{
			return pblk ;
			}
		pblk++ ;
		}
	return ( PZFS_BLK_INFO_t ) NULL ;
}


//Function Name: AllocSector
//Description: This function will search for a free sector and allocates it
ZFS_SEC_ID_t AllocSector( PZFS_VOL_INFO_t pvol_info, ZFS_SEC_ID_t sec_num, UINT8 sec_type )
{
	PZFS_BLK_INFO_t pblk_free ;
	ZFS_SEC_ID_t free_sec_addr ;
	ZFS_SEC_ID_t free_sec_id ;
	ZFS_SEC_HDR_t sec_hdr ;
	UINT8 **sat_start_addr ;

	if( pvol_info->pcfg->vol_type != ZFS_RAM_DEV_TYPE )
		{

		// first get the block where more number of sectors are free.
		pblk_free = GetBlkWithFreeSector( pvol_info ) ;
		if( pblk_free == NULL )
			{

			// now all blocks are full, need to check if any dirty sectors are present
			if( IsDirtySectorsPresent( pvol_info ) == ZFS_TRUE )
				{
				// call GC
				if ( GC( pvol_info ) != ZFSERR_SUCCESS )
					{
					// some problem exists
					return NULL ;
					}
				else
					{
					// get the block with free sectors
					// first get the block where more number of sectors are free.
					pblk_free = GetBlkWithFreeSector( pvol_info ) ;
					}
				}
			else
				{
				// disk is full return error.
				return NULL ;
				}
			}

		// just get the next free sec addr from blk_info structure.
		free_sec_addr = pblk_free->next_free_sec_addr ;

		if( sec_num == NULL )
			free_sec_id = GetNewSecNum( pvol_info ) ;
		else
			free_sec_id = sec_num ;

		// write the sector header as allocated.
		InitializeHeader( &sec_hdr, sizeof( ZFS_SEC_HDR_t ) );
		sec_hdr.sec_type = ~sec_type ;
		sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
		sec_hdr.sec_num = free_sec_id ;
		pvol_info->pcfg->pfn_drv_write( free_sec_addr, &sec_hdr, sizeof(sec_hdr)) ;

#ifdef POWER_FAIL_SAFE					
		// POWER_FAIL_SAFE: Here just update the sec_hdr.sec_data_bit for this sector header.
		//////////
		sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN ;
		pvol_info->pcfg->pfn_drv_write( ((UINT8*)free_sec_addr+SEC_DATA_BIT_OFFSET), &sec_hdr.sec_data_bit, 2) ;
		// POWER_FAIL_SAFE: Here just update the sec_hdr.sec_data_bit for this sector header.
		//////////
#endif		
		

		// update the SAT.
		sat_start_addr = (UINT8**) pvol_info->pvol_sat ;

		*(sat_start_addr + (UINT32)free_sec_id ) = ( UINT8 * ) free_sec_addr ;
		//pvol_info->pvol_sat[ free_sec_id ] = free_sec_addr ;

		// update the blk_info
		pblk_free->next_free_sec_addr = (UINT8*) free_sec_addr + ZFS_SEC_SIZE ;
		pblk_free->free_sec_count -- ;
		}
	else
		{
		// for RAM type,

		// first get the free sector by checking through memory locations
		free_sec_addr  = GetFreeSector( pvol_info ) ;
		if( free_sec_addr == NULL )
			{
			// media is full,
			return NULL ;
			}

		InitializeHeader( &sec_hdr, sizeof( ZFS_SEC_HDR_t) ) ;
		// write the sector header
		sec_hdr.sec_type = ~sec_type ;
		sec_hdr.status = ~ZFS_SEC_ALLOCATED ;
		sec_hdr.sec_num = free_sec_addr ;
		
		pvol_info->pcfg->pfn_drv_write( free_sec_addr, &sec_hdr, sizeof(sec_hdr)) ;
#ifdef POWER_FAIL_SAFE					
		// POWER_FAIL_SAFE: Here just update the sec_hdr.sec_data_bit for this sector header.
		//////////
		sec_hdr.sec_data_bit = ZFS_SEC_HDR_WRITTEN ;
		pvol_info->pcfg->pfn_drv_write( ((UINT8*)free_sec_addr+SEC_DATA_BIT_OFFSET), &sec_hdr.sec_data_bit, 2) ;
		// POWER_FAIL_SAFE: Here just update the sec_hdr.sec_data_bit for this sector header.
		//////////
#endif

		// update the blk_info
		pvol_info->blk_info->free_sec_count -- ;
		pvol_info->free_sec_count -- ;

		free_sec_id = free_sec_addr ;
		}
	
	return free_sec_id  ;
}

//Function Name: GetFreeSector
//Description: This function will return the free sector's address (this requires searching of whole volume for a free sector
// or some kind of RAM variables or RAM tables)
// Valid for RAM
ZFS_SEC_ID_t GetFreeSector( PZFS_VOL_INFO_t pvol_info )
{
	PZFS_SEC_HDR_t pstart_addr, pend_addr ;
	PZFS_SEC_HDR_t psec_hdr ;
	UINT8 free_sec ;
	if( pvol_info->pcfg->vol_type == ZFS_RAM_DEV_TYPE )
		{
		pstart_addr = ( PZFS_SEC_HDR_t) pvol_info->pcfg->vol_addr ;
		pend_addr = (PZFS_SEC_HDR_t) ((UINT8*)pstart_addr + pvol_info->pcfg->vol_size) ;

		psec_hdr = pstart_addr ;
		while( psec_hdr != pend_addr )
			{
			pvol_info->pcfg->pfn_drv_read( ((UINT8*)psec_hdr + 1), &free_sec, 1 ) ;
			if( (UINT8)( free_sec & (UINT8)(~ZFS_SEC_FREE) ) == (UINT8)(~ZFS_SEC_FREE) )
				return psec_hdr ;
			psec_hdr = ( PZFS_SEC_HDR_t ) (((UINT8*)psec_hdr) + ZFS_SEC_SIZE) ;
			}
		}
	return NULL ;
}



//Function Name: GetNewSecNum
//Description: This function will search through the SAT table to find a new sector num
ZFS_SEC_ID_t GetNewSecNum( PZFS_VOL_INFO_t pvol_info )
{
	UINT cnt =0  ;
	UINT max_sec ;
	void **ppvoid ;
	if( pvol_info->pcfg->vol_type != ZFS_RAM_DEV_TYPE )
		{
		max_sec = pvol_info->pcfg->vol_secs ;
		ppvoid = ( void ** ) pvol_info->pvol_sat ;
		while( max_sec != 0 )
			{
//			if( ( void * ) pvol_info->pvol_sat[ cnt ] == NULL )
			if( *ppvoid == NULL )
				return ( void *) cnt ;
			ppvoid ++ ;
			cnt++ ;
			max_sec-- ;
			}
		}
	return NULL;
}


//Function Name: FreeSector
//Description: This function will free the sector pointed by sector number and its linked sectors
UINT8 FreeSector( PZFS_VOL_INFO_t pvol_info, ZFS_SEC_ID_t sec_num )
{
	UINT8 *sec_addr ;
	UINT8* blk_addr ;
	UINT32 blk_size ;
//	UINT blk_num ;
	ZFS_SEC_HDR_t sec_hdr ;

	PZFS_BLK_INFO_t pcur_blk_info ;
	VOID **ppsat ;

	blk_size = pvol_info->pcfg->vol_size / pvol_info->pcfg->vol_blks ;
	sec_addr = GetSecAddr( pvol_info,  sec_num) ;
	blk_addr = (sec_addr - ((( UINT32 )sec_addr) % blk_size ) ) ;
//	blk_num = blk_addr / blk_size ;
	ppsat = ( VOID ** ) pvol_info->pvol_sat ;


	if( pvol_info->pcfg->vol_type != ZFS_RAM_DEV_TYPE )
		{
		// now find the pointer to the blk_info structure
		for( pcur_blk_info = pvol_info->blk_info; 
			pcur_blk_info->blk_start_addr != blk_addr ; pcur_blk_info++) ;

		// read the sector header.
		pvol_info->pcfg->pfn_drv_read( sec_addr, &sec_hdr, sizeof( ZFS_SEC_HDR_t ) ) ;
		sec_hdr.status &= ~ZFS_SEC_DIRTY ;

		// write the sector header.
		pvol_info->pcfg->pfn_drv_write( ((UINT8*)sec_addr)+1, ((UINT8 *) &sec_hdr)+1, 1 ) ;

		// update the number of sectors present in this block
		pcur_blk_info->dirty_sec_count ++ ;
		pvol_info->dirty_sec_count ++ ;
		*(ppsat + (UINT32)sec_num ) = NULL ;
		}
	else
		{

		pcur_blk_info = pvol_info->blk_info ;

		// CR 6245, MKC
		//pvol_info->pcfg->pfn_drv_erase( sec_addr, ZFS_SEC_SIZE ) ;	
		
		// CR 6500, MK, 3-OCT-2005, the parameters are corrected
		pvol_info->pcfg->pfn_drv_erase( sec_addr+sizeof(ZFS_SEC_HDR_t), ZFS_SEC_SIZE -sizeof(ZFS_SEC_HDR_t)) ;

		// CR 6500, MK on 3-OCT-2005, Status is made FREE 
		*(sec_addr+1) = ~ZFS_SEC_FREE;

		// if device is RAM type
//		pvol_info->pcfg->pfn_drv_read( sec_addr, &sec_hdr, sizeof( ZFS_SEC_HDR_t ) ) ;		
//		sec_hdr.status = ~ZFS_SEC_FREE;

		// write the sector header.
//		pvol_info->pcfg->pfn_drv_write( ((UINT8*)sec_addr)+1, ((UINT8 *) &sec_hdr)+1, 1 ) ;

		pcur_blk_info->free_sec_count ++ ;
		pvol_info->free_sec_count ++ ;
		}

	return ZFS_TRUE ;
}



//Function Name: AllocFIR
//Description: This function will allocate an FIR from the FIT
PZFS_FIR_t AllocFIR( PZFS_VOL_INFO_t pvol_info, PZFS_FIT_HDR_t pfit_hdr )
{

	UINT num_firs_in_sec ;
	PZFS_FIR_t fir_addr ;
	ZFS_FIR_t fir_hdr ;
	ZFS_SEC_HDR_t sec_hdr ;
	PZFS_FIT_HDR_t pfit_sec ;
	ZFS_SEC_ID_t new_sec_id ;
	ZFS_SEC_ID_t prev_sec_id ;
	UINT8 fir_alloc = ~ZFS_FIR_ALLOCATED ;


	// get which sector does current pfir belongs to.
	pfit_sec = ( PZFS_FIT_HDR_t ) pfit_hdr ;//GetSecAddr(pvol_info, (ZFS_SEC_ID_t) pfit_hdr ) ;
	prev_sec_id = (ZFS_SEC_ID_t ) pfit_sec ;
	fir_addr = ( PZFS_FIR_t) GetSecAddr(pvol_info, (ZFS_SEC_ID_t) pfit_hdr ) + 1 ;
	num_firs_in_sec = ( ZFS_SEC_DATA_SIZE / sizeof( ZFS_FIR_t ) ) ;

	while( pfit_sec != ( PZFS_FIT_HDR_t ) FREE_SECTOR )
		{
		// read the FIR.
		pvol_info->pcfg->pfn_drv_read( fir_addr, &fir_hdr, 1) ;

		// check whether it is a valid fir or not. If not just continue from the beginning.
		if( ( (fir_hdr.fir_type_status) & (~ZFS_FIR_FREE)) == (UINT8)(~ZFS_FIR_FREE) )
			{
			// allocate it.
//			fir_hdr.fir_type_status &= ~(ZFS_FIR_ALLOCATED) ;

			// write to the media
			pvol_info->pcfg->pfn_drv_write( fir_addr, &fir_alloc, 1) ;
			return fir_addr ;
			}

		num_firs_in_sec -- ;
		fir_addr++;
		if( num_firs_in_sec == 0 )
			{
			// store the new address into it.
			// read the fit header
//			pfit_sec = ( PZFS_FIT_HDR_t ) GetSecAddr( pvol_info,  pfit_sec->sec_hdr.nxtsecnum ) ;
			pvol_info->pcfg->pfn_drv_read( GetSecAddr(pvol_info, pfit_sec), &sec_hdr, sizeof( ZFS_SEC_HDR_t ) ) ;
			prev_sec_id = pfit_sec ;
			pfit_sec = ( PZFS_FIT_HDR_t ) sec_hdr.nxtsecnum ;
			fir_addr = ( PZFS_FIR_t) GetSecAddr(pvol_info, pfit_sec) + 1 ;
			num_firs_in_sec = ( ZFS_SEC_DATA_SIZE / sizeof( ZFS_FIR_t ) ) ;
			}
		}

	// if it comes here, it means that current FIT is full, need to allocate a new FIT and link it to the older one.
	new_sec_id = AllocSector(pvol_info, 0, ZFS_SEC_TYPE_FIT) ;
	if( new_sec_id == 0 )
		{
		// data media is full,
		return ( PZFS_FIR_t ) NULL ;
		}

	LinkSector( pvol_info, prev_sec_id, new_sec_id) ;

	InitializeHeader( &fir_hdr, sizeof( ZFS_FIR_t ) ) ;
	fir_hdr.fir_type_status &= ~(ZFS_FIR_ALLOCATED) ;
	fir_addr = (PZFS_FIR_t) GetSecAddr( pvol_info, new_sec_id) + 1 ;

	pvol_info->pcfg->pfn_drv_write( fir_addr, &fir_hdr, 1) ;

	return fir_addr ;
}



//Function Name: FreeFIR
//Description: This function will free the FIR pointing to it.
UINT8 FreeFIR( PZFS_VOL_INFO_t pvol_info, PZFS_FIR_t pfir )
{
//	UINT num_bytes_read ;
	UINT8 fir_status ;


⌨️ 快捷键说明

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