📄 fsmvfs.c
字号:
/*****************************************************************************
FILE NAME: FsmVfs.c
DESCRIPTION:
virtual file system, provide all fs APIs..
Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/
#include "fsmdefs.h"
#include "string.h"
#include "ostype.h"
#include "FsmApi.h"
#include "FsmDfs.h"
#include "FsmVfs.h"
#define MAX_VOLUME_NUM 3
#define MAX_VFS_FD 16
/* local variables */
static FsmVolumeT FsmVolumes[MAX_VOLUME_NUM];
static HMSEM FsmVolumeMtxSem;
static FsmVfsFileDescriptorT FsmVfsFds[MAX_VFS_FD];
static HMSEM FsmVfsMtxSem;
static uint32 FsmGetMatchedVolume(char ** path);
static uint32 FsmAllocVfd(void);
static uint32 FsmFreeVfd(uint32 vfd);
/* global variables. */
extern FsmDevObjHdrT * FsmDataItemDevObjP;
extern uint32 FsmDataItemExit(void);
/*#############################################################################
### FsmVfsStartup
###
### DESCRIPTION:
### initialize all variable used internally.
###
### PARAMETERS:
### IN:
###
### OUT:
###
### RETURNS:
### Returns the following errors codes:
### ERR_NONE
### ERR_SYSTEM
###
*/
uint32 FsmVfsStartup()
{
uint32 i;
/* initialize the Volume structure */
for (i = 0; i < MAX_VOLUME_NUM; i++)
{
FsmVolumes[i].DevObjP = NULL;
FsmVolumes[i].FsDrvP = NULL;
FsmVolumes[i].RefCnt = 0;
FsmVolumes[i].VolName[0] = 0;
}
/* initialize the VFD structure */
for (i = 0; i < MAX_VFS_FD; i++)
{
FsmVfsFds[i].ErrorCode = 0;
FsmVfsFds[i].LowerFd = -1;
FsmVfsFds[i].VolumeP = NULL;
FsmVfsFds[i].Flag = VFD_FLAG_FREE;
FsmVfsFds[i].MutexSem = 0;
}
FsmVolumeMtxSem = FsmCreateMtxSem(1);
if(FsmVolumeMtxSem == NULL)
{
return ERR_SYSTEM;
}
FsmVfsMtxSem = FsmCreateMtxSem(1);
if(FsmVfsMtxSem == NULL)
{
FsmDeleteMtxSem(FsmVolumeMtxSem);
return ERR_SYSTEM;
}
for (i = 0; i < MAX_VFS_FD; i++)
{
FsmVfsFds[i].MutexSem = FsmCreateMtxSem(1);
if(FsmVfsFds[i].MutexSem == NULL)
break;
}
if(i < MAX_VFS_FD)
{
while(i > 0)
{
FsmDeleteMtxSem(FsmVfsFds[i - 1].MutexSem);
FsmVfsFds[i - 1].MutexSem = NULL;
i--;
}
FsmDeleteMtxSem(FsmVfsMtxSem);
FsmDeleteMtxSem(FsmVolumeMtxSem);
return ERR_SYSTEM;
}
return ERR_NONE;
}
/*#############################################################################
### FsmVfsExit
###
### DESCRIPTION:
### release resources allocated when vfs startup.
###
### PARAMETERS:
### IN:
###
### OUT:
###
### RETURNS:
### Returns the following errors codes:
### ERR_NONE
###
*/
uint32 FsmVfsExit()
{
uint32 i;
i = MAX_VFS_FD;
while(i > 0)
{
FsmDeleteMtxSem(FsmVfsFds[i - 1].MutexSem);
FsmVfsFds[i - 1].MutexSem = NULL;
i--;
}
FsmDeleteMtxSem(FsmVfsMtxSem);
FsmDeleteMtxSem(FsmVolumeMtxSem);
return ERR_NONE;
}
/***********************************************************************
* Function Name: FsmOpen
* Description : Open a file, return the file descriptor
* Arguments : path : file path
* : mode : open mode
* First Edit 2003.8.13 wsm
* note: a path end with slash is illegal!
*/
uint32 FsmOpen(const char * filename, uint32 mode)
{
uint32 status;
uint32 VolIndex;
FsmFsDrvT * FsP;
uint32 vfd;
uint32 lfd;
char * path;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmOpen in %s,%d :Open file|dir %s \n", __FILE__, __LINE__, filename);
#endif
if(strlen(filename) > MAX_PATH_LENGTH)
{
return INVALID_FILE_HANDLE;
}
status = mode & FSM_OPEN_MODE_MASK;
if((status != FSM_OPEN_ALWAYS)
&& (status != FSM_OPEN_EXISTING)
&& (status != FSM_CREATE_NEW)
&& (status != FSM_CREATE_ALWAYS))
{
return INVALID_FILE_HANDLE;
}
path = (char *)filename;
if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
{
return INVALID_FILE_HANDLE;
}
VolIndex = FsmGetMatchedVolume(&path);
if (VolIndex == MAX_VOLUME_NUM)
{
FsmReleaseMtxSem(FsmVolumeMtxSem);
return INVALID_FILE_HANDLE;
}
FsmVolumes[VolIndex].RefCnt++; /* prevent volume from being unmounted. */
FsP = FsmVolumes[VolIndex].FsDrvP; /* it can be moved out of the lock protecting. */
FsmReleaseMtxSem(FsmVolumeMtxSem);
/*
if (FsP == NULL)
{
goto Open_Exit;
}
*/
vfd = FsmAllocVfd();
if (vfd == INVALID_FILE_HANDLE)
{
goto Open_Exit;
}
status = FsmGetMtxSem(FsmVfsFds[vfd].MutexSem);
if(status != ERR_NONE)
{
FsmFreeVfd(vfd);
goto Open_Exit;
}
FsmVfsFds[vfd].LowerFd = (uint32)(-1);
FsmVfsFds[vfd].VolumeP = &FsmVolumes[VolIndex];
FsmVfsFds[vfd].ErrorCode = ERR_NONE;
lfd = FsP->FsmOpen( FsmVolumes[VolIndex].DevObjP,
path,
(mode & FSM_ACCESS_MODE_MASK) | FSM_OPEN_EXISTING | FSM_OPEN_FILE,
&status
);
if (lfd != INVALID_FILE_HANDLE)
{
switch(mode & FSM_OPEN_MODE_MASK)
{
case FSM_OPEN_ALWAYS:
/* pass through. */
case FSM_OPEN_EXISTING:
FsmVfsFds[vfd].LowerFd = lfd;
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
return vfd;
break;
case FSM_CREATE_NEW:
FsP->FsmClose(lfd);
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
FsmFreeVfd(vfd);
goto Open_Exit;
break;
case FSM_CREATE_ALWAYS:
FsmVfsFds[vfd].LowerFd = lfd;
FsmTruncate(vfd, 0);
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
return vfd;
break;
default:
FsP->FsmClose(lfd);
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
FsmFreeVfd(vfd);
MonPrintf("\nOops, a bug is here! Invalid open mode in FsmOpen()");
goto Open_Exit;
break;
}
}
else
{
switch(mode & FSM_OPEN_MODE_MASK)
{
case FSM_OPEN_EXISTING:
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
FsmFreeVfd(vfd);
goto Open_Exit;
break;
case FSM_OPEN_ALWAYS:
case FSM_CREATE_NEW:
case FSM_CREATE_ALWAYS:
if(status == ERR_NOTEXIST)
{
lfd = FsP->FsmCreate( FsmVolumes[VolIndex].DevObjP,
path,
mode | FSM_OPEN_FILE,
&status
);
if(lfd != INVALID_FILE_HANDLE)
{
FsmVfsFds[vfd].LowerFd = lfd;
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
return vfd;
}
}
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
FsmFreeVfd(vfd);
goto Open_Exit;
break;
default:
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
FsmFreeVfd(vfd);
MonPrintf("\nOops, a bug is here! Invalid open mode in FsmOpen()");
goto Open_Exit;
break;
}
}
Open_Exit:
FsmGetMtxSem(FsmVolumeMtxSem);
FsmVolumes[VolIndex].RefCnt--;
FsmReleaseMtxSem(FsmVolumeMtxSem);
return INVALID_FILE_HANDLE;
}
/*
* Function Name: FsmClose
* Description : Close a file, return the error code
* Arguments : path : file path
* : mode : open mode
* First Edit 2003.8.13 wsm
*/
uint32 FsmClose(uint32 fd)
{
uint32 status;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmClose in %s,%d \n", __FILE__, __LINE__);
#endif
if(fd >= MAX_VFS_FD)
{
return ERR_PARAM;
}
if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
{
return status;
}
if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
|| (FsmVfsFds[fd].VolumeP == NULL))
{
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return ERR_PARAM;
}
status = FsmVfsFds[fd].VolumeP->FsDrvP->FsmClose(FsmVfsFds[fd].LowerFd);
if(status == ERR_NONE)
{
FsmVfsFds[fd].LowerFd = (uint32)(-1);
}
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
if(status == ERR_NONE)
{
FsmVolumeT * VolumeP;
VolumeP = FsmVfsFds[fd].VolumeP;
FsmFreeVfd(fd);
FsmGetMtxSem(FsmVolumeMtxSem);
VolumeP->RefCnt--;
FsmReleaseMtxSem(FsmVolumeMtxSem);
}
return status;
}
/*
* Function Name: FsmCloseAll
* Description : Close all files, return the error code
* Arguments :
* First Edit 2003.8.13 wsm
*/
uint32 FsmCloseAll()
{
/* uint32 status; */
uint32 fd;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmClose in %s,%d \n", __FILE__, __LINE__);
#endif
/*
// prevent FsmOpen from being called.
if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
{
return status;
}*/
for (fd = 0; fd < MAX_VFS_FD; fd++)
{
FsmClose(fd);
}
/* FsmReleaseMtxSem(FsmVolumeMtxSem); */
return ERR_NONE;
}
/*
* Function Name: FsmRead
* Description : Read from file, return the readed size
* Arguments : fd : file descriptor
* : buffer : content buffer
* : size : read size
* First Edit 2003.7.23 wsm
*/
uint32 FsmRead(uint32 fd, void * buffer, uint32 size)
{
uint32 status;
FsmFsDrvT * FsP;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmRead in %s,%d \n", __FILE__, __LINE__);
#endif
if (fd >= MAX_VFS_FD)
{
return 0;
}
if (size == 0)
{
FsmVfsFds[fd].ErrorCode = ERR_NONE;
return 0;
}
if (buffer == NULL)
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
return 0;
}
if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
{
FsmVfsFds[fd].ErrorCode = status;
return 0;
}
if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
|| (FsmVfsFds[fd].VolumeP == NULL))
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return 0;
}
FsP = FsmVfsFds[fd].VolumeP->FsDrvP;
size = FsP->FsmRead( FsmVfsFds[fd].LowerFd, buffer, size, &status);
FsmVfsFds[fd].ErrorCode = status;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return size;
}
/*
* Function Name: FsmWrite
* Description : Write to a file, return the wrote size
* Arguments : fd : file descriptor
* : buffer : content buffer
* : size : write size
* First Edit 2003.7.23 wsm
*/
uint32 FsmWrite(uint32 fd, void * buffer, uint32 size)
{
uint32 status;
FsmFsDrvT * FsP;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmWrite in %s,%d \n", __FILE__, __LINE__);
#endif
if (fd >= MAX_VFS_FD)
{
return 0;
}
if (size == 0)
{
FsmVfsFds[fd].ErrorCode = ERR_NONE;
return 0;
}
if (buffer == NULL)
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
return 0;
}
if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
{
FsmVfsFds[fd].ErrorCode = status;
return 0;
}
if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
|| (FsmVfsFds[fd].VolumeP == NULL))
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return 0;
}
FsP = FsmVfsFds[fd].VolumeP->FsDrvP;
size = FsP->FsmWrite(FsmVfsFds[fd].LowerFd, buffer, size, &status);
FsmVfsFds[fd].ErrorCode = status;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return size;
}
/*
* Function Name: FsmSeek
* Description : Shift a file offset, return the error code
* Arguments : fd : file descriptor
* : offset : the shift size
* : whence : base position
* First Edit 2003.7.23 wsm
*/
uint32 FsmSeek(uint32 fd, int32 offset, uint32 whence)
{
uint32 status;
FsmFsDrvT * FsP;
FsmIoctlSeekT arg;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmSeek in %s,%d \n", __FILE__, __LINE__);
#endif
if (fd >= MAX_VFS_FD)
{
return ERR_PARAM;
}
if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
{
FsmVfsFds[fd].ErrorCode = status;
return status;
}
if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
|| (FsmVfsFds[fd].VolumeP == NULL))
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return ERR_PARAM;
}
FsP = FsmVfsFds[fd].VolumeP->FsDrvP;
arg.offset = offset;
arg.whence = whence;
status = FsP->FsmIoCtrl(FsmVfsFds[fd].LowerFd, FSM_IOCTL_SEEK, (void *)&arg);
FsmVfsFds[fd].ErrorCode = status;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return status;
}
/*
* Function Name: FsmTell
* Description : get the file offset
* Arguments : fd : file descriptor
* First Edit 2003.7.23 wsm
*/
int32 FsmTell(uint32 fd)
{
uint32 status;
FsmFsDrvT * FsP;
uint32 pos;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmTell in %s,%d \n", __FILE__, __LINE__);
#endif
if (fd >= MAX_VFS_FD)
{
return -1;
}
if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
{
FsmVfsFds[fd].ErrorCode = status;
return -1;
}
if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
|| (FsmVfsFds[fd].VolumeP == NULL))
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return -1;
}
FsP = FsmVfsFds[fd].VolumeP->FsDrvP;
status = FsP->FsmIoCtrl(FsmVfsFds[fd].LowerFd, FSM_IOCTL_TELL, &pos);
FsmVfsFds[fd].ErrorCode = status;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
if(status == ERR_NONE)
return pos;
else
return -1;
}
/*
* Function Name: FsmEof
* Description : if the offset reac the end of file
* Arguments : fd : file descriptor
* First Edit 2003.7.23 wsm
*/
uint32 FsmEof(uint32 fd, uint32 * Eof)
{
uint32 status;
FsmFsDrvT * FsP;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmError in %s,%d \n", __FILE__, __LINE__);
#endif
*Eof = FALSE;
if (fd >= MAX_VFS_FD)
{
return ERR_PARAM;
}
if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
{
FsmVfsFds[fd].ErrorCode = status;
return status;
}
if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
|| (FsmVfsFds[fd].VolumeP == NULL))
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return ERR_PARAM;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -