📄 zfsrenamedir.c
字号:
/*
* File : ZFSRenameDir.c
* Description: This file contains the implementation of ZFS 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 #6013: MKC, 5/18/2005
* A bug in ZFSRenameDir where in if a file is opened in a sub-directory,
* then it was allowing to rename a directory that contains this sub-directory
* which should not be done.
*
* CR #6014: MKC, 5/18/2005
* Once the root directory is given for rename, this function simply
* does not comeout of it.
*/
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "glextern.h"
extern RZK_SEMAPHOREHANDLE_t hSem_FS;
//Function Name: ZFSRenameDir
//Description: This API renames a existing directory
ZFS_STATUS_t ZFSRenameDir( IN INT8 *src_dir_path, IN INT8* dst_dir_name )
{
UINT len = 0 ;
UINT off = 0 ;
UINT last_fd_off = 0 ;
UINT idx ;
PZFS_DIR_LIST_t pdir_node, pcur_node, pcwd_dir_node ;
PZFS_VOL_INFO_t pvol_info ;
PZFS_FIR_t pfir;
ZFS_FIR_t fir_hdr ;
UINT8 status ;
ZFS_STATUS_t ret_status = ZFSERR_SUCCESS ;
// if ZFS is not initialized, return error
if( !IsZFSInited() )
return ZFSERR_NOT_INITIALIZED ;
if( src_dir_path == NULL || dst_dir_name == NULL )
return ZFSERR_INVALID_ARGUMENTS ;
if( !ValidatePath( src_dir_path ) )
return ZFSERR_INVALID_FILEDIR_PATH ;
if( !ValidateFileDirName( dst_dir_name ) )
return ZFSERR_INVALID_FILE_DIR_NAME ;
last_fd_off = GetLastFileDirNameOff( src_dir_path ) ;
// now check the validity of the dir path given in the argument
len = strlen( (const INT8 *)src_dir_path ) ;
// disable preemption
RZKAcquireSemaphore(hSem_FS,INFINITE_SUSPEND);
// preempt_status = DisablePreemption() ;
if( GetCwdInfoForCurThread( &pvol_info, &pcwd_dir_node ) != ZFS_TRUE )
{
ret_status = ZFSERR_INVALID_VOLUME ;
goto err_Label_ZFSRenameDir ;
}
// now validated, disable preemption, find the absolute path with reduced length
status = IsAbsPath( src_dir_path, &pvol_info, &off, &pdir_node ) ;
if( status != ZFS_TRUE )
{
ret_status = ZFSERR_INVALID_FILEDIR_PATH ;
goto err_Label_ZFSRenameDir;
}
if( !IsVolumeValid(pvol_info) )
{
ret_status = ZFSERR_INVALID_VOLUME ;
goto err_Label_ZFSRenameDir;
}
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, src_dir_path + off, ( len - off ) ) ;
if( pdir_node == NULL )
{
ret_status = ZFSERR_FILE_DIR_DOES_NOT_EXIST ;
goto err_Label_ZFSRenameDir;
}
// CR #6014: Just check whether the directory to be renamed is root directory or not.
if( pdir_node == pvol_info->proot_node )
{
ret_status = ZFSERR_INVALID_FILEDIR_PATH ;
goto err_Label_ZFSRenameDir;
}
// now directory is found, just check whether a file with same new name exists or not
pfir = SearchFIR( pvol_info, ( PZFS_FIT_HDR_t ) pdir_node->up_list->sec_num, dst_dir_name, strlen( (const INT8 *)dst_dir_name ) ) ;
if( pfir != NULL )
{
ret_status = ZFSERR_FILE_DIR_ALREADY_EXISTS ;
goto err_Label_ZFSRenameDir;
}
// No directory with new name exists, just check whether any thread opened a file in this directory or not
for( idx = 0 ; idx < g_max_or_entries ; idx ++ )
{
if( g_zfs_or[idx].status == ZFS_OR_MAGIC_NUM )
{
// CR #6013: MKC, 5/18/2005
// traverse through the pdir_node and if found, return an error
for( pcur_node = g_zfs_or[ idx ].pdir_node ; pcur_node ; pcur_node = pcur_node->up_list )
{
if( pcur_node == pdir_node )
{
// file is opened in this directory, just return an error
ret_status = ZFSERR_FILE_DIR_IN_USE ;
goto err_Label_ZFSRenameDir;
}
}
}
}
// no file is opened in this directory, now check whether any thread made this directory as its cwd.
// No directory with new name exists, just check whether any thread opened a file in this directory or not
for( idx = 0; idx < g_max_threads ; idx++ )
{
// Get the thread handle with the id.
if( GetCwdNodeForThreadId( idx, &pcur_node ) == ZFS_TRUE )
{
while( pcur_node )
{
if( pcur_node == pdir_node )
{
// some thread made this directory as its cwd, so return an error
ret_status = ZFSERR_FILE_DIR_IN_USE ;
goto err_Label_ZFSRenameDir;
}
pcur_node = pcur_node->up_list ;
}
}
}
// The directory is not in use, just overwrite the previous FIR with new name.
// first get the fir of the source directory.
pfir = SearchFIR( pvol_info, ( PZFS_FIT_HDR_t ) pdir_node->up_list->sec_num, src_dir_path + last_fd_off, ( len - last_fd_off) ) ;
// read the FIR contents into memory.
pvol_info->pcfg->pfn_drv_read( pfir, &fir_hdr, sizeof( ZFS_FIR_t) ) ;
InitializeHeader( &fir_hdr.fir_name[0], ZFS_MAX_FILE_NAME_SIZE ) ;
memcpy( &fir_hdr.fir_name[0], dst_dir_name, strlen( (const INT8 *)dst_dir_name ) ) ;
if( OverWriteFIR( pvol_info, (PZFS_FIT_HDR_t) pdir_node->up_list->sec_num, pfir, &fir_hdr ) == NULL )
{
ret_status = ZFSERR_INTERNAL ;
goto err_Label_ZFSRenameDir;
}
// update the pdir_node structure.
memset( pdir_node->dir_name, 0x00, ZFS_MAX_FILE_NAME_SIZE ) ;
memcpy( pdir_node->dir_name, dst_dir_name, strlen( (const INT8 *)dst_dir_name) ) ;
err_Label_ZFSRenameDir:
// now every thing is over, just return
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ret_status ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -