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

📄 zfsrenamedir.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 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 + -