📄 zfslist.c
字号:
/*
* File : ZFSList.c
* Description: This file contains the implementation of ZFSList APIs
* 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 6183, MKC
* The hour stored in the ZFS_FD_LIST_t structure is 1 less than the acutal
* value, because of masking a bit. changed 0xF100 --> 0xF800
*/
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "glextern.h"
extern RZK_SEMAPHOREHANDLE_t hSem_FS;
#define MAX_ENTRIES_LIST_RETURN (8)
//Function Name: ZFSList
//Description: This API will return the files and directories present within a directory. This will
// return 8 files at a time.
ZFS_STATUS_t ZFSList( IN INT8 * path, IN_OUT ZFS_FD_LIST_t * list, IN UINT8 startCnt )
{
UINT len = 0 ;
UINT off = 0 ;
PZFS_DIR_LIST_t pdir_node, pcwd_dir_node ;
PZFS_VOL_INFO_t pvol_info ;
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 ;
UINT8 bcomp ;
UINT8 status ;
UINT32 date_time ;
INT fd_cnt ;
INT cnt = 0 ;
// if ZFS is not initialized, return error
if( !IsZFSInited() )
return ZFSERR_NOT_INITIALIZED ;
if( list == NULL || path == NULL )
return ZFSERR_INVALID_ARGUMENTS ;
if( !ValidatePath( path ) )
return ZFSERR_INVALID_FILEDIR_PATH ;
// now check the validity of the dir path given in the argument
len = strlen( (const INT8 *)path ) ;
// disable preemption
RZKAcquireSemaphore(hSem_FS,INFINITE_SUSPEND);
// preempt_status = DisablePreemption() ;
if( GetCwdInfoForCurThread( &pvol_info, &pcwd_dir_node ) != ZFS_TRUE )
{
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_INVALID_VOLUME ;
}
// now validated, disable preemption, find the absolute path with reduced length
status = IsAbsPath( path, &pvol_info, &off, &pdir_node ) ;
if( status != ZFS_TRUE )
{
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_INVALID_FILEDIR_PATH ;
}
if( !IsVolumeValid(pvol_info) )
{
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_INVALID_VOLUME ;
}
if( pdir_node == NULL )
{
// get the CWD_INFO table
pdir_node = pcwd_dir_node ;
}
// this is relative path, get the directory node of the relative path with reduced length
pdir_node = GetNodeForPath( pdir_node, path + off, ( len - off ) ) ;
if( pdir_node == NULL )
{
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_FILE_DIR_DOES_NOT_EXIST ;
}
// now directory is found, just get the file/directory name and store it into the fd_list
// store the number of files/directories present in the local variable.
fd_cnt = (INT) pdir_node->fd_cnt ;
if( fd_cnt < startCnt )
{
// error here, return error
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_INVALID_OFFSET_RANGE ;
}
fd_cnt = 0 ;
// get which sector does current pfir belongs to.
pfit_sec = ( PZFS_FIT_HDR_t) pdir_node->sec_num ;
fir_addr = (PZFS_FIR_t) GetSecAddr( pvol_info, (ZFS_SEC_ID_t) pdir_node->sec_num ) + 1 ;
num_firs_in_sec = ( ZFS_SEC_DATA_SIZE / sizeof( ZFS_FIR_t ) ) ;
while( pfit_sec != ( PZFS_FIT_HDR_t ) FREE_SECTOR )
{
bcomp = ZFS_FALSE ;
// read the FIR.
pvol_info->pcfg->pfn_drv_read( fir_addr, &fir_hdr, sizeof(ZFS_FIR_t)) ;
// check whether it is a valid fir or not. If not just continue from the beginning.
if( pvol_info->pcfg->vol_type != ZFS_RAM_DEV_TYPE )
{
if( !( ~fir_hdr.fir_type_status & ZFS_FIR_DIRTY ) )
{
// if it is not dirty, check whether the FIR is FREE or allocated.
if( ~fir_hdr.fir_type_status & ZFS_FIR_ALLOCATED )
{
bcomp = ZFS_TRUE ;
}
}
}
else
{
if( ( ~fir_hdr.fir_type_status & ( ZFS_FIR_ALLOCATED ) == ZFS_FIR_ALLOCATED ) )
{
bcomp = ZFS_TRUE ;
}
}
if( bcomp == ZFS_TRUE )
{
// increment the count and we have to wait till we reach given file count
if( cnt < startCnt )
{
// do not do any thing here.. just check to next
cnt++ ;
}
else
{
// it is a valid FIR. copy all the details of an FIR into the list.
memset( list, 0x00, sizeof( ZFS_FD_LIST_t ) ) ;
len = GetLenOfFDNameFromFIR( ( INT8 * ) &fir_hdr.fir_name[0] ) ;
memcpy( &(list->fd_name[0]), &fir_hdr.fir_name[0], len ) ;
list->fd_name[len] = '\0' ;
if( fir_hdr.size == FREE_SECTOR )
list->fd_size = 0 ;
else
list->fd_size = fir_hdr.size ;
list->fd_type = fir_hdr.fir_type_status ;
// storing the date and time
date_time = fir_hdr.tom ;
list->fd_sec = (date_time & 0x1F ) << 1;
list->fd_min = ( ( date_time & 0x7E0 ) >> 5 ) ;
list->fd_hrs = ( ( date_time & 0xF800 ) >> 11 ) ; /* CR 6183 , changed 0xF100 --> 0xF800 */
list->fd_day = ( ( date_time & 0x1F0000 ) >> 16 ) ;
list->fd_mon = ( ( date_time & 0x01E00000 ) >> 21 ) ;
list->fd_year = ( ( date_time & 0xFE000000 ) >> 25 ) ;
list->fd_century = fir_hdr.tom_century ;
list++ ;
// increment the return count and if it is equal to MAX_ENTRIES_LIST_RETURN, then break from the loop
// and return the number.
fd_cnt++ ;
if( fd_cnt == MAX_ENTRIES_LIST_RETURN )
break ;
}
}
num_firs_in_sec -- ;
fir_addr++;
if( num_firs_in_sec == 0 )
{
// store the new address into it.
// read the fit header
pvol_info->pcfg->pfn_drv_read( GetSecAddr( pvol_info, pfit_sec ), &sec_hdr, sizeof(ZFS_SEC_HDR_t)) ;
pfit_sec = ( PZFS_FIT_HDR_t ) sec_hdr.nxtsecnum ;
fir_addr = (( PZFS_FIR_t) GetSecAddr( pvol_info, sec_hdr.nxtsecnum ) + 1 ) ;
num_firs_in_sec = ( ZFS_SEC_DATA_SIZE / sizeof( ZFS_FIR_t ) ) ;
}
}
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return fd_cnt ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -