📄 fsmvfs.c
字号:
{
return ERR_PARAM;
}
if(VolumeName == NULL)
return ERR_PARAM;
path = (char *)VolumeName;
if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
{
return status;
}
VolIndex = FsmGetMatchedVolume(&path);
if (VolIndex == MAX_VOLUME_NUM)
{
FsmReleaseMtxSem(FsmVolumeMtxSem);
return ERR_PARAM;
}
FsmVolumes[VolIndex].RefCnt++; /* prevent volume from being unmounted. */
FsP = FsmVolumes[VolIndex].FsDrvP;
FsmReleaseMtxSem(FsmVolumeMtxSem);
GetFreeSpace.total_space = total_space;
GetFreeSpace.avail_space = avail_space;
GetFreeSpace.free_space = free_space;
GetFreeSpace.DevObjP = FsmVolumes[VolIndex].DevObjP;
status = FsP->FsmIoCtrl(INVALID_FILE_HANDLE, FSM_IOCTL_GET_FREE_SPACE, (void *)&GetFreeSpace);
FsmGetMtxSem(FsmVolumeMtxSem);
FsmVolumes[VolIndex].RefCnt--;
FsmReleaseMtxSem(FsmVolumeMtxSem);
return status;
}
/*
* Function Name: FsmMount
* Description : Delete a empty directory
* Arguments : pFs : fiel systme object
* : pDev : device object
* : name : mount path
* : sectorsize : sector size in bytes
* First Edit 2003.8.13 wsm
*/
uint32 FsmMount(FsmFsDrvT * pFs, FsmDevObjHdrT * pDev, const char * name, uint32 sectorsize)
{
uint32 status;
uint32 i;
uint32 j;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmMount in %s,%d :Mount %s\n", __FILE__, __LINE__, name);
#endif
if ((pDev == NULL) || (pFs == NULL) || (name == NULL))
{
return ERR_PARAM;
}
if(GetFirstPath(name, &i, &j) == 0)
{
return ERR_PARAM; /* invalid volume name */
}
if(strlen(name) != j)
{
return ERR_PARAM;
}
FsmGetMtxSem(FsmVolumeMtxSem);
/* if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
{
return status;
}*/
for(i = 0; i < MAX_VOLUME_NUM; i++ )
{
if (strcmp(FsmVolumes[i].VolName, name) == 0 )
{
FsmReleaseMtxSem(FsmVolumeMtxSem);
return ERR_EXIST; /* volume in use */
}
if (FsmVolumes[i].DevObjP == pDev )
{
FsmReleaseMtxSem(FsmVolumeMtxSem);
return ERR_MOUNTED; /* device in use */
}
}
for(i = 0; i < MAX_VOLUME_NUM; i++ )
{
if (FsmVolumes[i].VolName[0] == 0 )
{
j = i; /* get a empty volume */
break;
}
}
if (i >= MAX_VOLUME_NUM)
{
FsmReleaseMtxSem(FsmVolumeMtxSem);
return ERR_MAX_VOLUME;
}
status = pFs->FsmInit(pDev, sectorsize);
if(status == ERR_NONE)
{
FsmVolumes[j].DevObjP = pDev;
FsmVolumes[j].FsDrvP = pFs;
strcpy(FsmVolumes[j].VolName, name);
}
else
{
FsmVolumes[j].VolName[0] = 0;
FsmVolumes[j].FsDrvP = NULL;
FsmVolumes[j].DevObjP = NULL;
}
FsmVolumes[j].RefCnt = 0;
FsmReleaseMtxSem(FsmVolumeMtxSem);
return status;
}
/*
* Function Name: FsmUnMount
* Description : Delete a empty directory
* Arguments : name : volumn name (path)
* First Edit 2003.8.13 wsm
*/
uint32 FsmUnMount(const char * path)
{
uint32 status = ERR_NONE;
uint32 VolIndex;
FsmFsDrvT * FsP;
FsmDevObjHdrT * DevP;
char * name;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmUnMount in %s,%d :Unmount %s\n", __FILE__, __LINE__, path);
#endif
name = (char *)path;
FsmGetMtxSem(FsmVolumeMtxSem);
/* If it is called when system starts, FsmGetMtxSem always fails.
status = FsmGetMtxSem(FsmVolumeMtxSem);
if(status != ERR_NONE)
{
return status;
}
*/
VolIndex = FsmGetMatchedVolume(&name);
if (VolIndex == MAX_VOLUME_NUM)
{
status = ERR_PARAM;
goto FsmUnMount_Exit;
}
/* ensure that all files opened externally have been closed. */
if(FsmVolumes[VolIndex].RefCnt > 0)
{
status = ERR_ACCESS_DENY;
goto FsmUnMount_Exit;
}
FsP = FsmVolumes[VolIndex].FsDrvP;
DevP = FsmVolumes[VolIndex].DevObjP;
/* we should be sure that all files opened from */
/* this device internally also have been closed. */
status = FsP->FsmTerminate(DevP);
if(status == ERR_NONE)
{
FsmVolumes[VolIndex].VolName[0] = 0;
FsmVolumes[VolIndex].DevObjP = NULL;
FsmVolumes[VolIndex].FsDrvP = NULL;
}
FsmUnMount_Exit:
FsmReleaseMtxSem(FsmVolumeMtxSem);
return status;
}
/*
* Function Name: FsmFileIoCtrl
* Description : send command to the file
* Arguments : fd : file descriptor
* : cmd : command
* : arg : argument pointer
* First Edit 2003.8.13 wsm
*/
uint32 FsmFileIoCtrl(uint32 fd, uint32 cmd, void * arg)
{
uint32 status;
FsmFsDrvT * FsP;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmFileIoCtrl 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;
status = FsP->FsmIoCtrl(FsmVfsFds[fd].LowerFd, cmd, arg);
FsmVfsFds[fd].ErrorCode = status;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return status;
}
/*
* Function Name: FsmOpenDir
* Description : open a directory for read operation
* Arguments : path : directory path
* First Edit 2003.8.13 wsm
*/
uint32 FsmOpenDir(const char * dirname)
{
uint32 status;
uint32 VolIndex;
FsmFsDrvT * FsP;
uint32 vfd;
uint32 lfd;
char * path;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmOpenDir in %s,%d :OpenDir %s \n", __FILE__, __LINE__, dirname);
#endif
if(strlen(dirname) > MAX_PATH_LENGTH)
{
return INVALID_FILE_HANDLE;
}
path = (char *)dirname;
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;
FsmReleaseMtxSem(FsmVolumeMtxSem);
vfd = FsmAllocVfd();
if (vfd == INVALID_FILE_HANDLE)
{
goto OpenDir_Exit;
}
status = FsmGetMtxSem(FsmVfsFds[vfd].MutexSem);
if(status != ERR_NONE)
{
FsmFreeVfd(vfd);
goto OpenDir_Exit;
}
FsmVfsFds[vfd].LowerFd = (uint32)(-1);
FsmVfsFds[vfd].VolumeP = &FsmVolumes[VolIndex];
FsmVfsFds[vfd].ErrorCode = ERR_NONE;
lfd = FsP->FsmOpen( FsmVolumes[VolIndex].DevObjP,
path,
FSM_OPEN_DIR | FSM_OPEN_READ | FSM_OPEN_EXISTING,
&status
);
if(lfd != INVALID_FILE_HANDLE)
{
FsmVfsFds[vfd].LowerFd = lfd;
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
return vfd;
}
FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
FsmFreeVfd(vfd);
OpenDir_Exit:
FsmGetMtxSem(FsmVolumeMtxSem);
FsmVolumes[VolIndex].RefCnt--;
FsmReleaseMtxSem(FsmVolumeMtxSem);
return INVALID_FILE_HANDLE;
}
/*
* Function Name: FsmReadDir
* Description : open a directory for read operation
* Arguments : DirId : directory descriptor
* : direntry : directory info buffer
* First Edit 2003.8.13 wsm
*/
uint32 FsmReadDir(uint32 fd, FsmFileInfoT * FileInfo)
{
uint32 status;
FsmFsDrvT * FsP;
uint32 size;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmReadDir in %s,%d \n", __FILE__, __LINE__);
#endif
if (fd >= MAX_VFS_FD)
{
return ERR_PARAM;
}
if (FileInfo == NULL)
{
FsmVfsFds[fd].ErrorCode = ERR_PARAM;
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;
size = FsP->FsmRead( FsmVfsFds[fd].LowerFd,
(uint8 *)FileInfo,
sizeof(FsmFileInfoT),
&status
);
FsmVfsFds[fd].ErrorCode = status;
FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
return status;
}
/*
* Function Name: FsmCloseDir
* Description : close an opened directory
* Arguments : DirId : directory descriptor
* First Edit 2003.8.13 wsm
*/
uint32 FsmCloseDir(uint32 fd)
{
return FsmClose(fd);
}
/*********************************************
*
* Function Name: FsmFormat
*
* Description : format the flash
* Arguments : VolumeName
*
* First Edit 2003.8.13 wsm
*
* anyhow, you should reboot the
* system after this function is called
**********************************************/
uint32 FsmFormat(FsmFormatArgumentT * FormatArg)
{
uint32 status = ERR_NONE;
uint32 VolIndex;
FsmFsDrvT * FsP;
FsmDevObjHdrT * DevP;
char * name;
#ifdef FSM_DEBUG
MonPrintf("Interface FsmFormat :Format\n");
#endif
if (FormatArg == NULL)
{
return ERR_PARAM;
}
if (FormatArg->mode == FSM_FORMAT_NAME)
{
name = FormatArg->Param.VolumeName;
status = FsmGetMtxSem(FsmVolumeMtxSem);
if(status != ERR_NONE)
{
return status;
}
VolIndex = FsmGetMatchedVolume(&name);
if (VolIndex == MAX_VOLUME_NUM)
{
status = ERR_PARAM;
FsmReleaseMtxSem(FsmVolumeMtxSem);
return status;
}
FsP = FsmVolumes[VolIndex].FsDrvP;
DevP = FsmVolumes[VolIndex].DevObjP;
FsmReleaseMtxSem(FsmVolumeMtxSem);
status = FsmUnMount(FormatArg->Param.VolumeName);
if(status != ERR_NONE)
{
return status;
}
}
else if (FormatArg->mode == FSM_FORMAT_DEV)
{
uint32 i;
/* maybe the volume has been mounted successful */
DevP = FormatArg->Param.DevArg.DevP;
FsP = FormatArg->Param.DevArg.FsP;
status = FsmGetMtxSem(FsmVolumeMtxSem);
/*
if(status != ERR_NONE)
{
return status;
}
*/
for(i = 0; i < MAX_VOLUME_NUM; i++)
{
if(FsmVolumes[i].DevObjP == DevP)
{
break;
}
}
FsmReleaseMtxSem(FsmVolumeMtxSem);
if(i < MAX_VOLUME_NUM)
{
status = FsmUnMount(FsmVolumes[i].VolName);
if(status != ERR_NONE)
{
return status;
}
}
}
else
{
return ERR_PARAM;
}
/* The data item always coexist on the same device with data file system. */
if (DevP == FsmDataItemDevObjP)
{
status = FsmDataItemExit();
if(status != ERR_NONE)
{
return status;
}
}
status = FsP->FsmIoCtrl(INVALID_FILE_HANDLE, FSM_IOCTL_FORMAT, (void *)DevP);
return status;
}
/*------------------------- local function --------------------------*/
static uint32 FsmAllocVfd()
{
uint32 i;
if (FsmGetMtxSem(FsmVfsMtxSem) != ERR_NONE)
{
#ifdef FSM_DEBUG
MonPrintf("VFDLock semaphore fail!\n");
#endif
return INVALID_FILE_HANDLE;
}
for (i = 0; i < MAX_VFS_FD; i++ )
{
if (FsmVfsFds[i].Flag == VFD_FLAG_FREE)
{
FsmVfsFds[i].Flag = VFD_FLAG_IN_USE;
FsmReleaseMtxSem(FsmVfsMtxSem);
return i;
}
}
FsmReleaseMtxSem(FsmVfsMtxSem);
return INVALID_FILE_HANDLE;
}
static uint32 FsmFreeVfd(uint32 vfd)
{
uint32 status;
if (vfd >= MAX_VFS_FD)
{
return ERR_PARAM;
}
if ((status = FsmGetMtxSem(FsmVfsMtxSem)) != ERR_NONE )
{
#ifdef FSM_DEBUG
MonPrintf("VFDLock semaphore fail!\n");
#endif
return status;
}
FsmVfsFds[vfd].LowerFd = (uint32)(-1);
FsmVfsFds[vfd].VolumeP = NULL;
FsmVfsFds[vfd].ErrorCode = 0;
FsmVfsFds[vfd].Flag = VFD_FLAG_FREE;
FsmReleaseMtxSem(FsmVfsMtxSem);
return ERR_NONE;
}
/* The caller of this function should be
* responsible for obtaining the FsmVolumeMtxSem
* semaphore before call this function. */
static uint32 FsmGetMatchedVolume (char ** path)
{
uint32 i, j;
uint32 volume_len;
uint32 offset;
if(GetFirstPath(*path, &offset, &volume_len) == 0)
{
return MAX_VOLUME_NUM;
}
/*
if (FsmGetMtxSem(FsmVolumeMtxSem) != ERR_NONE )
{
return MAX_VOLUME_NUM;
}
*/
for (i = 0; i < MAX_VOLUME_NUM; i++ )
{
if (strlen(FsmVolumes[i].VolName) == volume_len )
{
for (j = 0; j < volume_len; j++ )
{
if (FsmVolumes[i].VolName[j] != (*path)[offset + j] )
{
break;
}
}
if( j >= volume_len)
{
(*path) += (offset + volume_len);
break;
/*
FsmReleaseMtxSem(FsmVolumeMtxSem);
return i;
*/
}
}
}
/*
FsmReleaseMtxSem(FsmVolumeMtxSem);
*/
return i;
/* return MAX_VOLUME_NUM; */
}
/*****************************************************************************
* $Log: FsmVfs.c $
* Revision 1.3.1.2 2004/04/05 12:31:24 zgy
* Modify FsmFormat.
* Revision 1.3.1.1 2004/03/17 12:58:53 zgy
* Duplicate revision
* Revision 1.3 2004/03/17 12:58:53 zgy
* Revision 1.29 2004/03/16 16:00:50 jjs
* Revision 1.28 2004/03/11 14:51:49 jjs
* Added vfs initialize function
* Revision 1.27 2003/11/25 16:02:48 wsm
* 1.remove fsmformat (use extern dfsformat to use it)
* Revision 1.26 2003/11/05 11:37:38 jjs
* Revision 1.25 2003/11/05 11:25:30 jjs
* replaced //
* Revision 1.23 2003/10/26 17:00:37 jjs
* Fixed the return code bug in FsmEof function. Updated the funtion prototype.
* Revision 1.22 2003/10/26 11:25:57 jjs
* Revision 1.21 2003/10/26 11:14:14 jjs
* Revision 1.20 2003/10/24 17:08:30 jjs
* added Support for Volume format.
* Revision 1.19 2003/10/22 10:40:31 jjs
* Added support for 16-byte file name searching.
* Revision 1.18 2003/10/15 18:22:29 jjs
* Revision 1.17 2003/10/08 18:07:34 jjs
* Revision 1.16 2003/10/08 17:29:12 jjs
* Revision 1.15 2003/10/08 12:46:16 jjs
* Revision 1.14 2003/09/20 16:58:14 wsm
* Revision 1.13 2003/09/20 12:36:19 wsm
* Revision 1.12 2003/09/19 11:26:19 wsm
* Revision 1.11 2003/09/16 17:12:39 wsm
* Revision 1.10 2003/09/16 11:36:03 wsm
* Revision 1.9 2003/09/15 14:40:38 wsm
* Revision 1.8 2003/09/15 10:00:23 wsm
* Revision 1.7 2003/09/14 16:55:45 jjs
* Revision 1.6 2003/09/12 15:27:56 wsm
* Revision 1.5 2003/09/12 15:05:27 wsm
* Revision 1.4 2003/09/11 15:05:58 wsm
* update out put message
* Revision 1.3 2003/09/11 09:58:17 wsm
* update the Macro name
* Revision 1.2 2003/09/10 19:11:13 wsm
* update
* Revision 1.1 2003/09/09 15:07:32 wsm
* Initial revision
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -