diff --git a/components/fs/littlefs/lfs_api.c b/components/fs/littlefs/lfs_api.c index 67a2db90..ef97a0bb 100644 --- a/components/fs/littlefs/lfs_api.c +++ b/components/fs/littlefs/lfs_api.c @@ -32,6 +32,8 @@ #define _GNU_SOURCE 1 #include "lfs_api.h" #include "los_config.h" +#include "los_mux.h" +#include "los_debug.h" #include "securec.h" lfs_t g_lfs; @@ -40,29 +42,41 @@ FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0}; struct FileOpInfo g_fsOp[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0}; static LittleFsHandleStruct g_handle[LITTLE_FS_MAX_OPEN_FILES] = {0}; struct dirent g_nameValue; -static pthread_mutex_t g_FslocalMutex = PTHREAD_MUTEX_INITIALIZER; static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a", "/b", "/c"}; +#define LFS_MUTEX_UNINIT (-1) +static UINT32 g_lfsMutex = LFS_MUTEX_UNINIT; + +static int LfsLock(void) +{ + if (LOS_MuxPend(g_lfsMutex, LOS_WAIT_FOREVER) != LOS_OK) { + PRINT_ERR("LfsLock failed!"); + return LOS_NOK; + } + + return LOS_OK; +} + +static void LfsUnlock(void) +{ + (void)LOS_MuxPost(g_lfsMutex); +} LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) { if (g_handle[i].useFlag == 0) { *fd = i; g_handle[i].useFlag = 1; g_handle[i].pathName = strdup(fileName); - pthread_mutex_unlock(&g_FslocalMutex); return &(g_handle[i]); } } - pthread_mutex_unlock(&g_FslocalMutex); *fd = INVALID_FD; return NULL; } static void LfsFreeFd(int fd) { - pthread_mutex_lock(&g_FslocalMutex); g_handle[fd].useFlag = 0; if (g_handle[fd].pathName != NULL) { free((void *)g_handle[fd].pathName); @@ -72,21 +86,17 @@ static void LfsFreeFd(int fd) if (g_handle[fd].lfsHandle != NULL) { g_handle[fd].lfsHandle = NULL; } - pthread_mutex_unlock(&g_FslocalMutex); } BOOL CheckFileIsOpen(const char *fileName) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) { if (g_handle[i].useFlag == 1) { if (strcmp(g_handle[i].pathName, fileName) == 0) { - pthread_mutex_unlock(&g_FslocalMutex); return TRUE; } } } - pthread_mutex_unlock(&g_FslocalMutex); return FALSE; } @@ -103,22 +113,18 @@ static BOOL LfsFdIsValid(int fd) FileDirInfo *GetFreeDir(const char *dirName) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) { if (g_lfsDir[i].useFlag == 0) { g_lfsDir[i].useFlag = 1; g_lfsDir[i].dirName = strdup(dirName); - pthread_mutex_unlock(&g_FslocalMutex); return &(g_lfsDir[i]); } } - pthread_mutex_unlock(&g_FslocalMutex); return NULL; } void FreeDirInfo(const char *dirName) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) { if (g_lfsDir[i].useFlag == 1 && strcmp(g_lfsDir[i].dirName, dirName) == 0) { g_lfsDir[i].useFlag = 0; @@ -126,24 +132,19 @@ void FreeDirInfo(const char *dirName) free(g_lfsDir[i].dirName); g_lfsDir[i].dirName = NULL; } - pthread_mutex_unlock(&g_FslocalMutex); } } - pthread_mutex_unlock(&g_FslocalMutex); } BOOL CheckDirIsOpen(const char *dirName) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) { if (g_lfsDir[i].useFlag == 1) { if (strcmp(g_lfsDir[i].dirName, dirName) == 0) { - pthread_mutex_unlock(&g_FslocalMutex); return TRUE; } } } - pthread_mutex_unlock(&g_FslocalMutex); return FALSE; } @@ -165,35 +166,29 @@ BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo) char tmpName[LITTLEFS_MAX_LFN_LEN] = {0}; int len = GetFirstLevelPathLen(pathName); - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) { if (g_fsOp[i].useFlag == 1) { (void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, len); if (strcmp(tmpName, g_fsOp[i].dirName) == 0) { *fileOpInfo = &(g_fsOp[i]); - pthread_mutex_unlock(&g_FslocalMutex); return TRUE; } } } - pthread_mutex_unlock(&g_FslocalMutex); return FALSE; } struct FileOpInfo *AllocMountRes(const char* target, const struct FileOps *fileOps) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) { if (g_fsOp[i].useFlag == 0 && strcmp(target, g_littlefsMntName[i]) == 0) { g_fsOp[i].useFlag = 1; g_fsOp[i].fsVops = fileOps; g_fsOp[i].dirName = strdup(target); - pthread_mutex_unlock(&g_FslocalMutex); return &(g_fsOp[i]); } } - pthread_mutex_unlock(&g_FslocalMutex); return NULL; } @@ -203,26 +198,21 @@ int SetDefaultMountPath(int pathNameIndex, const char* target) return VFS_ERROR; } - pthread_mutex_lock(&g_FslocalMutex); g_littlefsMntName[pathNameIndex] = strdup(target); - pthread_mutex_unlock(&g_FslocalMutex); return VFS_OK; } struct FileOpInfo *GetMountRes(const char *target, int *mountIndex) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) { if (g_fsOp[i].useFlag == 1) { if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) { *mountIndex = i; - pthread_mutex_unlock(&g_FslocalMutex); return &(g_fsOp[i]); } } } - pthread_mutex_unlock(&g_FslocalMutex); return NULL; } @@ -232,33 +222,28 @@ int FreeMountResByIndex(int mountIndex) return VFS_ERROR; } - pthread_mutex_lock(&g_FslocalMutex); if (g_fsOp[mountIndex].useFlag == 1 && g_fsOp[mountIndex].dirName != NULL) { g_fsOp[mountIndex].useFlag = 0; free(g_fsOp[mountIndex].dirName); g_fsOp[mountIndex].dirName = NULL; } - pthread_mutex_unlock(&g_FslocalMutex); return VFS_OK; } int FreeMountRes(const char *target) { - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) { if (g_fsOp[i].useFlag == 1) { if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) { g_fsOp[i].useFlag = 0; free(g_fsOp[i].dirName); g_fsOp[i].dirName = NULL; - pthread_mutex_unlock(&g_FslocalMutex); return VFS_OK; } } } - pthread_mutex_unlock(&g_FslocalMutex); return VFS_ERROR; } @@ -330,6 +315,18 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType, int ret; struct FileOpInfo *fileOpInfo = NULL; + if (g_lfsMutex == LFS_MUTEX_UNINIT) { + if (LOS_MuxCreate(&g_lfsMutex) != LOS_OK) { + errno = EBUSY; + return VFS_ERROR; + } + } + + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (target == NULL || fileSystemType == NULL || data == NULL) { errno = EFAULT; ret = VFS_ERROR; @@ -370,6 +367,7 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType, } errout: + LfsUnlock(); return ret; } @@ -384,9 +382,15 @@ int LfsUmount(const char *target) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + fileOpInfo = GetMountRes(target, &mountIndex); if (fileOpInfo == NULL) { errno = ENOENT; + LfsUnlock(); return VFS_ERROR; } @@ -397,6 +401,7 @@ int LfsUmount(const char *target) } (void)FreeMountResByIndex(mountIndex); + LfsUnlock(); return ret; } @@ -410,8 +415,14 @@ int LfsUnlink(const char *fileName) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (CheckPathIsMounted(fileName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; + LfsUnlock(); return VFS_ERROR; } @@ -421,6 +432,7 @@ int LfsUnlink(const char *fileName) ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -434,8 +446,14 @@ int LfsMkdir(const char *dirName, mode_t mode) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; + LfsUnlock(); return VFS_ERROR; } @@ -445,6 +463,7 @@ int LfsMkdir(const char *dirName, mode_t mode) ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -459,8 +478,14 @@ int LfsRmdir(const char *dirName) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; + LfsUnlock(); return VFS_ERROR; } @@ -470,6 +495,7 @@ int LfsRmdir(const char *dirName) ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -480,9 +506,14 @@ DIR *LfsOpendir(const char *dirName) if (dirName == NULL) { errno = EFAULT; - goto errout; + return NULL; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return NULL; + } + if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; goto errout; @@ -509,9 +540,11 @@ DIR *LfsOpendir(const char *dirName) dirInfo->lfsHandle = &(fileOpInfo->lfsInfo); + LfsUnlock(); return (DIR *)dirInfo; errout: + LfsUnlock(); return NULL; } @@ -527,9 +560,13 @@ struct dirent *LfsReaddir(DIR *dir) return NULL; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return NULL; + } + ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo); if (ret == TRUE) { - pthread_mutex_lock(&g_FslocalMutex); (void)strncpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1); if (lfsInfo.type == LFS_TYPE_DIR) { g_nameValue.d_type = DT_DIR; @@ -538,8 +575,7 @@ struct dirent *LfsReaddir(DIR *dir) } g_nameValue.d_reclen = lfsInfo.size; - pthread_mutex_unlock(&g_FslocalMutex); - + LfsUnlock(); return &g_nameValue; } @@ -547,6 +583,7 @@ struct dirent *LfsReaddir(DIR *dir) errno = LittlefsErrno(ret); } + LfsUnlock(); return NULL; } @@ -560,6 +597,11 @@ int LfsClosedir(DIR *dir) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + ret = lfs_dir_close(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir))); FreeDirInfo(dirInfo->dirName); @@ -569,6 +611,7 @@ int LfsClosedir(DIR *dir) ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -581,9 +624,14 @@ int LfsOpen(const char *pathName, int openFlag, int mode) if (pathName == NULL) { errno = EFAULT; - goto errout; + return INVALID_FD; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (CheckPathIsMounted(pathName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; goto errout; @@ -609,9 +657,11 @@ int LfsOpen(const char *pathName, int openFlag, int mode) } g_handle[fd].lfsHandle = &(fileOpInfo->lfsInfo); + LfsUnlock(); return fd; errout: + LfsUnlock(); return INVALID_FD; } @@ -624,8 +674,14 @@ int LfsRead(int fd, void *buf, unsigned int len) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (LfsFdIsValid(fd) == FALSE) { errno = EBADF; + LfsUnlock(); return VFS_ERROR; } @@ -634,6 +690,7 @@ int LfsRead(int fd, void *buf, unsigned int len) errno = LittlefsErrno(ret); ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -646,8 +703,14 @@ int LfsWrite(int fd, const void *buf, unsigned int len) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (LfsFdIsValid(fd) == FALSE) { errno = EBADF; + LfsUnlock(); return VFS_ERROR; } @@ -656,6 +719,7 @@ int LfsWrite(int fd, const void *buf, unsigned int len) errno = LittlefsErrno(ret); ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -663,8 +727,14 @@ off_t LfsSeek(int fd, off_t offset, int whence) { off_t ret; + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (LfsFdIsValid(fd) == FALSE) { errno = EBADF; + LfsUnlock(); return VFS_ERROR; } @@ -674,6 +744,7 @@ off_t LfsSeek(int fd, off_t offset, int whence) ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -681,14 +752,18 @@ int LfsClose(int fd) { int ret; + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (LfsFdIsValid(fd) == FALSE) { errno = EBADF; + LfsUnlock(); return VFS_ERROR; } - pthread_mutex_lock(&g_FslocalMutex); ret = lfs_file_close(g_handle[fd].lfsHandle, &(g_handle[fd].file)); - pthread_mutex_unlock(&g_FslocalMutex); LfsFreeFd(fd); @@ -696,7 +771,7 @@ int LfsClose(int fd) errno = LittlefsErrno(ret); ret = VFS_ERROR; } - + LfsUnlock(); return ret; } @@ -710,8 +785,14 @@ int LfsRename(const char *oldName, const char *newName) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (CheckPathIsMounted(oldName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; + LfsUnlock(); return VFS_ERROR; } @@ -721,6 +802,7 @@ int LfsRename(const char *oldName, const char *newName) ret = VFS_ERROR; } + LfsUnlock(); return ret; } @@ -735,8 +817,14 @@ int LfsStat(const char *path, struct stat *buf) return VFS_ERROR; } + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (CheckPathIsMounted(path, &fileOpInfo) == FALSE || fileOpInfo == NULL) { errno = ENOENT; + LfsUnlock(); return VFS_ERROR; } @@ -752,7 +840,7 @@ int LfsStat(const char *path, struct stat *buf) errno = LittlefsErrno(ret); ret = VFS_ERROR; } - + LfsUnlock(); return ret; } @@ -760,8 +848,14 @@ int LfsFsync(int fd) { int ret; + if (LfsLock() != LOS_OK) { + errno = EAGAIN; + return VFS_ERROR; + } + if (LfsFdIsValid(fd) == FALSE) { errno = EBADF; + LfsUnlock(); return VFS_ERROR; } @@ -770,5 +864,6 @@ int LfsFsync(int fd) errno = LittlefsErrno(ret); ret = VFS_ERROR; } + LfsUnlock(); return ret; } diff --git a/components/fs/littlefs/lfs_api.h b/components/fs/littlefs/lfs_api.h index 9d0ccbf3..0409b800 100644 --- a/components/fs/littlefs/lfs_api.h +++ b/components/fs/littlefs/lfs_api.h @@ -42,7 +42,6 @@ #include "lfs.h" #include "lfs_util.h" #include "memory.h" -#include "pthread.h" #define INVALID_FD (-1)