📄 fsmdfs.c
字号:
FsmDfsFds[fd].FilePointer = 0; /* offset into sector. */
}
else
{
status = ERR_PARAM;
goto DfsOpen_Exit2;
}
/* FsmDfsFds[fd].AccessMode = mode; */
FsmDfsFds[fd].FirstLsn = entry.FirstLsn;
FsmDfsFds[fd].ParentDirFirstLsn = ParentDirFirstLsn;
FsmDfsFds[fd].CreateDate = entry.Date;
FsmDfsFds[fd].CreateTime = entry.Time;
FsmDfsFds[fd].Attrib = entry.Type;
DfsOpen_Exit_Success:
FsmDfsFds[fd].Flag = DFD_FLAG_IN_USE; /* prevent from being preempted. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
if(ErrorCodeP != NULL)
*ErrorCodeP = ERR_NONE;
return fd;
DfsOpen_Exit2:
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
DfsFreeFd(fd);
DfsOpen_Exit:
if(ErrorCodeP != NULL)
*ErrorCodeP = status;
return INVALID_FILE_HANDLE;
}
/*
* Function Name: DfsRead
* Description : Read from a file or directory , implement the read interface
* Arguments : fd : file descriptor
* : buffer : content buffer
* : size : read size
* First Edit 2003.8.13 wsm
*/
uint32 FsmDfsRead(uint32 fd, uint8 * buf, uint32 size, uint32 *ErrorCode)
{
uint32 status;
FsmDevObjHdrT * DevP;
FsmFlashMediaT * MediaP;
#ifdef FSM_DEBUG
MonPrintf("Interface DfsRead\n");
#endif
if (fd >= MAX_DFS_FD)
{
status = ERR_PARAM;
goto DfsRead_Exit;
}
if(FsmDfsFds[fd].Flag != DFD_FLAG_IN_USE)
{
status = ERR_PARAM;
goto DfsRead_Exit;
}
if(size == 0)
{
if(ErrorCode != NULL)
{
*ErrorCode = ERR_NONE;
}
return 0;
}
if(buf == NULL)
{
status = ERR_PARAM;
goto DfsRead_Exit;
}
/* Get the semaphore of this file. */
status = FsmGetMtxSem(FsmDfsFds[fd].MutexSem);
if(status != ERR_NONE)
{
goto DfsRead_Exit;
}
/* CHECK if the fd is in PENDING or FREE state. */
if(FsmDfsFds[fd].Flag != DFD_FLAG_IN_USE)
{
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
status = ERR_PARAM;
goto DfsRead_Exit;
}
DevP = FsmDfsFds[fd].FdHdr.DevObjP;
MediaP = (FsmFlashMediaT *)DevP->MediaObjP;
/* if read directory entry. */
if (FsmDfsFds[fd].Attrib == ENTRY_TYPE_SUBDIR)
{
uint32 SectorLsn;
uint32 sector_offset;
FsmFileDirEntryT entry;
/*
* For directory fd, FileLength field stores
* Sector LSN for next directory entry read.
*/
SectorLsn = FsmDfsFds[fd].FileLength;
sector_offset = FsmDfsFds[fd].FilePointer;
/*
if ((status = FsmGetMtxSem(MediaP->MapTblLock)) != ERR_NONE)
{
// Release the semaphore of this file.
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
goto DfsRead_Exit;
}
*/
status = DfsReadFileEntry(DevP, &SectorLsn, §or_offset, &entry);
/*
FsmReleaseMtxSem(MediaP->MapTblLock);
*/
if(status != ERR_NONE)
{
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
goto DfsRead_Exit;
}
sector_offset += sizeof(FsmFileDirEntryT);
FsmDfsFds[fd].FileLength = SectorLsn;
FsmDfsFds[fd].FilePointer = sector_offset;
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
((FsmFileInfoT *)buf)->FileLength = entry.Length;
((FsmFileInfoT *)buf)->CreateDate = entry.Date;
((FsmFileInfoT *)buf)->CreateTime = entry.Time;
((FsmFileInfoT *)buf)->Attrib = entry.Type;
FsmMemoryMove((uint8 *)((FsmFileInfoT *)buf)->FileName,
(uint8 *)entry.FileName,
FIELD_SIZE(FsmFileDirEntryT, FileName)
);
((FsmFileInfoT *)buf)->FileName[FIELD_SIZE(FsmFileDirEntryT, FileName)] = 0;
switch(((FsmFileInfoT *)buf)->Attrib)
{
case ENTRY_TYPE_SUBDIR:
((FsmFileInfoT *)buf)->Attrib = FSM_FILE_ATTRIB_DIR;
break;
case ENTRY_TYPE_FILE:
((FsmFileInfoT *)buf)->Attrib = FSM_FILE_ATTRIB_ARCHIVE;
break;
default:
#if (OS_TYPE == OS_WINDOWS)
ASSERT(0);
#endif
break;
}
if(ErrorCode != NULL)
{
*ErrorCode = ERR_NONE;
}
return sizeof(FsmFileInfoT);
}
else /* read file. */
{
uint32 read_size;
if(FsmDfsFds[fd].FileLength <= FsmDfsFds[fd].FilePointer)
{
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
status = ERR_EOF;
goto DfsRead_Exit;
}
read_size = FsmDfsFds[fd].FileLength - FsmDfsFds[fd].FilePointer;
if(read_size < size)
{
size = read_size;
}
read_size = 0;
if ((status = FsmGetMtxSem(MediaP->MapTblLock)) != ERR_NONE)
{
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
goto DfsRead_Exit;
}
status = DfsReadData( DevP,
buf,
FsmDfsFds[fd].FirstLsn,
FsmDfsFds[fd].FilePointer,
size,
&read_size
);
if((status != ERR_NONE) && (status != ERR_EOF))
{
FsmReleaseMtxSem(MediaP->MapTblLock);
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
goto DfsRead_Exit; /* return zero. */
/*
if(ErrorCode != NULL)
{
*ErrorCode = status;
}
return read_size;
*/
}
/* merge the content in queue */
status = QueueReadData(QUEUE_FILE_DIR, fd, FsmDfsFds[fd].FilePointer, buf, size, &read_size);
FsmReleaseMtxSem(MediaP->MapTblLock);
if (status == ERR_NONE)
{
FsmDfsFds[fd].FilePointer += read_size;
}
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
if (ErrorCode != NULL)
{
*ErrorCode = status;
}
return read_size;
}
DfsRead_Exit:
if(ErrorCode != NULL)
{
*ErrorCode = status;
}
return 0;
}
/*
* Function Name: DfsWrite
* Description : Write to a file , implement the write interface
* Arguments : fd : file descriptor
* : buffer : content buffer
* : size : write size
* First Edit 2003.8.13 wsm
*/
uint32 FsmDfsWrite(uint32 fd, uint8 * buf, uint32 size, uint32 *ErrorCode)
{
uint32 status;
FsmFlashMediaT * MediaP;
uint32 AvailSpace;
uint32 needSpace;
uint32 append_size;
uint32 modify_size;
uint32 write_size;
FsmDfsFileDescriptorT * FdP;
#ifdef FSM_DEBUG
MonPrintf("Interface DfsWrite\n");
#endif
if (fd >= MAX_DFS_FD)
{
status = ERR_PARAM;
goto DfsWrite_Exit;
}
FdP = &FsmDfsFds[fd];
if(FdP->Flag != DFD_FLAG_IN_USE)
{
status = ERR_PARAM;
goto DfsWrite_Exit;
}
/* Get the semaphore of this file. */
status = FsmGetMtxSem(FdP->MutexSem);
if(status != ERR_NONE)
{
goto DfsWrite_Exit;
}
/* CHECK if the fd is in PENDING or FREE state. */
if(FdP->Flag != DFD_FLAG_IN_USE)
{
status = ERR_PARAM;
goto DfsWrite_Exit1;
}
/* check if the operation is permitted. */
if ((FdP->AccessMode & FSM_OPEN_WRITE) != FSM_OPEN_WRITE)
{
status = ERR_ACCESS_DENY;
goto DfsWrite_Exit1;
}
if ((FdP->AccessMode & FSM_OPEN_DIR) == FSM_OPEN_DIR)
{
status = ERR_ACCESS_DENY;
goto DfsWrite_Exit1;
}
if(size == 0)
{
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FdP->MutexSem);
if(ErrorCode != NULL)
{
*ErrorCode = ERR_NONE;
}
return 0;
}
if(buf == NULL)
{
status = ERR_PARAM;
goto DfsWrite_Exit1;
}
#ifdef DFS_DIR_LOCK_ENABLED
/* !!!!!!!!!! NOTE !!!!!!!!!*/
/*
* We have kept the file semaphore.
* Care should be taken to avoid deadlock.
*/
/* check the directory operation */
if ((status = FsmGetMtxSem(FsmDfsMtxSem)) != ERR_NONE )
{
goto DfsWrite_Exit1;
}
if (DfsIsParentDirOpened(FdP->PathName) != 0)
{
FsmReleaseMtxSem(FsmDfsMtxSem);
status = ERR_ACCESS_DENY;
goto DfsWrite_Exit1;
}
FsmReleaseMtxSem(FsmDfsMtxSem);
#endif /* DFS_DIR_LOCK_ENABLED */
MediaP = (FsmFlashMediaT *)(FdP->FdHdr.DevObjP->MediaObjP);
/* space calualation */
AvailSpace = DfsAvailSpaceCalc(MediaP);
append_size = 0;
modify_size = 0;
if((FdP->FilePointer + size) > FdP->FileLength)
{
append_size = (FdP->FilePointer + size) - FdP->FileLength;
modify_size = FdP->FileLength - FdP->FilePointer;
}
else
{
modify_size = size;
}
needSpace = 0;
if(modify_size > 0)
{
needSpace += ACCUM_CNT_MODIFY;
needSpace += ACCUM_CNT_MODIFY_RESERVED(FdP->FilePointer,
modify_size,
MediaP->SectorSize);
}
if(append_size > 0)
{
needSpace += ACCUM_CNT_APPEND(FdP->FileLength, append_size, MediaP->SectorSize);
}
if (AvailSpace < needSpace)
{
status = ERR_FULL;
goto DfsWrite_Exit1;
}
write_size = 0;
if(modify_size > 0)
{
/* add the modify to write queue */
status = QueueAddFileDir(CMD_MODIFY, fd, FdP->FilePointer, buf, modify_size);
if (status != ERR_NONE)
{
goto DfsWrite_Exit1;
}
buf += modify_size;
FdP->FilePointer += modify_size;
write_size += modify_size;
}
if(append_size > 0)
{
status = QueueAddFileDir(CMD_APPEND, fd, FdP->FilePointer, buf, append_size);
if (status == ERR_NONE)
{
FdP->FilePointer += append_size;
FdP->FileLength += append_size;
write_size += append_size;
}
}
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FdP->MutexSem);
if(ErrorCode != NULL)
{
*ErrorCode = status;
}
return write_size;
DfsWrite_Exit1:
/* Release the semaphore of this file. */
FsmReleaseMtxSem(FdP->MutexSem);
DfsWrite_Exit:
if(ErrorCode != NULL)
{
*ErrorCode = status;
}
return 0;
}
/*
* Function Name: DfsClose
* Description : Close an opened file , implement the close interface
* Arguments : fd : file descriptor
* First Edit 2003.8.13 wsm
*/
uint32 FsmDfsClose(uint32 fd)
{
uint32 status;
#ifdef FSM_DEBUG
MonPrintf("Interface DfsColse\n");
#endif
if (fd >= MAX_DFS_FD)
{
return ERR_PARAM;
}
if(FsmDfsFds[fd].Flag != DFD_FLAG_IN_USE)
{
return ERR_PARAM;
}
status = FsmGetMtxSem(FsmDfsFds[fd].MutexSem);
if(status != ERR_NONE)
{
return status;
}
if(FsmDfsFds[fd].Flag != DFD_FLAG_IN_USE)
{
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
return ERR_PARAM;
}
/*
// maybe this implementation is better, safer than the current.
status = WaitFdEmpty(fd, WAIT_FOREVER);
if(status == ERR_NONE)
{
FsmDfsFds[fd].Flag = DFD_FLAG_PENDING; // prevent from re-entering.
}
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
if(status == ERR_NONE)
{
DfsFreeFd(fd);
}
return status;
*/
FsmDfsFds[fd].Flag = DFD_FLAG_PENDING; /* prevent from re-entering. */
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
status = WaitFdEmpty(fd, WAIT_FOREVER);
DfsFreeFd(fd);
return status;
}
/*
* Function Name: DfsCreate
* Description : Create a new file , implement the create interface
* Arguments : filename : file path
* First Edit 2003.8.13 wsm
*/
uint32 FsmDfsCreate(FsmDevObjHdrT * DevObjP, char * path, uint32 mode, uint32 * ErrorCodeP)
{
uint32 status;
char * name;
uint32 len;
uint32 fd;
uint32 ParentDirFirstLsn;
FsmFileDirEntryT entry;
char dir[DFS_MAX_PATH_LEN + 1];
uint32 AvailSpace;
uint32 needSpace;
#ifdef FSM_DEBUG
MonPrintf("Interface DfsCreate\n");
#endif
if(strlen(path) > DFS_MAX_PATH_LEN)
{
status = ERR_PARAM;
goto DfsCreate_Exit;
}
name = ExtractFilename(path);
if(name == NULL)
{
status = ERR_PARAM;
goto DfsCreate_Exit;
}
if(DfsFilenameValid(path) == FALSE)
{
status = ERR_PARAM;
goto DfsCreate_Exit;
}
len = strlen(name);
if((len == 0) || (len > DFS_MAX_FILE_NAME_LEN))
{
status = ERR_PARAM;
goto DfsCreate_Exit;
}
if(ExtractDir(path, &len) != 0)
{
if(len > 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -