From 45c72e792744dc50c37ad64381e060c63a322ae4 Mon Sep 17 00:00:00 2001 From: li_zan <371442490@qq.com> Date: Tue, 18 May 2021 16:10:25 +0800 Subject: [PATCH 1/2] Add Multi mount func --- components/fs/littlefs/lfs_api.c | 356 +++++++++++++++++++++++++++---- components/fs/littlefs/lfs_api.h | 16 +- 2 files changed, 333 insertions(+), 39 deletions(-) diff --git a/components/fs/littlefs/lfs_api.c b/components/fs/littlefs/lfs_api.c index 5b0ffb99..3e668016 100644 --- a/components/fs/littlefs/lfs_api.c +++ b/components/fs/littlefs/lfs_api.c @@ -34,10 +34,11 @@ lfs_t g_lfs; FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0}; -FileOpInfo g_fsOp; +struct FileOpInfo g_fsOp[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 *const g_littlefsMntName[LFS_MAX_MOUNT_SIZE] = {"/a","/b","/c"}; FileOpInfo GetFsOpInfo(void) { @@ -55,7 +56,7 @@ LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd) g_handle[i].useFlag = 1; g_handle[i].pathName = (char *)malloc(len); if (g_handle[i].pathName) { - memcpy_s(g_handle[i].pathName, LITTLE_FS_MAX_NAME_LEN, fileName, len); + strncpy_s(g_handle[i].pathName, LITTLE_FS_MAX_NAME_LEN, fileName, len); } pthread_mutex_unlock(&g_FslocalMutex); return &(g_handle[i]); @@ -68,31 +69,160 @@ LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd) 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; } -lfs_dir_t *GetFreeDir() +FileDirInfo *GetFreeDir(const char *dirName) { + int len = strlen(dirName) + 1; + 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 = (char *)malloc(len); + if (g_lfsDir[i].dirName) { + strncpy_s(g_lfsDir[i].dirName, len, dirName, len); + } pthread_mutex_unlock(&g_FslocalMutex); - return &(g_lfsDir[i].dir); + return &(g_lfsDir[i]); } } pthread_mutex_unlock(&g_FslocalMutex); return NULL; } +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; +} + +BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo) +{ + char tmpName[LITTLEFS_MAX_LFN_LEN] = {0}; + int mountPathNameLen = 0; + int len = strlen(pathName) + 1; + + pthread_mutex_lock(&g_FslocalMutex); + for (int i = 0; i < LFS_MAX_MOUNT_SIZE; i++) { + if (g_fsOp[i].useFlag == 1) { + mountPathNameLen = strlen(g_fsOp[i].dirName); + if(len < mountPathNameLen + 1) { + pthread_mutex_unlock(&g_FslocalMutex); + return FALSE; + } + + (void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, mountPathNameLen); + tmpName[mountPathNameLen] = '\0'; + + 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, struct FileOps *fileOps) +{ + int len = strlen(target) + 1; + + pthread_mutex_lock(&g_FslocalMutex); + for (int i = 0; i < 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; + if (g_fsOp[i].dirName == NULL) { + g_fsOp[i].dirName = (char *)malloc(len); + if(g_fsOp[i].dirName) { + (void)strncpy_s(g_fsOp[i].dirName, len, target, len); + } + } + pthread_mutex_unlock(&g_FslocalMutex); + return &(g_fsOp[i]); + } + } + + pthread_mutex_unlock(&g_FslocalMutex); + return NULL; +} + +struct FileOpInfo *GetMountRes(const char*target, int *mountIndex) +{ + pthread_mutex_lock(&g_FslocalMutex); + for (int i = 0; i < 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; +} + +int FreeMountResByIndex(int mountIndex) +{ + if (mountIndex < 0 || mountIndex >= LFS_MAX_MOUNT_SIZE) { + 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 < 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; +} + const struct MountOps g_lfsMnt = { .Mount = LfsMount, .Umount = LfsUmount, @@ -119,49 +249,134 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType, const void *data) { int ret; + struct FileOpInfo *fileOpInfo = NULL; - g_fsOp.fsVops = &g_lfsVops; - ret = lfs_mount(&g_lfs, (struct lfs_config*)data); + if (target == NULL || fileSystemType == NULL || data == NULL) { + ret = VFS_ERROR; + goto errout; + } + if (strcmp(fileSystemType, "littlefs") != 0) { + ret = VFS_ERROR; + goto errout; + } + + if (CheckPathIsMounted(target, &fileOpInfo)) { + ret = VFS_OK; + goto errout; + } + + // select free mount resource + fileOpInfo = AllocMountRes(target, &g_lfsFops); + if (fileOpInfo == NULL) { + ret = VFS_ERROR; + goto errout; + } + + return lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data); +errout: return ret; } int LfsUmount(const char *target) { - return lfs_unmount(&g_lfs); + int ret, mountIndex = -1; + struct FileOpInfo *fileOpInfo = NULL; + + if (target == NULL) { + return VFS_ERROR; + } + + fileOpInfo = GetMountRes(target, &mountIndex); + if (fileOpInfo == NULL) { + return VFS_ERROR; + } + + ret = lfs_unmount(&(fileOpInfo->lfsInfo)); + + (void)FreeMountResByIndex(mountIndex); + return ret; } int LfsUnlink(const char *fileName) { - return lfs_remove(&g_lfs, fileName); + struct FileOpInfo *fileOpInfo = NULL; + + if (fileName == NULL) { + return VFS_ERROR; + } + + if (CheckPathIsMounted(fileName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + return VFS_ERROR; + } + + return lfs_remove(&(fileOpInfo->lfsInfo), fileName); } int LfsMkdir(const char *dirName, mode_t mode) { - return lfs_mkdir(&g_lfs, dirName); + struct FileOpInfo *fileOpInfo = NULL; + + if (dirName == NULL) { + return VFS_ERROR; + } + + if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + return VFS_ERROR; + } + + return lfs_mkdir(&(fileOpInfo->lfsInfo), dirName); } int LfsRmdir(const char *dirName) { - return lfs_remove(&g_lfs, dirName); + struct FileOpInfo *fileOpInfo = NULL; + + if (dirName == NULL) { + return VFS_ERROR; + } + + if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + return VFS_ERROR; + } + + return lfs_remove(&(fileOpInfo->lfsInfo), dirName); } DIR *LfsOpendir(const char *dirName) { int ret; + struct FileOpInfo *fileOpInfo = NULL; - lfs_dir_t *dir = GetFreeDir(); - if (dir == NULL) { - return NULL; + if (dirName == NULL) { + return VFS_ERROR; } - ret = lfs_dir_open(&g_lfs, dir, dirName); - - if (ret == 0) { - return (DIR *)dir; - } else { - return NULL; + if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + return VFS_ERROR; } + + if (CheckDirIsOpen(dirName)) { + goto errout; + } + + FileDirInfo *dirInfo = GetFreeDir(dirName); + if (dirInfo == NULL) { + goto errout; + } + + ret = lfs_dir_open(&(fileOpInfo->lfsInfo), (lfs_dir_t *)(&(dirInfo->dir)), dirName); + + if (ret != 0) { + goto errout; + } + + dirInfo->lfsHandle = &(fileOpInfo->lfsInfo); + + return (DIR *)dirInfo; + +errout: + return NULL; } struct dirent *LfsReaddir(DIR *dir) @@ -169,10 +384,16 @@ struct dirent *LfsReaddir(DIR *dir) int ret; struct lfs_info lfsInfo; - ret = lfs_dir_read(&g_lfs, (lfs_dir_t *)dir, &lfsInfo); + FileDirInfo *dirInfo = (FileDirInfo *)dir; + + if (dirInfo == NULL || dirInfo->lfsHandle == NULL) { + return NULL; + } + + ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo); if (ret == 0) { pthread_mutex_lock(&g_FslocalMutex); - (void)memcpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1); + (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; } else if (lfsInfo.type == LFS_TYPE_REG) { @@ -190,15 +411,29 @@ struct dirent *LfsReaddir(DIR *dir) int LfsClosedir(const DIR *dir) { - return lfs_dir_close(&g_lfs, (lfs_dir_t *)dir); + FileDirInfo *dirInfo = (FileDirInfo *)dir; + + if (dirInfo == NULL || dirInfo->lfsHandle == NULL) { + return VFS_ERROR; + } + + return lfs_dir_close(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir))); } int LfsOpen(const char *pathName, int openFlag, int mode) { int fd = INVALID_FD; + struct FileOpInfo *fileOpInfo = NULL; + if (pathName == NULL) { + goto errout; + } + + if (CheckPathIsMounted(pathName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + goto errout; + } // if file is already open, return invalid fd - if (pathName == NULL || CheckFileIsOpen(pathName)) { + if (CheckFileIsOpen(pathName)) { goto errout; } @@ -207,11 +442,12 @@ int LfsOpen(const char *pathName, int openFlag, int mode) goto errout; } - int err = lfs_file_open(&g_lfs, &(fsHandle->file), pathName, openFlag); + int err = lfs_file_open(&(fileOpInfo->lfsInfo), &(fsHandle->file), pathName, openFlag); if (err != 0) { goto errout; } + g_handle[fd].lfsHandle = &(fileOpInfo->lfsInfo); return fd; errout: return INVALID_FD; @@ -219,47 +455,66 @@ errout: int LfsRead(int fd, void *buf, unsigned int len) { - if (fd >= LITTLE_FS_MAX_OPEN_FILES && fd < 0) { + if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0 || buf == NULL) { return VFS_ERROR; } - return lfs_file_read(&g_lfs, &(g_handle[fd].file), buf, len); + if (g_handle[fd].lfsHandle == NULL) { + return VFS_ERROR; + } + + return lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len); } int LfsWrite(int fd, const void *buf, unsigned int len) { - if (fd >= LITTLE_FS_MAX_OPEN_FILES && fd < 0) { + if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0 || buf == NULL) { return VFS_ERROR; } - return lfs_file_write(&g_lfs, &(g_handle[fd].file), buf, len); + if (g_handle[fd].lfsHandle == NULL) { + return VFS_ERROR; + } + + return lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len); } int LfsSeek(int fd, off_t offset, int whence) { - if (fd >= LITTLE_FS_MAX_OPEN_FILES && fd < 0) { + if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) { return VFS_ERROR; } - return lfs_file_seek(&g_lfs, &(g_handle[fd].file), offset, whence); + if (g_handle[fd].lfsHandle == NULL) { + return VFS_ERROR; + } + + return lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, whence); } int LfsClose(int fd) { int ret = VFS_ERROR; - if (fd >= LITTLE_FS_MAX_OPEN_FILES && fd < 0) { + if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) { return ret; } + if (g_handle[fd].lfsHandle == NULL) { + return VFS_ERROR; + } + pthread_mutex_lock(&g_FslocalMutex); - ret = lfs_file_close(&g_lfs, &(g_handle[fd].file)); + ret = lfs_file_close(g_handle[fd].lfsHandle, &(g_handle[fd].file)); g_handle[fd].useFlag = 0; if (g_handle[fd].pathName != NULL) { - free(g_handle[fd].pathName); g_handle[fd].pathName = NULL; } + + if (g_handle[fd].lfsHandle != NULL) { + g_handle[fd].lfsHandle = NULL; + } pthread_mutex_unlock(&g_FslocalMutex); return ret; @@ -267,15 +522,34 @@ int LfsClose(int fd) int LfsRename(const char *oldName, const char *newName) { - return lfs_rename(&g_lfs, oldName, newName); + struct FileOpInfo *fileOpInfo = NULL; + + if (oldName == NULL || newName == NULL) { + return VFS_ERROR; + } + + if (CheckPathIsMounted(oldName, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + return VFS_ERROR; + } + + return lfs_rename(&(fileOpInfo->lfsInfo), oldName, newName); } int LfsStat(const char *path, struct stat *buf) { int ret; struct lfs_info info; + struct FileOpInfo *fileOpInfo = NULL; - ret = lfs_stat(&g_lfs, path, &info); + if (path == NULL || buf == NULL) { + return VFS_ERROR; + } + + if (CheckPathIsMounted(path, &fileOpInfo) == FALSE || fileOpInfo == NULL) { + return VFS_ERROR; + } + + ret = lfs_stat(&(fileOpInfo->lfsInfo), path, &info); if (ret == 0) { buf->st_size = info.size; } @@ -285,6 +559,14 @@ int LfsStat(const char *path, struct stat *buf) int LfsFsync(int fd) { - return lfs_file_sync(&g_lfs, &(g_handle[fd].file)); + if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) { + return VFS_ERROR; + } + + if (g_handle[fd].lfsHandle == NULL) { + return VFS_ERROR; + } + + return lfs_file_sync(g_handle[fd].lfsHandle, &(g_handle[fd].file)); } diff --git a/components/fs/littlefs/lfs_api.h b/components/fs/littlefs/lfs_api.h index 3cf0556a..a9b78ca4 100644 --- a/components/fs/littlefs/lfs_api.h +++ b/components/fs/littlefs/lfs_api.h @@ -56,15 +56,21 @@ typedef unsigned mode_t; typedef struct { uint8_t useFlag; const char *pathName; + lfs_t *lfsHandle; lfs_file_t file; } LittleFsHandleStruct; -typedef struct { +struct FileOpInfo { + uint8_t useFlag; struct FileOps *fsVops; -} FileOpInfo; + char *dirName; + lfs_t lfsInfo; +}; typedef struct { uint8_t useFlag; + char *dirName; + lfs_t *lfsHandle; lfs_dir_t dir; } FileDirInfo; @@ -76,11 +82,17 @@ typedef struct { #define MAX_BUFFER_LEN 100 #define MAX_WRITE_FILE_LEN 500 #define MAX_READ_FILE_LEN 500 +#define LITTLEFS_MAX_LFN_LEN 255 #ifndef LFS_MAX_OPEN_DIRS #define LFS_MAX_OPEN_DIRS 10 #endif +#ifndef LFS_MAX_MOUNT_SIZE +#define LFS_MAX_MOUNT_SIZE 3 +#endif + + LittleFsHandleStruct *GetFreeFd(int *fd); int InitMountInfo(const char *fileSystemType, const struct MountOps *fsMops); From 3181b4395daa0c82aa88fa03aeb7c1b8d5c6102e Mon Sep 17 00:00:00 2001 From: li_zan <371442490@qq.com> Date: Thu, 20 May 2021 15:36:54 +0800 Subject: [PATCH 2/2] Add Multi mount func --- components/fs/littlefs/lfs_api.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/components/fs/littlefs/lfs_api.c b/components/fs/littlefs/lfs_api.c index 3e668016..cb81932d 100644 --- a/components/fs/littlefs/lfs_api.c +++ b/components/fs/littlefs/lfs_api.c @@ -47,17 +47,12 @@ FileOpInfo GetFsOpInfo(void) LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd) { - int len = strlen(fileName) + 1; - 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 = (char *)malloc(len); - if (g_handle[i].pathName) { - strncpy_s(g_handle[i].pathName, LITTLE_FS_MAX_NAME_LEN, fileName, len); - } + g_handle[i].pathName = strdup(fileName); pthread_mutex_unlock(&g_FslocalMutex); return &(g_handle[i]); } @@ -84,16 +79,11 @@ BOOL CheckFileIsOpen(const char *fileName) FileDirInfo *GetFreeDir(const char *dirName) { - int len = strlen(dirName) + 1; - 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 = (char *)malloc(len); - if (g_lfsDir[i].dirName) { - strncpy_s(g_lfsDir[i].dirName, len, dirName, len); - } + g_lfsDir[i].dirName = strdup(dirName); pthread_mutex_unlock(&g_FslocalMutex); return &(g_lfsDir[i]); } @@ -148,19 +138,12 @@ BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo) struct FileOpInfo *AllocMountRes(const char* target, struct FileOps *fileOps) { - int len = strlen(target) + 1; - pthread_mutex_lock(&g_FslocalMutex); for (int i = 0; i < 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; - if (g_fsOp[i].dirName == NULL) { - g_fsOp[i].dirName = (char *)malloc(len); - if(g_fsOp[i].dirName) { - (void)strncpy_s(g_fsOp[i].dirName, len, target, len); - } - } + g_fsOp[i].dirName == strdup(target); pthread_mutex_unlock(&g_FslocalMutex); return &(g_fsOp[i]); } @@ -393,7 +376,7 @@ struct dirent *LfsReaddir(DIR *dir) ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo); if (ret == 0) { pthread_mutex_lock(&g_FslocalMutex); - (void)strncpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1); + g_nameValue.d_name = strdup(lfsInfo.name); if (lfsInfo.type == LFS_TYPE_DIR) { g_nameValue.d_type = DT_DIR; } else if (lfsInfo.type == LFS_TYPE_REG) {