diff --git a/Kconfig b/Kconfig
index 77380a27..1ba5c3c1 100755
--- a/Kconfig
+++ b/Kconfig
@@ -93,12 +93,27 @@ source "../../kernel/liteos_a/fs/ramfs/Kconfig"
source "../../kernel/liteos_a/fs/nfs/Kconfig"
source "../../kernel/liteos_a/fs/proc/Kconfig"
source "../../kernel/liteos_a/fs/jffs2/Kconfig"
-source "../../kernel/liteos_a/fs/zpfs/Kconfig"
config ENABLE_READ_BUFFER
bool "Enable read buffer Option"
default n
help
Answer Y to add enable read buffer Option.
+
+config MAX_VNODE_SIZE
+ int "Vnode max number"
+ range 0 512
+ default 512
+ depends on FS_VFS
+ help
+ vnode number, range from 0 to 512.
+
+config MAX_PATH_CACHE_SIZE
+ int "PathCache max number"
+ range 0 1024
+ default 512
+ depends on FS_VFS
+ help
+ pathCache number, range from 0 to 1024.
endmenu
######################## config options of net ############################
diff --git a/apps/shell/src/shcmd.c b/apps/shell/src/shcmd.c
index a4930a90..31aca4cc 100755
--- a/apps/shell/src/shcmd.c
+++ b/apps/shell/src/shcmd.c
@@ -453,6 +453,7 @@ unsigned int OsCmdKeyShift(const char *cmdKey, char *cmdOut, unsigned int size)
free(outputBak);
return SH_OK;
}
+
int OsTabCompletion(char *cmdKey, unsigned int *len)
{
int count;
diff --git a/fs/fat/Makefile b/fs/fat/Makefile
index ce372490..b4e3e624 100755
--- a/fs/fat/Makefile
+++ b/fs/fat/Makefile
@@ -37,7 +37,9 @@ LOCAL_SRCS += $(wildcard $(LITEOSTHIRDPARTY)/FatFs/source/*.c)
LOCAL_INCLUDE := \
-I $(LITEOSTHIRDPARTY)/FatFs/source \
-I $(LITEOSTOPDIR)/fs/fat/os_adapt \
- -I $(LITEOSTOPDIR)/fs/fat/virpart/include
+ -I $(LITEOSTOPDIR)/fs/fat/virpart/include \
+ -I $(LITEOSTOPDIR)/fs/vfs \
+ -I $(LITEOSTHIRDPARTY)/NuttX/include
LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS)
diff --git a/fs/fat/os_adapt/dirop_fat.c b/fs/fat/os_adapt/dirop_fat.c
deleted file mode 100755
index 0515cf15..00000000
--- a/fs/fat/os_adapt/dirop_fat.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
- * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. Neither the name of the copyright holder nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "dirop_fat.h"
-#include "fatfs.h"
-#include "errno.h"
-#include "fs/fs.h"
-#include "inode/inode.h"
-#include "integer.h"
-#include "string.h"
-
-#ifdef LOSCFG_FS_FAT
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C"{
-#endif
-#endif /* __cplusplus */
-
-extern const struct mountpt_operations fat_operations;
-#define SECTOR_SIZE 512
-#define FIRST_MALLOC_SIZE 10
-
-static INT vfat_check_path(const char *path)
-{
- struct inode *inode_ptr = NULL;
- char *fullpath = NULL;
- INT ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
- struct inode_search_s desc;
-
- if (ret < ENOERR) {
- ret = -ret;
- set_errno(ret);
- return FAT_ERROR;
- }
-
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
- PRINT_ERR("ERROR: Failed to find %s\n", fullpath);
- ret = -ret;
- set_errno(ret);
- return FAT_ERROR;
- }
- inode_ptr = desc.node;
-
- free(fullpath);
-
- if (inode_ptr && (inode_ptr->u.i_mops == &fat_operations)) {
- inode_release(inode_ptr);
- return ENOERR;
- }
-
- return FAT_ERROR;
-}
-
-static DIR_FAT *initdir_fat(DIR *dp)
-{
- DIR_FAT *dir_fat = NULL;
-
- if (dp != NULL) {
- dir_fat = (DIR_FAT *)malloc(sizeof(DIR_FAT) + PATH_MAX);
- if (dir_fat != NULL) {
- (void)memset_s(dir_fat, sizeof(DIR_FAT) + PATH_MAX, 0, sizeof(DIR_FAT) + PATH_MAX);
-
- dir_fat->stDirStream.dd_nextloc = 0;
- dir_fat->stDirStream.dd_size = 0;
- dir_fat->stBuf.d_count = SECTOR_SIZE;
- dir_fat->stBuf.d_usecount = 0;
-
- (void)pthread_mutex_init(&(dir_fat->stDirStream.dd_lock), (const pthread_mutexattr_t *)NULL);
- dir_fat->stDirStream.dp = dp;
-
- return dir_fat;
- }
-
- (void)closedir(dp);
- }
-
- return NULL;
-}
-
-DIR_FAT *opendir_fat(const char *name)
-{
- INT ret;
- DIR *dp = NULL;
-
- ret = vfat_check_path(name);
- if (ret) {
- return NULL;
- }
-
- dp = opendir(name);
-
- return initdir_fat(dp);
-}
-
-int closedir_fat(DIR_FAT *dir_fat)
-{
- INT ret;
-
- if (dir_fat == NULL) {
- return FAT_ERROR;
- }
-
- ret = closedir(dir_fat->stDirStream.dp);
- if (ret == ENOERR) {
- (void)pthread_mutex_destroy(&(dir_fat->stDirStream.dd_lock));
- free(dir_fat);
- }
-
- return ret;
-}
-
-extern int fatfs_readdir_all(DIR_FAT *dir_fat);
-
-struct fat_direntall *readdir_fat(DIR_FAT *dir_fat)
-{
- INT ret;
- struct fat_direntall *de = (struct fat_direntall *)NULL;
-
- if (dir_fat == NULL) {
- return NULL;
- }
-
- if (pthread_mutex_lock(&(dir_fat->stDirStream.dd_lock)) != ENOERR) {
- return NULL;
- }
-
- ret = fatfs_readdir_all(dir_fat);
- if (!ret) {
- de = &(dir_fat->stBuf.direntall);
- }
-
- if (pthread_mutex_unlock(&(dir_fat->stDirStream.dd_lock)) != ENOERR)
- PRINT_ERR("readdir_fat mutex unlock error \n");
- return de;
-}
-
-static struct fat_direntall **scandir_fat_remalloc_names(struct fat_direntall **names,
- UINT *names_size, UINT pos, bool *failed)
-{
- struct fat_direntall **new_direntall = NULL;
- INT32 ret;
-
- if (pos == *names_size) {
-
- if (*names_size == 0) {
- *names_size = FIRST_MALLOC_SIZE;
- } else {
- *names_size <<= 1;
- }
-
- new_direntall = (struct fat_direntall **)malloc(*names_size * sizeof(struct fat_direntall *));
- if (new_direntall == NULL) {
- *failed = 1;
- return names;
- }
-
- if (names != NULL) {
- ret = memcpy_s(new_direntall, (*names_size) * sizeof(struct fat_direntall *),
- names, pos * sizeof(struct fat_direntall *));
- if (ret != EOK){
- *failed = 1;
- free(new_direntall);
- return names;
- }
- free(names);
- }
- return new_direntall;
- }
- return names;
-}
-
-int scandir_fat(const char *dir, struct fat_direntall ***namelist,
- int (*selector) (const struct fat_direntall *),
- int (*compar) (const struct fat_direntall **, const struct fat_direntall **))
-{
- DIR_FAT *dp = opendir_fat(dir);
- struct fat_direntall *current = NULL;
- struct fat_direntall **names = NULL;
- struct fat_direntall *vnew = NULL;
- UINT names_size = 0;
- UINT pos = 0;
- UINT dsize;
- bool failed = 0;
- INT use_it;
-
- if (dp == NULL) {
- return FAT_ERROR;
- }
-
- current = readdir_fat(dp);
- while (current != NULL) {
- use_it = (selector == NULL);
- if (!use_it) {
- use_it = (*selector) (current);
- }
- if (use_it) {
- names = scandir_fat_remalloc_names(names, &names_size, pos, &failed);
- if (failed == 1) {
- break;
- }
-
- dsize = current->d_reclen;
- vnew = (struct fat_direntall *)malloc(dsize);
- if (vnew == NULL) {
- failed = 1;
- break;
- }
-
- (void)memcpy_s(vnew, dsize, current, dsize);
- names[pos++] = vnew;
- }
- current = readdir_fat(dp);
- }
-
- if (failed == 1) {
- (void)closedir_fat(dp);
- while (pos > 0) {
- free(names[--pos]);
- }
-
- if (names != NULL) {
- free(names);
- }
-
- return FAT_ERROR;
- }
-
- (void)closedir_fat(dp);
-
- /* Sort the list if we have a comparison function to sort with. */
- if (compar != NULL && names != NULL) {
- qsort((void *)names, pos, sizeof (struct fat_direntall *), (int (*)(const void *, const void *))*compar);
- }
- *namelist = names;
- return pos;
-}
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif /* __cplusplus */
-#endif /* CONFIG_FS_FAT */
diff --git a/fs/fat/os_adapt/dirop_fat.h b/fs/fat/os_adapt/dirop_fat.h
deleted file mode 100755
index 2f9b9fa2..00000000
--- a/fs/fat/os_adapt/dirop_fat.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
- * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. Neither the name of the copyright holder nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @defgroup fat Fat
- * @ingroup filesystem
- */
-
-#ifndef _DIROP_FAT_H
-#define _DIROP_FAT_H
-
-#include "pthread.h"
-#include "dirent.h"
-#ifdef LOSCFG_FS_FAT
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C"{
-#endif
-#endif /* __cplusplus */
-
-#define TIME_LENGTH 8
-
-struct fat_direntall {
- unsigned long d_ino;
- unsigned long d_off;
- unsigned char d_type;
- unsigned int d_size;
- char d_createtime[TIME_LENGTH];
- unsigned short d_reclen;
- char d_name[1];
-};
-
-struct fat_direntall_buf {
- int d_count;
- int d_usecount;
- struct fat_direntall direntall;
-};
-
-struct dirstream_fat {
- DIR *dp;
-
- /* offset of the next dir entry in buffer */
- unsigned int dd_nextloc;
-
- /* bytes of valid entries in buffer */
- unsigned int dd_size;
-
- pthread_mutex_t dd_lock;
-};
-
-typedef struct fat_dir{
- struct dirstream_fat stDirStream;
- struct fat_direntall_buf stBuf;
-} DIR_FAT;
-
-/**
- * @ingroup fat
- * @brief open a directory
- *
- * @par Description:
- * This API is used to open a directory stream corresponding to the directory name, and
- * returns a pointer to the directory stream.
- *
- * @attention
- *
- * The parameter name should be a valid string.
- *
- *
- * @param name [IN] the directory to open.
- *
- * @retval #NULL Open directory unsuccessfully and set errno.
- * @retval #DIR_FAT* A pointer to the directory stream.
- * @par Dependency:
- * dirop_fat.h: the header file that contains the API declaration.
- * @see closedir_fat
- */
-DIR_FAT *opendir_fat(const char *name);
-
-/**
- * @ingroup fat
- * @brief close a directory
- *
- * @par Description:
- * This API is used to close the directory stream associated with dirp.
- *
- * @attention
- *
- * The parameter dir_fat should be a valid pointer which opendir_fat returns.
- *
- *
- * @param dir_fat [IN] Directory object structure pointer which opendir_fat returns.
- *
- * @retval #FAT_ERROR The directory dirp close unsuccessfully and set errno.
- * @retval #OK The directory dirp close successfully.
- * @par Dependency:
- * dirop_fat.h: the header file that contains the API declaration.
- * @see opendir_fat
- */
-int closedir_fat(DIR_FAT *dir_fat);
-
-/**
- * @ingroup fat
- * @brief read a directory
- *
- * @par Description:
- * This API is used to get a pointer to a dirent structure
- * representing the next directory entry in the directory stream pointed
- * to by dirp.
- *
- * @attention
- *
- * The parameter dir_fat should be a valid pointer which opendir_fat returns.
- *
- *
- * @param dir_fat [IN] An instance of type DIR created by a previous call to opendir_fat().
- *
- * @retval #NULL Reaching the end of the directory stream or if an error occurred and set errno.
- * @retval #fat_direntall* A pointer to a dirent structure.
- * @par Dependency:
- * dirop_fat.h: the header file that contains the API declaration.
- * @see opendir_fat
- */
-struct fat_direntall *readdir_fat(DIR_FAT *dir_fat);
-
-/**
-* @ingroup fat
-* @brief scan a directory for matching entries.
-*
-* @par Description:
-* The scandir_fat() function scans the directory dirp, calling selector() in
-* each directory entry. Entries for which selector() returns nonzero are
-* stored in strings allocated via malloc, sorted using qsort with
-* the comparison function compar(), and collected in array namelist
-* which is allocated via malloc. If filter is NULL, all entries are
-* selected, compare with scandir(), scandir_fat() can get the create-time of
-* file.
-*
-* @attention
-*
-*
-* @param dir [IN] Type #const char* a pointer to directory information.
-* @param namelist [OUT] Type #const struct fat_direntall*** a pointer to collected directory entries.
-* @param selector [IN] Type #int(*selector)(const struct fat_direntall*) a filter type function.
-* @param compar [IN] Type #int(*compar)(const struct fat_direntall**,const struct dirent**) a compar type function.
-*
-* @retval #int The number of directory entries selected.
-* @retval #<0 An error occurred.
-* @par Dependency:
-* dirop_fat.h: the header file that contains the API declaration.
-* @see readdir_fat
-*/
-int scandir_fat(const char *dir, struct fat_direntall ***namelist,
- int (*selector) (const struct fat_direntall *),
- int (*compar) (const struct fat_direntall **, const struct fat_direntall **));
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif /* __cplusplus */
-
-#endif /* LOSCFG_FS_FAT */
-
-#endif /* _DIROP_FAT_H */
diff --git a/fs/fat/os_adapt/fat_shellcmd.c b/fs/fat/os_adapt/fat_shellcmd.c
old mode 100644
new mode 100755
index 0648d29c..35dcbdd1
--- a/fs/fat/os_adapt/fat_shellcmd.c
+++ b/fs/fat/os_adapt/fat_shellcmd.c
@@ -45,8 +45,8 @@ int osShellCmdFormat(int argc, char **argv)
if (argc < 3) { /* 3, at least 3 params for this shell command. */
perror("format error");
PRINTK("Usage :\n");
- PRINTK(" format \n");
- PRINTK(" dev_inodename : the name of dev\n");
+ PRINTK(" format \n");
+ PRINTK(" dev_vnodename : the name of dev\n");
PRINTK(" sectors : Size of allocation unit in unit of byte or sector, ");
PRINTK("0 instead of default size\n");
PRINTK(" options : Index of filesystem. 1 for FAT filesystem, ");
diff --git a/fs/fat/os_adapt/fatfs.c b/fs/fat/os_adapt/fatfs.c
index e2829109..6a173100 100755
--- a/fs/fat/os_adapt/fatfs.c
+++ b/fs/fat/os_adapt/fatfs.c
@@ -30,34 +30,31 @@
*/
#include "fatfs.h"
-
#ifdef LOSCFG_FS_FAT
-#include
-#include
-
-#include "errno.h"
#include "ff.h"
-#include "dirop_fat.h"
+#include "fs/vfs_util.h"
#include "disk_pri.h"
-#include "los_tables.h"
-
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
-#include "virpart.h"
-#include "errcode_fat.h"
-#include "virpartff.h"
-#endif
-
-#ifdef LOSCFG_FS_FAT_CACHE
-#include "bcache.h"
-#endif
-
-#include "los_config.h"
-#include "los_vm_filemap.h"
-#include "los_process_pri.h"
-#include "capability_type.h"
-#include "capability_api.h"
+#include "diskio.h"
+#include "fs/fs.h"
+#include "fs/dirent_fs.h"
#include "fs_other.h"
-#include "los_strncpy_from_user.h"
+#include "fs/mount.h"
+#include "fs/vnode.h"
+#include "fs/path_cache.h"
+#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+#include "virpartff.h"
+#include "errcode_fat.h"
+#endif
+#include "los_tables.h"
+#include "user_copy.h"
+#include "los_vm_filemap.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#ifdef __cplusplus
#if __cplusplus
@@ -65,58 +62,24 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
-FAT_VIR_PART g_fatVirPart = {0};
-static pthread_mutex_t fatfsVirtMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-static void FatfsVirtLock(void)
+struct VnodeOps fatfs_vops; /* forward define */
+struct file_operations_vfs fatfs_fops;
+
+#define BITMASK4 0x0F
+#define BITMASK5 0x1F
+#define BITMASK6 0x3F
+#define BITMASK7 0x7F
+#define FTIME_MIN_OFFSET 6 /* minute offset in word */
+#define FTIME_HR_OFFSET 11 /* hour offset in word */
+#define FTIME_MTH_OFFSET 5 /* month offset in word */
+#define FTIME_YEAR_OFFSET 9 /* year offset in word */
+#define FTIME_DATE_OFFSET 16 /* date offset in dword */
+#define SEC_MULTIPLIER 2
+#define YEAR_OFFSET 80 /* Year start from 1980 in FATFS, while start from 1900 in struct tm */
+
+int fatfs_2_vfs(int result)
{
- (void)pthread_mutex_lock(&fatfsVirtMutex);
-}
-static void FatfsVirtUnlock(void)
-{
- (void)pthread_mutex_unlock(&fatfsVirtMutex);
-}
-#endif
-
-PARTITION VolToPart[FF_VOLUMES];
-static struct inode *DiskDev[FF_VOLUMES];
-char FatLabel[LABEL_LEN];
-
-#define DRIVER_NAME_LEN 8
-
-/* Returns -1 if there is no space to install fatfs driver, else returns >=0 */
-static INT FatGetDisk(struct inode *node)
-{
- INT index;
-
- for (index = 0; index < FF_VOLUMES; index++) {
- if (DiskDev[index] == node) {
- return index;
- }
- }
-
- return FAT_ERROR;
-}
-
-static INT FatfsSdSync(unsigned long mountflags, FATFS *fat)
-{
-#ifdef LOSCFG_FS_FAT_CACHE
- los_part *part = NULL;
- if (mountflags != MS_NOSYNC) {
- part = get_part((INT)fat->pdrv);
- if (part == NULL) {
- return -ENODEV;
- }
-
- (void)OsSdSync(part->disk_id);
- }
-#endif
- return ENOERR;
-}
-
-INT fatfs_2_vfs(INT result)
-{
- INT status = ENOERR;
+ int status = ENOERR;
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
if (result < 0 || result >= VIRERR_BASE) {
@@ -136,1570 +99,1473 @@ INT fatfs_2_vfs(INT result)
case FR_NO_FILE:
case FR_NO_PATH:
case FR_NO_FILESYSTEM:
- status = -ENOENT;
+ status = ENOENT;
break;
case FR_INVALID_NAME:
- status = -EINVAL;
+ status = EINVAL;
break;
case FR_EXIST:
case FR_INVALID_OBJECT:
- status = -EEXIST;
+ status = EEXIST;
break;
case FR_DISK_ERR:
case FR_NOT_READY:
case FR_INT_ERR:
- status = -EIO;
+ status = EIO;
break;
case FR_WRITE_PROTECTED:
- status = -EROFS;
+ status = EROFS;
break;
case FR_MKFS_ABORTED:
case FR_INVALID_PARAMETER:
- status = -EINVAL;
+ status = EINVAL;
break;
case FR_NO_SPACE_LEFT:
- status = -ENOSPC;
+ status = ENOSPC;
break;
case FR_NO_DIRENTRY:
- status = -ENFILE;
+ status = ENFILE;
break;
case FR_NO_EMPTY_DIR:
- status = -ENOTEMPTY;
+ status = ENOTEMPTY;
break;
case FR_IS_DIR:
- status = -EISDIR;
+ status = EISDIR;
break;
case FR_NO_DIR:
- status = -ENOTDIR;
+ status = ENOTDIR;
break;
case FR_NO_EPERM:
case FR_DENIED:
- status = -EPERM;
+ status = EPERM;
break;
case FR_LOCKED:
- status = -EBUSY;
+ case FR_TIMEOUT:
+ status = EBUSY;
break;
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
case FR_MODIFIED:
- status = VIRERR_MODIFIED;
+ status = -VIRERR_MODIFIED;
break;
case FR_CHAIN_ERR:
- status = VIRERR_CHAIN_ERR;
+ status = -VIRERR_CHAIN_ERR;
break;
case FR_OCCUPIED:
- status = VIRERR_OCCUPIED;
+ status = -VIRERR_OCCUPIED;
break;
case FR_NOTCLEAR:
- status = VIRERR_NOTCLEAR;
+ status = -VIRERR_NOTCLEAR;
break;
case FR_NOTFIT:
- status = VIRERR_NOTFIT;
+ status = -VIRERR_NOTFIT;
break;
case FR_INVAILD_FATFS:
- status = VIRERR_INTER_ERR;
+ status = -VIRERR_INTER_ERR;
break;
#endif
default:
- status = FAT_ERROR;
+ status = -FAT_ERROR;
break;
}
return status;
}
-static int FatfsBindCheck(struct inode *blkdriver, los_part **partition)
+static int fatfs_sync(unsigned long mountflags, FATFS *fs)
{
+#ifdef LOSCFG_FS_FAT_CACHE
los_part *part = NULL;
- if (blkdriver == NULL || blkdriver->u.i_bops == NULL) {
- return -ENODEV;
- }
+ if (mountflags != MS_NOSYNC) {
+ part = get_part((INT)fs->pdrv);
+ if (part == NULL) {
+ return -ENODEV;
+ }
- if (blkdriver->u.i_bops->open != NULL && blkdriver->u.i_bops->open(blkdriver) != 0) {
- return -ENODEV;
- }
-
- part = los_part_find(blkdriver);
- if (part == NULL) {
- return -ENODEV;
- }
-
- if (part->part_name != NULL) {
- return -EACCES;
- }
-
-#ifndef FF_MULTI_PARTITION
- if (part->part_no_mbr > 1) {
- return -EPERM;
+ (void)OsSdSync(part->disk_id);
}
#endif
+ return 0;
+}
+int fatfs_hash_cmp(struct Vnode *vp, void *arg)
+{
+ DIR_FILE *dfp_target = (DIR_FILE *)arg;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
- *partition = part;
- return ENOERR;
+ return dfp_target->f_dir.sect != dfp->f_dir.sect ||
+ dfp_target->f_dir.dptr != dfp->f_dir.dptr ||
+ dfp_target->fno.sclst != dfp->fno.sclst;
}
-struct FatfsMountOpts {
- uid_t FsUid;
- gid_t FsGid;
- unsigned short FsDmask;
- unsigned short FsFmask;
-};
-struct MatchOption {
- int opt;
- const char *pattern;
-};
-typedef struct MatchOption MatchTable[];
-enum {
- OptionUid,
- OptionGid,
- OptionUmask,
- OptionDmask,
- OptionFmask,
- OptionErr,
-};
-static const MatchTable FatFsTokens = {
- {OptionUid, "uid=%u"},
- {OptionGid, "gid=%u"},
- {OptionUmask, "umask=%o"},
- {OptionDmask, "dmask=%o"},
- {OptionFmask, "fmask=%o"},
- {OptionErr, NULL},
-};
-
-static int MatchOption(char *s, const MatchTable table, char **args)
+static DWORD fatfs_hash(QWORD sect, DWORD dptr, DWORD sclst)
{
- struct MatchOption opt = {0};
- const char *p = NULL;
- char *meta = NULL;
- for (unsigned int i = 0; i < (sizeof(FatFsTokens) / sizeof(struct MatchOption)); i++) {
- opt = table[i];
- p = opt.pattern;
- if (p == NULL) {
- continue;
- }
- meta = strchr(table[i].pattern, '%');
- if ((meta == NULL) || (strncmp(p, s, meta - p) != 0)) {
- continue;
- }
- *args = s + (meta - p);
- break;
- }
+ DWORD hash = FNV1_32_INIT;
+ hash = fnv_32_buf(§, sizeof(QWORD), hash);
+ hash = fnv_32_buf(&dptr, sizeof(DWORD), hash);
+ hash = fnv_32_buf(&sclst, sizeof(DWORD), hash);
- return opt.opt;
-}
-static void FatParseOptions(char *data, struct FatfsMountOpts *opts)
-{
- char *args = NULL;
- int opt;
- char *p = NULL;
-
- if ((data == NULL) || (opts == NULL)) {
- return;
- }
-
- opts->FsUid = OsCurrUserGet()->effUserID;
- opts->FsGid = OsCurrUserGet()->effGid;
- opts->FsDmask = GetUmask();
- opts->FsFmask = GetUmask();
-
- while ((p = strsep((char**)&data, ",")) != NULL) {
- if (!*p)
- continue;
-
- opt = MatchOption(p, FatFsTokens, &args);
- if (args == NULL) {
- continue;
- }
-
- switch (opt) {
- case OptionUid:
- opts->FsUid = strtoul(args, NULL, 0);
- break;
- case OptionGid:
- opts->FsGid = strtoul(args, NULL, 0);
- break;
- case OptionUmask:
- opts->FsDmask = opts->FsFmask = strtoul(args, NULL, 8); /* 8: octal formats */
- break;
- case OptionDmask:
- opts->FsDmask = strtoul(args, NULL, 8); /* 8: octal formats */
- break;
- case OptionFmask:
- opts->FsFmask = strtoul(args, NULL, 8); /* 8: octal formats */
- break;
- default:
- PRINTK("Not Match\n");
- break;
- }
- }
- return;
+ return hash;
}
-int fatfs_bind(struct inode *blkdriver, const void *data, void **handle, const char *relpath)
+static mode_t fatfs_get_mode(BYTE attribute, mode_t fs_mode)
{
- FATFS *fat = NULL;
- INT result;
- BYTE index;
- INT err;
- los_part *part = NULL;
- char drive[DRIVER_NAME_LEN];
- struct FatfsMountOpts opts = {0};
-
- FatParseOptions((char *)data, &opts);
-
- result = FatfsBindCheck(blkdriver, &part);
- if (result != 0)
- return result;
-
- err = SetDiskPartName(part, relpath);
- if (err != 0)
- return -ENOMEM;
-
- index = (BYTE)FatGetDisk((struct inode *)NULL);
- if (index >= FF_VOLUMES || (INT8)index < 0) {
- err = -EBUSY;
- goto ERROUT;
+ mode_t mask = 0;
+ if (attribute & AM_RDO) {
+ mask = S_IWUSR | S_IWGRP | S_IWOTH;
}
- VolToPart[index].di = part->disk_id;
- VolToPart[index].pd = part->part_id;
- VolToPart[index].pt = part->part_no_mbr;
- VolToPart[index].ps = part->sector_start;
- VolToPart[index].pc = part->sector_count;
-
- fat = (FATFS *)zalloc(sizeof(FATFS));
- if (fat == NULL) {
- err = -ENOMEM;
- goto ERROUT_WITH_DISK;
- }
- result = snprintf_s(drive, sizeof(drive), sizeof(drive) - 1, "%d:/", index);
- if (result < 0) {
- err = -EINVAL;
- free(fat);
- goto ERROUT_WITH_DISK;
- }
-
- fat->fs_uid = opts.FsUid;
- fat->fs_gid = opts.FsGid;
- fat->fs_dmask = opts.FsDmask;
- fat->fs_fmask = opts.FsFmask;
-
- /* save blockdriver inode : driver will use in f_mount */
- DiskDev[index] = blkdriver;
- /* mount fatfs, mmc always 0 logic driver */
- result = f_mount(fat, drive, 1);
- if (result == FR_OK) {
- DIR *dir = NULL;
-
- dir = (DIR *)malloc(sizeof(DIR));
- if (dir == NULL) {
- err = -ENOMEM;
- goto ERROUT_WITH_MOUNT;
- }
-
-#if FF_FS_MINIMIZE <= 1
- /* open the root directory, returns error if fatfs is invalid */
- result = f_opendir(dir, drive);
- if (result != FR_OK) {
- err = fatfs_2_vfs(result);
- free(dir);
- goto ERROUT_WITH_MOUNT;
- }
- result = f_closedir(dir);
- if (result != FR_OK) {
- err = fatfs_2_vfs(result);
- free(dir);
- goto ERROUT_WITH_MOUNT;
- }
-#else
- PRINT_ERR("cannot open root directory to check if fatfs is invalid!\n");
-#endif
- /* mount ok! */
- *handle = (void *)fat;
- free(dir);
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- /* Parent Partition Mount Success, then process virtual partition mount operation */
- struct inode_search_s desc;
- FAR struct inode *inode;
- if (result == FR_OK) {
- if (fat->fs_type != FS_FAT32)
- return VIRERR_NOTFIT;
- SETUP_SEARCH(&desc, g_fatVirPart.virtualinfo.devpartpath, false);
- result = inode_find(&desc);
- if (result < 0)
- return VIRERR_NOPARAM;
- inode = desc.node;
-
- if (blkdriver != inode) {
- return VIRERR_NOPARAM;
- } else {
- FatfsVirtLock();
- result = FatFsBindVirPart(fat, index);
- FatfsVirtUnlock();
- if (result != FR_OK && result < VIRERR_BASE) {
- result = VIRERR_INTER_ERR;
- }
- }
- }
-#endif
- return fatfs_2_vfs(result);
+ fs_mode &= ~mask;
+ if (attribute & AM_DIR) {
+ fs_mode |= S_IFDIR;
} else {
- err = fatfs_2_vfs(result);
+ fs_mode |= S_IFREG;
}
-ERROUT_WITH_MOUNT:
- (void)f_mount((FATFS *)NULL, drive, 0);
- if (fat->win != NULL)
- free(fat->win);
- free(fat);
-
-ERROUT_WITH_DISK:
- DiskDev[index] = (struct inode *)NULL;
-
-ERROUT:
- free(part->part_name);
- part->part_name = NULL;
-
- return err;
+ return fs_mode;
}
-int fatfs_unbind(void *handle, struct inode **blkdriver)
+int fatfs_lookup(struct Vnode *parent, const char *path, int len, struct Vnode **vpp)
{
- BYTE index;
- FATFS *fat = NULL;
- INT result;
- los_part *part = NULL;
- char drive[DRIVER_NAME_LEN];
-
- fat = (FATFS *)handle;
- if (fat == NULL)
- return -EINVAL;
- index = (BYTE)fatfs_get_vol(fat);
- if (index >= FF_VOLUMES || (INT8)index < 0)
- return -EINVAL;
- result = snprintf_s(drive, sizeof(drive), sizeof(drive) - 1, "%d:/", index);
- if (result < 0)
- return -EINVAL;
-
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- /* Release virtual partition objects before unbind real partition */
- struct inode_search_s desc;
- FAR struct inode *inode;
- SETUP_SEARCH(&desc, g_fatVirPart.virtualinfo.devpartpath, false);
- FatfsVirtLock();
- result = FatFsUnbindVirPart(fat);
- FatfsVirtUnlock();
- if (result == FR_OK) {
- part = get_part((INT)fat->pdrv);
- (void)inode_find(&desc);
- inode = desc.node;
- if (part == NULL || part->dev == inode) {
- (void)memset_s(g_devPartName, sizeof(g_devPartName), 0, sizeof(g_devPartName));
- (void)memset_s(&g_fatVirPart.virtualinfo, sizeof(virpartinfo), 0, sizeof(virpartinfo));
- g_fatVirPart.isparamset = FALSE;
- }
- } else {
- return fatfs_2_vfs(result);
- }
-
-#endif
- result = f_mount((FATFS *)NULL, drive, 0);
- if (result != FR_OK)
- return fatfs_2_vfs(result);
-
- VolToPart[index].di = 0;
- VolToPart[index].pd = 0;
- VolToPart[index].pt = 0;
- VolToPart[index].ps = 0;
- VolToPart[index].pc = 0;
-
- part = get_part((INT)fat->pdrv);
- if (part != NULL && part->part_name) {
- free(part->part_name);
- part->part_name = NULL;
- }
-
- if (blkdriver != NULL)
- *blkdriver = DiskDev[index];
- DiskDev[index] = (struct inode *)NULL;
- if (fat->win != NULL) {
- free(fat->win);
- fat->win = NULL;
- }
- if (fat != NULL) {
- free(fat);
- fat = NULL;
- }
-
- return OK;
-}
-
-static BYTE FatFsGetMode(int oflags, int *accMode)
-{
- BYTE fmode = FA_READ;
- *accMode = READ_OP;
-
- if ((UINT)oflags & O_WRONLY) {
- fmode |= FA_WRITE;
- *accMode = (unsigned int)(*accMode) | WRITE_OP;
- }
-
- if (((UINT)oflags & O_ACCMODE) & O_RDWR) {
- fmode |= FA_WRITE;
- *accMode = (unsigned int)(*accMode) | WRITE_OP;
- }
- /* Creates a new file if the file is not existing, otherwise, just open it. */
- if ((UINT)oflags & O_CREAT) {
- fmode |= FA_OPEN_ALWAYS;
- *accMode = (unsigned int)(*accMode) | WRITE_OP;
- /* Creates a new file. If the file already exists, the function shall fail. */
- if ((UINT)oflags & O_EXCL)
- fmode |= FA_CREATE_NEW;
- }
- /* Creates a new file. If the file already exists, its length shall be truncated to 0. */
- if ((UINT)oflags & O_TRUNC) {
- fmode |= FA_CREATE_ALWAYS;
- *accMode = (unsigned int)(*accMode) | WRITE_OP;
- }
-
- return fmode;
-}
-
-#define FAT_USER_SHIFT 6
-#define FAT_GROUP_SHIFT 3
-#define FAT_NO_PERM 1
-#define FAT_PERM 0
-static unsigned int FatFsCheckPermission(struct inode *mountpt, bool dirFlag, int accMode)
-{
- FATFS *fat = NULL;
- unsigned short umask;
- uint uid = OsCurrUserGet()->effUserID;
- uint gid = OsCurrUserGet()->effGid;
- mode_t fileMode = mountpt->i_mode;
- fat = (FATFS *)mountpt->i_private;
-
- if (fat == NULL) {
- umask = GetUmask();
- } else if (dirFlag) {
- umask = fat->fs_dmask;
- } else {
- umask = fat->fs_fmask;
- }
-
- fileMode &= (~umask);
-
- if (uid == mountpt->i_uid) {
- fileMode >>= FAT_USER_SHIFT;
- } else if (LOS_CheckInGroups(mountpt->i_gid)) {
- fileMode >>= FAT_GROUP_SHIFT;
- }
-
- fileMode &= (READ_OP | WRITE_OP | EXEC_OP);
-
- if (((unsigned int)accMode & fileMode) == (unsigned int)accMode) {
- return FAT_PERM;
- }
-
- fileMode = 0;
- if (S_ISDIR(mountpt->i_mode)) {
- if (((unsigned int)accMode & EXEC_OP) && (IsCapPermit(CAP_DAC_READ_SEARCH))) {
- fileMode |= EXEC_OP;
- }
- } else {
- if (((unsigned int)accMode & EXEC_OP) && (IsCapPermit(CAP_DAC_EXECUTE))
- && (mountpt->i_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
- fileMode |= EXEC_OP;
- }
- }
-
- if (((unsigned int)accMode & WRITE_OP) && IsCapPermit(CAP_DAC_WRITE)) {
- fileMode |= WRITE_OP;
- }
-
- if (((unsigned int)accMode & READ_OP) && IsCapPermit(CAP_DAC_READ_SEARCH)) {
- fileMode |= READ_OP;
- }
-
- if (((unsigned int)accMode & fileMode) == (unsigned int)accMode) {
- return FAT_PERM;
- }
-
- PRINTK("%s, %d, permission check fail,uid %d, gid %d, mode %d%d%d, accMode %d, cuid %d, cgid %d\n",
- __FUNCTION__, __LINE__, mountpt->i_uid, mountpt->i_gid,
- (mountpt->i_mode >> FAT_USER_SHIFT) & (READ_OP | WRITE_OP | EXEC_OP),
- (mountpt->i_mode >> FAT_GROUP_SHIFT) & (READ_OP | WRITE_OP | EXEC_OP),
- (mountpt->i_mode) & (READ_OP | WRITE_OP | EXEC_OP), accMode, uid, gid);
-
- return FAT_NO_PERM;
-}
-
-static bool oflag_convert_and_check(FAR struct file *filep, int oflags)
-{
- unsigned int acc_mode = 0;
-
- if (((unsigned int)oflags & O_ACCMODE) == O_RDONLY)
- acc_mode |= READ_OP;
- if ((unsigned int)oflags & O_WRONLY)
- acc_mode |= WRITE_OP;
- if ((unsigned int)oflags & O_RDWR)
- acc_mode |= READ_OP | WRITE_OP;
- if ((unsigned int)oflags & O_CREAT)
- acc_mode |= WRITE_OP;
- if ((unsigned int)oflags & O_TRUNC)
- acc_mode |= WRITE_OP;
- if ((unsigned int)oflags & O_EXCL)
- acc_mode |= WRITE_OP;
- if ((unsigned int)oflags & O_APPEND)
- acc_mode |= WRITE_OP;
- if ((unsigned int)oflags & O_EXECVE)
- acc_mode |= EXEC_OP;
-
- if ((filep->f_inode->mountflags == MS_RDONLY) && ((acc_mode & WRITE_OP) != 0))
- return false;
-
- return true;
-}
-
-int fatfs_open(struct file *filep, const char *relpath, int oflags, mode_t mode)
-{
- BYTE fmode;
- char *filePath = NULL;
- FATFS *fat = NULL;
- FIL *fp = NULL;
+ struct Vnode *vp = NULL;
+ FATFS *fs = (FATFS *)(parent->originMount->data);
+ DIR_FILE *dfp;
+ DIR *dp = NULL;
+ FILINFO *finfo = NULL;
+ DWORD hash;
FRESULT result;
- INT vol, ret;
- int accMode;
+ int ret;
- if (filep == NULL || filep->f_inode == NULL || filep->f_inode->i_private == NULL || relpath == NULL) {
- return -EINVAL;
+ dfp = (DIR_FILE *)zalloc(sizeof(DIR_FILE));
+ if (dfp == NULL) {
+ ret = ENOMEM;
+ goto ERROR_EXIT;
}
- if ((UINT)oflags & O_DIRECTORY) {
- return -EACCES;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ ret = EBUSY;
+ goto ERROR_FREE;
+ }
+ finfo = &(dfp->fno);
+ LOS_ListInit(&finfo->fp_list);
+ dp = &(dfp->f_dir);
+ dp->obj.fs = fs;
+ dp->obj.sclust = ((DIR_FILE *)(parent->data))->fno.sclst;
+
+ DEF_NAMBUF;
+ INIT_NAMBUF(fs);
+ result = create_name(dp, &path);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
}
- if (strlen(relpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
+ result = dir_find(dp);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
}
- if (oflag_convert_and_check(filep, oflags) != true) {
- return -EACCES;
+ if (dp->fn[NSFLAG] & NS_NONAME) {
+ result = FR_INVALID_NAME;
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
}
- fat = (FATFS *)filep->f_inode->i_private;
+ get_fileinfo(dp, finfo);
+ dp->obj.objsize = 0;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
+ hash = fatfs_hash(dp->sect, dp->dptr, finfo->sclst);
+ ret = VfsHashGet(parent->originMount, hash, &vp, fatfs_hash_cmp, dfp);
+ if (ret != 0) {
+ ret = VnodeAlloc(&fatfs_vops, &vp);
+ if (ret != 0) {
+ ret = ENOMEM;
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_UNLOCK;
+ }
+ vp->parent = parent;
+ vp->fop = &fatfs_fops;
+ vp->data = dfp;
+ vp->originMount = parent->originMount;
+ vp->uid = fs->fs_uid;
+ vp->gid = fs->fs_gid;
+ vp->mode = fatfs_get_mode(finfo->fattrib, fs->fs_mode);
+ if (finfo->fattrib & AM_DIR) {
+ vp->type = VNODE_TYPE_DIR;
+ } else {
+ vp->type = VNODE_TYPE_REG;
+ }
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
- return -ENOMEM;
- }
-
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, relpath);
- if (ret < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- fmode = FatFsGetMode(oflags, &accMode);
-
- if (FatFsCheckPermission(filep->f_inode, false, accMode)) {
- free(filePath);
- return -EACCES;
- }
-
- fp = (FIL *)malloc(sizeof(FIL));
- if (fp == NULL) {
- free(filePath);
- return -ENOMEM;
- }
-#if !FF_FS_TINY
- fp->buf = NULL;
-#endif
-
- result = f_open(fp, filePath, fmode);
- free(filePath);
- if (result == FR_OK) {
- filep->f_pos = fp->fptr;
- filep->f_priv = fp;
-
- if ((UINT)oflags & O_APPEND) {
-#if FF_FS_MINIMIZE <= 2
- /* seek to the end of file */
- (void)f_lseek(fp, fp->obj.objsize);
- filep->f_pos = fp->fptr;
-#else
- PRINT_ERR("f_lseek is not supported, O_APPEND won't take effect!\n");
-#endif
+ ret = VfsHashInsert(vp, hash);
+ if (ret != 0) {
+ result = FR_INVALID_PARAMETER;
+ goto ERROR_UNLOCK;
}
} else {
- /* open failed, release memory and return errno */
-#if !FF_FS_TINY
- if (fp->buf != NULL) {
- free(fp->buf);
- }
-#endif
- free(fp);
- return fatfs_2_vfs(result);
+ free(dfp); /* hash hit dfp is no needed */
}
- return FatfsSdSync(filep->f_inode->mountflags, fat);
+ unlock_fs(fs, FR_OK);
+ FREE_NAMBUF();
+ *vpp = vp;
+ return 0;
+
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ERROR_FREE:
+ free(dfp);
+ERROR_EXIT:
+ return -ret;
+}
+
+int fatfs_create(struct Vnode *parent, const char *name, int mode, struct Vnode **vpp)
+{
+ struct Vnode *vp = NULL;
+ FATFS *fs = (FATFS *)parent->originMount->data;
+ DIR_FILE *dfp;
+ DIR *dp = NULL;
+ FILINFO *finfo = NULL;
+ QWORD time;
+ DWORD hash;
+ FRESULT result;
+ int ret;
+
+ dfp = (DIR_FILE *)zalloc(sizeof(DIR_FILE));
+ if (dfp == NULL) {
+ ret = ENOMEM;
+ goto ERROR_EXIT;
+ }
+ ret = lock_fs(fs);
+ if (ret == FALSE) { /* lock failed */
+ ret = EBUSY;
+ goto ERROR_FREE;
+ }
+
+ finfo = &(dfp->fno);
+ LOS_ListInit(&finfo->fp_list);
+ dp = &(dfp->f_dir);
+ dp->obj.fs = fs;
+ dp->obj.sclust = ((DIR_FILE *)(parent->data))->fno.sclst;
+
+ DEF_NAMBUF;
+ INIT_NAMBUF(fs);
+ result = create_name(dp, &name);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
+ }
+ result = dir_find(dp);
+ if (result == FR_OK) {
+ ret = EEXIST;
+ goto ERROR_UNLOCK;
+ }
+ result = dir_register(dp);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
+ }
+ /* Set the directory entry attribute */
+ if (time_status == SYSTEM_TIME_ENABLE) {
+ time = GET_FATTIME();
+ } else {
+ time = 0;
+ }
+ st_dword(dp->dir + DIR_CrtTime, time);
+ st_dword(dp->dir + DIR_ModTime, time);
+ st_word(dp->dir + DIR_LstAccDate, time >> FTIME_DATE_OFFSET);
+ dp->dir[DIR_Attr] = AM_ARC;
+ if ((mode & S_IWUSR) == 0) {
+ dp->dir[DIR_Attr] |= AM_RDO;
+ }
+ st_clust(fs, dp->dir, 0);
+ st_dword(dp->dir + DIR_FileSize, 0);
+
+#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+ PARENTFS(fs)->wflag = 1;
+#else
+ fs->wflag = 1;
+#endif
+ result = sync_fs(fs);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
+ }
+ result = dir_read(dp, 0);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_UNLOCK;
+ }
+ get_fileinfo(dp, finfo);
+ dp->obj.objsize = 0;
+
+ ret = VnodeAlloc(&fatfs_vops, &vp);
+ if (ret != 0) {
+ ret = ENOMEM;
+ goto ERROR_UNLOCK;
+ }
+
+ vp->parent = parent;
+ vp->fop = &fatfs_fops;
+ vp->data = dfp;
+ vp->originMount = parent->originMount;
+ vp->uid = fs->fs_uid;
+ vp->gid = fs->fs_gid;
+ vp->mode = fatfs_get_mode(finfo->fattrib, fs->fs_mode);
+ vp->type = VNODE_TYPE_REG;
+
+ hash = fatfs_hash(dp->sect, dp->dptr, finfo->sclst);
+ ret = VfsHashInsert(vp, hash);
+ if (ret != 0) {
+ ret = EINVAL;
+ goto ERROR_UNLOCK;
+ }
+ *vpp = vp;
+
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ return fatfs_sync(parent->originMount->mountFlags, fs);
+
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ERROR_FREE:
+ free(dfp);
+ERROR_EXIT:
+ return -ret;
+}
+
+int fatfs_open(struct file *filep)
+{
+ struct Vnode *vp = filep->f_vnode;
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ DIR *dp = &(dfp->f_dir);
+ FILINFO *finfo = &(dfp->fno);
+ FIL *fp;
+ int ret;
+
+ fp = (FIL *)zalloc(sizeof(FIL));
+ if (fp == NULL) {
+ ret = ENOMEM;
+ goto ERROR_EXIT;
+ }
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ ret = EBUSY;
+ goto ERROR_EXIT;
+ }
+
+ fp->dir_sect = dp->sect;
+ fp->dir_ptr = dp->dir;
+ fp->obj.sclust = finfo->sclst;
+ fp->obj.objsize = finfo->fsize;
+#if FF_USE_FASTSEEK
+ fp->cltbl = 0; /* Disable fast seek mode */
+#endif
+ fp->obj.fs = fs;
+ fp->obj.id = fs->id;
+ fp->flag = FA_READ | FA_WRITE;
+ fp->err = 0;
+ fp->sect = 0;
+ fp->fptr = 0;
+ fp->buf = (BYTE*) ff_memalloc(SS(fs));
+ if (fp->buf == NULL) {
+ ret = ENOMEM;
+ goto ERROR_FREE;
+ }
+ LOS_ListAdd(&finfo->fp_list, &fp->fp_entry);
+ unlock_fs(fs, FR_OK);
+
+ filep->f_priv = fp;
+ return fatfs_sync(vp->originMount->mountFlags, fs);
+
+ERROR_FREE:
+ unlock_fs(fs, FR_OK);
+ free(fp);
+ERROR_EXIT:
+ return -ret;
}
int fatfs_close(struct file *filep)
{
- FATFS *fat = NULL;
- FIL *fp = NULL;
+ FIL *fp = (FIL *)filep->f_priv;
+ FATFS *fs = fp->obj.fs;
FRESULT result;
- INT vol;
+ int ret;
- if (filep == NULL || filep->f_inode == NULL || filep->f_inode->i_private == NULL) {
- return -EINVAL;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
}
-
- fat = (FATFS *)filep->f_inode->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
+#if !FF_FS_READONLY
+ result = f_sync(fp); /* Flush cached data */
+ if (result != FR_OK) {
+ goto EXIT;
+ }
+ ret = fatfs_sync(filep->f_vnode->originMount->mountFlags, fs);
+ if (ret != 0) {
+ unlock_fs(fs, FR_OK);
+ return ret;
}
-
- fp = (FIL *)(filep->f_priv);
- FAT_CHECK(fp);
-
- result = f_close(fp);
- if (result == FR_OK) {
- /* close succeed, release memory */
-#if !FF_FS_TINY
- if (fp->buf != NULL)
- free(fp->buf);
#endif
- free(fp);
- return FatfsSdSync(filep->f_inode->mountflags, fat);
- }
-
- return fatfs_2_vfs(result);
+ LOS_ListDelete(&fp->fp_entry);
+ ff_memfree(fp->buf);
+ free(fp);
+ filep->f_priv = NULL;
+EXIT:
+ unlock_fs(fs, result);
+ return -fatfs_2_vfs(result);
}
-int fatfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
+int fatfs_read(struct file *filep, char *buff, size_t count)
{
- return -ENOSYS;
-}
-
-ssize_t fatfs_read(struct file *filep, char *buffer, size_t buflen)
-{
- FIL *fp = NULL;
+ FIL *fp = (FIL *)filep->f_priv;
+ FATFS *fs = fp->obj.fs;
+ struct Vnode *vp = filep->f_vnode;
+ FILINFO *finfo = &((DIR_FILE *)(vp->data))->fno;
+ size_t rcount;
FRESULT result;
- UINT byteRead;
+ int ret;
- fp = (FIL *)(filep->f_priv);
- FAT_CHECK(fp);
-
- result = f_read(fp, buffer, buflen, &byteRead);
- /* file position should be updated */
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+ fp->obj.objsize = finfo->fsize;
+ fp->obj.sclust = finfo->sclst;
+ result = f_read(fp, buff, count, &rcount);
+ if (result != FR_OK) {
+ goto EXIT;
+ }
filep->f_pos = fp->fptr;
-
- if (result == FR_OK)
- return byteRead;
-
- return fatfs_2_vfs(result);
+EXIT:
+ unlock_fs(fs, result);
+ return rcount;
}
-ssize_t fatfs_write(struct file *filep, const char *buffer, size_t buflen)
+static FRESULT update_dir(DIR *dp, FILINFO *finfo)
{
-#if !FF_FS_READONLY
- FIL *fp = (FIL *)(filep->f_priv);
+ FATFS *fs = dp->obj.fs;
+ DWORD tm;
+ BYTE *dbuff = NULL;
FRESULT result;
- UINT byteWrite;
- if (filep->f_inode->mountflags == MS_RDONLY)
- return -EACCES;
-
- FAT_CHECK(fp);
-
- result = f_write(fp, buffer, buflen, &byteWrite);
- /* file position should be updated */
- filep->f_pos = fp->fptr;
- if (f_sync(fp) != FR_OK)
- PRINT_ERR("fatfs_write f_sync error \n");
- if (result == FR_OK)
- return byteWrite;
-
- return fatfs_2_vfs(result);
+ result = move_window(fs, dp->sect);
+ if (result != FR_OK) {
+ return result;
+ }
+ dbuff = fs->win + dp->dptr % SS(fs);
+ dbuff[DIR_Attr] = finfo->fattrib;
+ st_clust(fs, dbuff, finfo->sclst); /* Update start cluster */
+ st_dword(dbuff + DIR_FileSize, (DWORD)finfo->fsize); /* Update file size */
+ if (time_status == SYSTEM_TIME_ENABLE) {
+ tm = GET_FATTIME();
+ } else {
+ tm = 0;
+ }
+ st_dword(dbuff + DIR_ModTime, tm); /* Update mtime */
+ st_word(dbuff + DIR_LstAccDate, tm >> FTIME_DATE_OFFSET); /* Update access date */
+#ifndef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+ fs->wflag = 1;
#else
- return -ENOSYS;
+ PARENTFS(fs)->wflag = 1;
#endif
+ return sync_fs(fs);
}
-int fatfs_sync(struct file *filep)
+off64_t fatfs_lseek64(struct file *filep, off64_t offset, int whence)
{
-#if !FF_FS_READONLY
- FATFS *fat = NULL;
- FIL *fp = NULL;
+ FIL *fp = (FIL *)filep->f_priv;
+ FATFS *fs = fp->obj.fs;
+ struct Vnode *vp = filep->f_vnode;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ FILINFO *finfo = &(dfp->fno);
+ FSIZE_t fpos;
FRESULT result;
- INT vol;
+ int ret;
- if (filep == NULL || filep->f_inode == NULL || filep->f_inode->i_private == NULL)
+ switch (whence) {
+ case SEEK_CUR:
+ offset = filep->f_pos + offset;
+ if (offset < 0) {
+ return -EINVAL;
+ }
+ fpos = offset;
+ break;
+ case SEEK_SET:
+ if (offset < 0) {
+ return -EINVAL;
+ }
+ fpos = offset;
+ break;
+ case SEEK_END:
+ offset = (off_t)((long long)finfo->fsize + offset);
+ if (offset < 0) {
+ return -EINVAL;
+ }
+ fpos = offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (offset >= FAT32_MAXSIZE) {
return -EINVAL;
+ }
- if (filep->f_inode->mountflags == MS_RDONLY)
- return -EACCES;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+ fp->obj.sclust = finfo->sclst;
+ fp->obj.objsize = finfo->fsize;
- fat = (FATFS *)filep->f_inode->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES)
- return -ENOENT;
-
- fp = (FIL *)(filep->f_priv);
- FAT_CHECK(fp);
+ result = f_lseek(fp, fpos);
+ finfo->fsize = fp->obj.objsize;
+ finfo->sclst = fp->obj.sclust;
+ if (result != FR_OK) {
+ goto ERROR_EXIT;
+ }
result = f_sync(fp);
-
-#ifdef LOSCFG_FS_FAT_CACHE
- los_part *part = NULL;
- if (result == FR_OK) {
- part = get_part((INT)fat->pdrv);
- if (part == NULL)
- return -ENODEV;
- (void)OsSdSync(part->disk_id);
- }
-#endif
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_dup(FAR const struct file *oldp, FAR struct file *newp)
-{
- return -ENOSYS;
-}
-
-off_t fatfs_seek(struct file *filep, off_t offset, int whence)
-{
-#if FF_FS_MINIMIZE <= 2
- FRESULT result;
- FIL *fp = (FIL *)(filep->f_priv);
-
- FAT_CHECK(fp);
-
- switch (whence) {
- case SEEK_SET: /* The offset is set to offset bytes. */
- break;
-
- case SEEK_CUR: /* The offset is set to its current location plus offset bytes. */
- offset += (off_t)filep->f_pos;
- break;
-
- case SEEK_END: /* The offset is set to the size of the file plus offset bytes. */
- offset += fp->obj.objsize;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (offset < 0) {
- return -EINVAL;
- }
-
- result = f_lseek(fp, offset);
- if (result == FR_OK) {
- /* return current position */
- filep->f_pos = (off_t)fp->fptr;
- return (off_t)fp->fptr;
- }
-
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-loff_t fatfs_seek64(struct file *filep, loff_t offset, int whence)
-{
-#if FF_FS_MINIMIZE <= 2
- FRESULT result;
- FIL *fp = (FIL *)(filep->f_priv);
-
- FAT_CHECK(fp);
-
- switch (whence) {
- case SEEK_SET: /* The offset is set to offset bytes. */
- break;
-
- case SEEK_CUR: /* The offset is set to its current location plus offset bytes. */
- offset += filep->f_pos;
- break;
-
- case SEEK_END: /* The offset is set to the size of the file plus offset bytes. */
- offset += (loff_t)fp->obj.objsize;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (offset < 0)
- return -EINVAL;
-
- result = f_lseek(fp, offset);
- if (result == FR_OK) {
- /* return current position */
- filep->f_pos = (loff_t)fp->fptr;
- return (loff_t)fp->fptr;
- }
-
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_unlink(struct inode *mountpt, const char *relpath)
-{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- FATFS *fat = NULL;
- FRESULT result;
- INT ret, vol;
- char *filePath = NULL;
- struct stat st;
-
- if (strlen(relpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH)
- return -ENAMETOOLONG;
-
- if (mountpt->mountflags == MS_RDONLY)
- return -EACCES;
-
- ret = fatfs_stat(mountpt, relpath, &st);
- if (ret != FR_OK)
- return ret;
-
- switch (st.st_mode & S_IFMT) {
- case S_IFREG:
- break;
- case S_IFDIR:
- return -EISDIR;
- default:
- /* unknown file type */
- return FAT_ERROR;
- }
-
- if (FatFsCheckPermission(mountpt, false, WRITE_OP | EXEC_OP)) {
- return -EACCES;
- }
-
- fat = (FATFS *)mountpt->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES)
- return -ENOENT;
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL)
- return -ENOMEM;
-
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, relpath);
- if (ret < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- result = f_unlink(filePath);
-
- free(filePath);
-
- if (result == FR_OK) {
- return FatfsSdSync(mountpt->mountflags, fat);
- }
-
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_rename(struct inode *mountpt, const char *oldpath, const char *newpath)
-{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- FATFS *fat = NULL;
- FRESULT result;
- char *oldfspath = NULL;
- const char *newfspath = NULL;
- INT vol;
- size_t oldlen, newlen, len;
- INT ret;
-
- if (strlen(oldpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
- }
-
- if (mountpt->mountflags == MS_RDONLY)
- return -EACCES;
-
- oldlen = strlen(oldpath);
- newlen = strlen(newpath);
- if (!oldlen || !newlen) {
- return -EPERM;
- }
-
- len = oldlen < newlen ? oldlen : newlen;
- if (!strncmp(oldpath, newpath, len) && (oldpath[len] == '/' || newpath[len] == '/')) {
- return -EPERM;
- }
-
- if (FatFsCheckPermission(mountpt, false, WRITE_OP | EXEC_OP)) {
- return -EACCES;
- }
-
- fat = (FATFS *)mountpt->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- oldfspath = (char *)malloc(MAX_LFNAME_LENTH);
- if (oldfspath == NULL) {
- return -ENOMEM;
- }
-
- newfspath = newpath;
- ret = snprintf_s(oldfspath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, oldpath);
- if (ret < 0) {
- free(oldfspath);
- return -EINVAL;
- }
-
- result = f_rename(oldfspath, newfspath);
-
- free(oldfspath);
-
- if (result == FR_OK) {
- return FatfsSdSync(mountpt->mountflags, fat);
- }
-
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-static void get_stmtime(struct stat *st, FILINFO *finfo)
-{
- struct tm ftm;
- INT year, mon, day, hour, min, sec;
- WORD mtime;
-
- mtime = finfo->fdate;
- day = mtime & 0x1F; /* bit[4:0] Day(1..31) */
- mtime >>= 5;
- mon = mtime & 0x0F; /* bit[8:5] Month(1..12) */
- mtime >>= 4;
- year = (mtime & 0x7F) + 1980; /* bit[15:9] Year since 1980(0..127) */
-
- mtime = finfo->ftime;
- sec = (mtime & 0x1F) * 2; /* bit[4:0] Second/2(0..29) */
- mtime >>= 5;
- min = mtime & 0x3F; /* bit[10:5] Minute(0..59) */
- mtime >>= 6;
- hour = mtime & 0x1F; /* bit[15:11] Hour(0..23) */
-
- (void)memset_s(&ftm, sizeof(ftm), 0, sizeof(ftm));
- ftm.tm_year = year - 1900; /* Years since 1900 */
- ftm.tm_mon = mon - 1; /* Months since January: 0-11 */
- ftm.tm_mday = day; /* Day: 1-31 */
- ftm.tm_hour = hour; /* Hours: 0-23 */
- ftm.tm_min = min; /* Minutes: 0-59 */
- ftm.tm_sec = sec; /* Seconds: 0-59 */
-
- st->st_mtime = mktime(&ftm);
-}
-
-int fatfs_stat(struct inode *mountpt, const char *path, struct stat *buf)
-{
-#if FF_FS_MINIMIZE == 0
- FILINFO finfo;
- FRESULT result;
- FATFS *fat = NULL;
- INT vol, ret;
- char *filePath = NULL;
-
- if (mountpt == NULL || mountpt->i_private == NULL) {
- return -EINVAL;
- }
-
- if (strlen(path) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
- }
-
- fat = (FATFS *)mountpt->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
- return -ENOMEM;
- }
-
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, path);
- if (ret < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- result = f_stat(filePath, &finfo);
-
- (void)memset_s((void *)buf, sizeof(struct stat), 0, sizeof(struct stat));
-
- if (result == FR_OK) {
- buf->st_dev = 0;
-
- buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
- S_IWUSR | S_IWGRP | S_IWOTH |
- S_IXUSR | S_IXGRP | S_IXOTH;
-
- if (finfo.fattrib & AM_RDO) {
- buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- }
-
- if (finfo.fattrib & AM_DIR) {
- buf->st_mode &= ~S_IFREG;
- buf->st_mode |= S_IFDIR;
- buf->st_mode &= ~fat->fs_dmask;
- } else {
- buf->st_mode &= ~fat->fs_fmask;
- }
-
- if (!(mountpt->mountflags & MS_NOSUID)) {
- buf->st_uid = fat->fs_uid;
- buf->st_gid = fat->fs_gid;
- }
-
- buf->st_size = (long long)finfo.fsize;
-#if FF_MAX_SS != FF_MIN_SS
- buf->st_blksize = (unsigned long)fat->ssize * fat->csize;
-#else
- buf->st_blksize = (unsigned long)FF_MIN_SS * fat->csize;
-#endif
- buf->st_blocks = (unsigned long long)(buf->st_size + buf->st_blksize - 1) / buf->st_blksize;
- get_stmtime(buf, &finfo);
- }
-
- if ((result == FR_INVALID_NAME) && (strlen(path) == 0)) { /* root directory */
- buf->st_dev = 0;
- buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
- S_IWUSR | S_IWGRP | S_IWOTH;
-
- buf->st_mode &= ~S_IFREG;
- buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
- if (mountpt->mountflags & MS_RDONLY) {
- buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- }
-
- buf->st_mode &= ~fat->fs_dmask;
- buf->st_mtime = 0;
- buf->st_size = 0;
- if (!(mountpt->mountflags & MS_NOSUID)) {
- buf->st_uid = fat->fs_uid;
- buf->st_gid = fat->fs_gid;
- }
-
-#if FF_MAX_SS != FF_MIN_SS
- buf->st_blksize = (unsigned long)fat->ssize * fat->csize;
-#else
- buf->st_blksize = (unsigned long)FF_MIN_SS * fat->csize;
-#endif
- buf->st_blocks = (unsigned long long)(buf->st_size + buf->st_blksize - 1) / buf->st_blksize;
- result = FR_OK;
- }
-
- free(filePath);
-
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-#define VOL_NAME_LEN 4
-int fatfs_statfs(struct inode *mountpt, struct statfs *buf)
-{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- char drive[VOL_NAME_LEN];
- DWORD freClust;
- FATFS *fat = NULL;
- FRESULT result;
- INT vol, ret;
-
- FAT_CHECK(mountpt);
- FAT_CHECK(buf);
-
- fat = (FATFS *)mountpt->i_private;
- FAT_CHECK(fat);
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- ret = snprintf_s(drive, sizeof(drive), sizeof(drive) - 1, "%d:", vol);
- if (ret < 0) {
- return -EINVAL;
- }
-
- result = f_getfree(drive, &freClust, &fat);
if (result != FR_OK) {
- return fatfs_2_vfs(result);
+ goto ERROR_EXIT;
}
+ filep->f_pos = fpos;
- buf->f_type = MSDOS_SUPER_MAGIC;
- buf->f_bfree = freClust;
- buf->f_bavail = freClust;
- buf->f_blocks = fat->n_fatent - 2; /* Cluster #0 and #1 is for VBR, reserve sectors and fat */
-#if FF_MAX_SS != FF_MIN_SS
- buf->f_bsize = fat->ssize * fat->csize;
-#else
- buf->f_bsize = FF_MIN_SS * fat->csize;
-#endif
-
-#if FF_USE_LFN
- /* Maximum length of filenames */
- buf->f_namelen = FF_MAX_LFN;
-#else
- /* Maximum length of filenames: 8 is the basename length, 1 is the dot, 3 is the extension length */
- buf->f_namelen = (8 + 1 + 3);
-#endif
- buf->f_flags = mountpt->mountflags;
- return 0;
-#else
- return -ENOSYS;
-#endif
+ unlock_fs(fs, FR_OK);
+ return fpos;
+ERROR_EXIT:
+ unlock_fs(fs, result);
+ return -fatfs_2_vfs(result);
}
-int fatfs_utime(struct inode *mountpt, const char *pathname, const struct tm * set_tm)
+off_t fatfs_lseek(struct file *filep, off_t offset, int whence)
{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- FILINFO finfo;
- FRESULT result;
- FATFS *fat = NULL;
- INT vol, status;
- char *filePath = NULL;
-
- if (mountpt == NULL || mountpt->i_private == NULL) {
- return -EINVAL;
- }
-
- if (strlen(pathname) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
- }
-
- if (set_tm->tm_year < 80) { /* year must be lager than 1980 */
- PRINT_ERR("modetime must be lager than 1980-1-1\n");
- return -EINVAL;
- }
-
- if (mountpt->mountflags == MS_RDONLY) {
- return -EACCES;
- }
-
- fat = (FATFS *)mountpt->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
- return -ENOMEM;
- }
-
- status = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, pathname);
- if (status < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- /*
- * transform set_tm to be the format what we want,
- * and write in fatfs through f_utime to set modified
- * time.
- */
-
- /* fdate: bit[15:9] Year since 1980(0..127), bit[8:5] Month(0..11), bit[4:0] Day(1..31) */
- finfo.fdate = (WORD)(((UINT)(set_tm->tm_year - 80) << 9) | ((UINT)(set_tm->tm_mon + 1) << 5) |
- (UINT)set_tm->tm_mday);
- /* ftime: bit[15:11] Hour(0..23), bit[10:5] Minute(0..59), bit[4:0] Second/2(0..29) */
- finfo.ftime = (WORD)(((UINT)set_tm->tm_hour << 11) | ((UINT)set_tm->tm_min << 5) | ((UINT)set_tm->tm_sec >> 1));
- result = f_utime(filePath, &finfo);
- status = fatfs_2_vfs(result);
- free(filePath);
- return status;
-#else
- return -ENOSYS;
-#endif
+ return (off_t)fatfs_lseek64(filep, offset, whence);
}
-int fatfs_opendir(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir)
+static int update_filbuff(FILINFO *finfo, FIL *wfp, const char *data)
{
-#if FF_FS_MINIMIZE <= 1
- char *filePath = NULL;
- DIR *fdir = NULL;
- FATFS *fat = NULL;
+ LOS_DL_LIST *list = &finfo->fp_list;
+ FATFS *fs = wfp->obj.fs;
+ FIL *entry = NULL;
+ int ret = 0;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(entry, list, FIL, fp_entry) {
+ if (entry == wfp) {
+ continue;
+ }
+ if (entry->sect != 0) {
+ if (disk_read(fs->pdrv, entry->buf, entry->sect, 1) != RES_OK) {
+ ret = -1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+int fatfs_write(struct file *filep, const char *buff, size_t count)
+{
+ FIL *fp = (FIL *)filep->f_priv;
+ FATFS *fs = fp->obj.fs;
+ struct Vnode *vp = filep->f_vnode;
+ FILINFO *finfo = &(((DIR_FILE *)vp->data)->fno);
+ size_t wcount;
FRESULT result;
- INT vol, ret;
+ int ret;
- if (strlen(relpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
}
-
- FAT_CHECK(dir);
- fat = (FATFS *)mountpt->i_private;
- FAT_CHECK(fat);
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
- return -ENOMEM;
- }
-
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, relpath);
- if (ret < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- /* open directory */
- fdir = (DIR *)malloc(sizeof(DIR));
- if (fdir == NULL) {
- free(filePath);
- return -ENOMEM;
- }
-
- result = f_opendir(fdir, filePath);
- free(filePath);
-
+ fp->obj.objsize = finfo->fsize;
+ fp->obj.sclust = finfo->sclst;
+ result = f_write(fp, buff, count, &wcount);
if (result != FR_OK) {
- free(fdir);
- return fatfs_2_vfs(result);
+ goto ERROR_EXIT;
}
- dir->u.fs_dir = (fs_dir_s)fdir;
- return FR_OK;
-#else
- return -ENOSYS;
-#endif
+ finfo->fsize = fp->obj.objsize;
+ finfo->sclst = fp->obj.sclust;
+ result = f_sync(fp);
+ if (result != FR_OK) {
+ goto ERROR_EXIT;
+ }
+ update_filbuff(finfo, fp, buff);
+
+ filep->f_pos = fp->fptr;
+
+ unlock_fs(fs, FR_OK);
+ return wcount;
+ERROR_EXIT:
+ unlock_fs(fs, result);
+ return -fatfs_2_vfs(result);
}
-int fatfs_closedir(struct inode *mountpt, struct fs_dirent_s *dir)
+int fatfs_fsync(struct file *filep)
{
-#if FF_FS_MINIMIZE <= 1
- DIR *fdir = NULL;
+ FIL *fp = filep->f_priv;
+ FATFS *fs = fp->obj.fs;
+ FRESULT result;
+ int ret;
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+
+ result = f_sync(fp);
+ unlock_fs(fs, result);
+ return -fatfs_2_vfs(result);
+}
+
+int fatfs_fallocate64(struct file *filep, int mode, off64_t offset, off64_t len)
+{
+ FIL *fp = (FIL *)filep->f_priv;
+ FATFS *fs = fp->obj.fs;
+ struct Vnode *vp = filep->f_vnode;
+ FILINFO *finfo = &((DIR_FILE *)(vp->data))->fno;
+ FRESULT result;
+ int ret;
+
+ if (offset < 0 || len <= 0) {
+ return -EINVAL;
+ }
+
+ if (len >= FAT32_MAXSIZE || offset >= FAT32_MAXSIZE ||
+ len + offset >= FAT32_MAXSIZE) {
+ return -EINVAL;
+ }
+
+ if (mode != FALLOC_FL_KEEP_SIZE) {
+ return -EINVAL;
+ }
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+ result = f_expand(fp, (FSIZE_t)offset, (FSIZE_t)len, 1);
+ if (result == FR_OK && finfo->sclst == 0) {
+ finfo->sclst = fp->obj.sclust;
+ }
+ result = f_sync(fp);
+ unlock_fs(fs, FR_OK);
+
+ return -fatfs_2_vfs(result);
+}
+
+static FRESULT realloc_cluster(FILINFO *finfo, FFOBJID *obj, FSIZE_t size)
+{
+ FATFS *fs = obj->fs;
+ off64_t remain;
+ DWORD cclust;
+ DWORD pclust;
+ QWORD csize;
FRESULT result;
- FAT_CHECK(dir);
- fdir = (DIR *)(dir->u.fs_dir);
- FAT_CHECK(fdir);
-
- result = f_closedir(fdir);
- if (result == FR_OK) {
- free(fdir);
+ if (size == 0) { /* Remove cluster chain */
+ if (finfo->sclst != 0) {
+ result = remove_chain(obj, finfo->sclst, 0);
+ if (result != FR_OK) {
+ return result;
+ }
+ finfo->sclst = 0;
+ }
return FR_OK;
}
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- int i = 0;
-#if FF_FS_MINIMIZE <= 1
- DIR *fdir = NULL;
- FILINFO fno;
- FRESULT result;
- struct dirent *d = NULL;
-
- FAT_CHECK(dir);
- fdir = (DIR *)(dir->u.fs_dir);
-
- while (i < dir->read_cnt) {
- d = &(dir->fd_dir[i]);
-
- (void)memset_s(&fno, sizeof(FILINFO), 0, sizeof(FILINFO));
- result = f_readdir(fdir, &fno);
+ remain = size;
+ csize = SS(fs) * fs->csize;
+ if (finfo->sclst == 0) { /* Allocate one cluster if file doesn't have any cluster */
+ cclust = create_chain(obj, 0);
+ if (cclust == 0) {
+ return FR_NO_SPACE_LEFT;
+ }
+ if (cclust == 1 || cclust == DISK_ERROR) {
+ return FR_DISK_ERR;
+ }
+ finfo->sclst = cclust;
+ }
+ cclust = finfo->sclst;
+ while (remain > csize) { /* Follow or strentch the cluster chain */
+ pclust = cclust;
+ cclust = create_chain(obj, pclust);
+ if (cclust == 0) {
+ return FR_NO_SPACE_LEFT;
+ }
+ if (cclust == 1 || cclust == DISK_ERROR) {
+ return FR_DISK_ERR;
+ }
+ remain -= csize;
+ }
+ pclust = cclust;
+ cclust = get_fat(obj, pclust);
+ if ((cclust == BAD_CLUSTER) || (cclust == DISK_ERROR)) {
+ return FR_DISK_ERR;
+ }
+ if (cclust != END_OF_FILE) { /* Remove extra cluster if existing */
+ result = remove_chain(obj, cclust, pclust);
if (result != FR_OK) {
- break;
+ return result;
}
-
- /*
- * 0x00:Reached end of directory.
- * 0xFF:The directory is empty.
- */
- if (fno.fname[0] == 0 || fno.fname[0] == (TCHAR)0xFF) {
- break;
- }
-
- if (fno.fattrib & AM_DIR) {
- d->d_type = DT_DIR;
- } else {
- d->d_type = DT_REG;
- }
-
- if (strncpy_s(d->d_name, sizeof(d->d_name), fno.fname, strlen(fno.fname)) != EOK) {
- return -ENAMETOOLONG;
- }
-
- dir->fd_position++;
- dir->fd_dir[i].d_off = dir->fd_position;
- dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent);
- i++;
- }
-
- return i;
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_readdir_all(DIR_FAT *dir_fat)
-{
-#if FF_FS_MINIMIZE <= 1
- char *fn = NULL;
- DIR *fdir = NULL;
- FILINFO fno;
- FRESULT result;
- struct fs_dirent_s *dir = NULL;
- struct fat_direntall *d = NULL;
- INT ret;
- INT year, mon, day, hour, min, sec;
- WORD tmp;
-
- FAT_CHECK(dir_fat);
- dir = (struct fs_dirent_s *)dir_fat->stDirStream.dp;
-
- FAT_CHECK(dir);
- fdir = (DIR *)(dir->u.fs_dir);
- d = &dir_fat->stBuf.direntall;
-
- result = f_readdir(fdir, &fno);
- if (result != FR_OK) {
- return fatfs_2_vfs(result);
- }
-
- /*
- * 0x00:Reached end of directory.
- * 0xFF:The directory is empty.
- */
- if (fno.fname[0] == 0 || fno.fname[0] == (TCHAR)0xFF) {
- return -ENOENT;
- }
-
- fn = fno.fname;
-
- if (fno.fattrib & AM_DIR) {
- d->d_type = DT_DIR;
- } else {
- d->d_type = DT_REG;
- }
-
-#ifdef _DIRENT_HAVE_D_NAMLEN
- d->d_namlen = (BYTE)strlen(fn);
-#endif
- d->d_reclen = (WORD)(sizeof(struct fat_direntall) + strlen(fn));
- ret = strncpy_s(d->d_name, NAME_MAX, fn, strlen(fn));
- if (ret != EOK) {
- return -ENAMETOOLONG;
- }
-#ifdef _DIRENT_HAVE_D_OFF
- d->d_off++;
-#endif
-
- d->d_size = fno.fsize;
-
- /* get st_mtime. */
- tmp = fno.fdate;
- day = tmp & 0x1F; /* bit[4:0] Day(1..31) */
- tmp >>= 5;
- mon = tmp & 0x0F; /* bit[8:5] Month(1..12) */
- tmp >>= 4;
- year = tmp & 0x7F; /* bit[15:9] Year since 1980(0..127) */
-
- tmp = fno.ftime;
- sec = (tmp & 0x1F) * 2; /* bit[4:0] Second/2(0..29) */
- tmp >>= 5;
- min = tmp & 0x3F; /* bit[10:5] Minute(0..59) */
- tmp >>= 6;
- hour = tmp & 0x1F; /* bit[15:11] Hour(0..23) */
-
- d->d_createtime[0] = year;
- d->d_createtime[1] = mon;
- d->d_createtime[2] = day;
- d->d_createtime[3] = hour;
- d->d_createtime[4] = min;
- d->d_createtime[5] = sec;
-
- return ENOERR;
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
-#if FF_FS_MINIMIZE <= 1
- DIR *fdir = NULL;
- FRESULT result;
-
- FAT_CHECK(dir);
- fdir = (DIR *)(dir->u.fs_dir);
- FAT_CHECK(fdir);
-
- result = f_rewinddir(fdir);
- if (result != FR_OK) {
- return fatfs_2_vfs(result);
}
return FR_OK;
-#else
- return -ENOSYS;
-#endif
}
-int fatfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
+int fatfs_fallocate(struct file *filep, int mode, off_t offset, off_t len)
{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- char *filePath = NULL;
- FATFS *fat = NULL;
- FRESULT result;
- INT vol, ret;
+ return fatfs_fallocate64(filep, mode, offset, len);
+}
- if (mountpt->mountflags == MS_RDONLY) {
- return -EACCES;
- }
+int fatfs_truncate64(struct Vnode *vp, off64_t len)
+{
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ DIR *dp = &(dfp->f_dir);
+ FILINFO *finfo = &(dfp->fno);
+ FFOBJID object;
+ FRESULT result = FR_OK;
+ int ret;
- if (strlen(relpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
- }
-
- if (FatFsCheckPermission(mountpt, true, WRITE_OP | EXEC_OP)) {
- return -EACCES;
- }
-
- fat = (FATFS *)mountpt->i_private;
- FAT_CHECK(fat);
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
- return -ENOMEM;
- }
-
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, relpath);
- if (ret < 0) {
- free(filePath);
+ if (len < 0 || len >= FAT32_MAXSIZE) {
return -EINVAL;
}
- result = f_mkdir(filePath);
- free(filePath);
-
- if (result == FR_OK) {
- return FatfsSdSync(mountpt->mountflags, fat);
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ result = FR_TIMEOUT;
+ goto ERROR_OUT;
+ }
+ if (len == finfo->fsize) {
+ unlock_fs(fs, FR_OK);
+ return 0;
}
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
+ object.fs = fs;
+ result = realloc_cluster(finfo, &object, (FSIZE_t)len);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ finfo->fsize = (FSIZE_t)len;
+
+ result = update_dir(dp, finfo);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ unlock_fs(fs, FR_OK);
+ return fatfs_sync(vp->originMount->mountFlags, fs);
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ERROR_OUT:
+ return -fatfs_2_vfs(result);
}
-int fatfs_rmdir(struct inode *mountpt, const char *relpath)
+int fatfs_truncate(struct Vnode *vp, off_t len)
{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- char *filePath = NULL;
- FATFS *fat = NULL;
+ return fatfs_truncate64(vp, len);
+}
+
+static int fat_bind_check(struct Vnode *blk_driver, los_part **partition)
+{
+ los_part *part = NULL;
+
+ if (blk_driver == NULL || blk_driver->data == NULL) {
+ return ENODEV;
+ }
+
+ struct drv_data *dd = blk_driver->data;
+ if (dd->ops == NULL) {
+ return ENODEV;
+ }
+ const struct block_operations *bops = dd->ops;
+ if (bops->open == NULL) {
+ return EINVAL;
+ }
+ if (bops->open(blk_driver) < 0) {
+ return EBUSY;
+ }
+
+ part = los_part_find(blk_driver);
+ if (part->part_name != NULL) {
+ bops->close(blk_driver);
+ return EBUSY;
+ }
+
+#ifndef FF_MULTI_PARTITION
+ if (part->part_no_mbr > 1) {
+ bops->close(blk_driver);
+ return EPERM;
+ }
+#endif
+
+ *partition = part;
+ return 0;
+}
+
+int fatfs_mount(struct Mount *mnt, struct Vnode *blk_device, const void *data)
+{
+ struct Vnode *vp = NULL;
+ FATFS *fs = NULL;
+ DIR_FILE *dfp = NULL;
+ los_part *part = NULL;
+ QWORD start_sector;
+ BYTE fmt;
+ DWORD hash;
FRESULT result;
- INT ret, vol;
- struct stat st;
+ int ret;
- if (strlen(relpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
+ ret = fat_bind_check(blk_device, &part);
+ if (ret != 0) {
+ goto ERROR_EXIT;
}
- if (mountpt->mountflags == MS_RDONLY) {
- return -EACCES;
+ ret = SetDiskPartName(part, "vfat");
+ if (ret != 0) {
+ ret = EIO;
+ goto ERROR_EXIT;
}
- ret = fatfs_stat(mountpt, relpath, &st);
- if (ret != FR_OK) {
- return ret;
+ fs = (FATFS *)zalloc(sizeof(FATFS));
+ if (fs == NULL) {
+ ret = ENOMEM;
+ goto ERROR_PARTNAME;
}
- switch (st.st_mode & S_IFMT) {
- case S_IFDIR:
+#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+ fs->vir_flag = FS_PARENT;
+ fs->parent_fs = fs;
+ fs->vir_amount = DISK_ERROR;
+ fs->vir_avail = FS_VIRDISABLE;
+#endif
+
+ ret = ff_cre_syncobj(0, &fs->sobj);
+ if (ret == 0) { /* create sync object failed */
+ ret = EINVAL;
+ goto ERROR_WITH_FS;
+ }
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ ret = EBUSY;
+ goto ERROR_WITH_MUX;
+ }
+
+ fs->fs_type = 0;
+ fs->pdrv = part->part_id;
+
+#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
+ if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &(fs->ssize)) != RES_OK) {
+ ret = EIO;
+ goto ERROR_WITH_LOCK;
+ }
+ if (fs->ssize > FF_MAX_SS || fs->ssize < FF_MIN_SS || (fs->ssize & (fs->ssize - 1))) {
+ ret = EIO;
+ goto ERROR_WITH_LOCK;
+ }
+#endif
+
+ fs->win = (BYTE *)ff_memalloc(SS(fs));
+ if (fs->win == NULL) {
+ ret = ENOMEM;
+ goto ERROR_WITH_LOCK;
+ }
+
+ result = find_fat_partition(fs, part, &fmt, &start_sector);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_WITH_FSWIN;
+ }
+
+ result = init_fatobj(fs, fmt, start_sector);
+ if (result != FR_OK) {
+ ret = fatfs_2_vfs(result);
+ goto ERROR_WITH_FSWIN;
+ }
+
+ fs->fs_uid = mnt->vnodeBeCovered->uid;
+ fs->fs_gid = mnt->vnodeBeCovered->gid;
+ fs->fs_dmask = GetUmask();
+ fs->fs_fmask = GetUmask();
+ fs->fs_mode = mnt->vnodeBeCovered->mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+
+ dfp = (DIR_FILE *)zalloc(sizeof(DIR_FILE));
+ if (dfp == NULL) {
+ ret = ENOMEM;
+ goto ERROR_WITH_FSWIN;
+ }
+
+ dfp->f_dir.obj.fs = fs;
+ dfp->f_dir.obj.sclust = 0; /* set start clust 0, root */
+ dfp->f_dir.obj.attr = AM_DIR;
+ dfp->f_dir.obj.objsize = 0; /* dir size is 0 */
+ dfp->fno.fsize = 0;
+ dfp->fno.fdate = 0;
+ dfp->fno.ftime = 0;
+ dfp->fno.fattrib = AM_DIR;
+ dfp->fno.sclst = 0;
+ dfp->fno.fname[0] = '/'; /* Mark as root dir */
+ dfp->fno.fname[1] = '\0';
+ LOS_ListInit(&(dfp->fno.fp_list));
+
+ ret = VnodeAlloc(&fatfs_vops, &vp);
+ if (ret != 0) {
+ ret = ENOMEM;
+ goto ERROR_WITH_FSWIN;
+ }
+
+ mnt->data = fs;
+ mnt->vnodeCovered = vp;
+
+ vp->parent = mnt->vnodeBeCovered;
+ vp->fop = &fatfs_fops;
+ vp->data = dfp;
+ vp->originMount = mnt;
+ vp->uid = fs->fs_uid;
+ vp->gid = fs->fs_gid;
+ vp->mode = mnt->vnodeBeCovered->mode;
+ vp->type = VNODE_TYPE_DIR;
+
+ hash = fatfs_hash(0, 0, 0);
+ ret = VfsHashInsert(vp, hash);
+ if (ret != 0) {
+ ret = -ret;
+ goto ERROR_WITH_LOCK;
+ }
+ unlock_fs(fs, FR_OK);
+
+ return 0;
+
+ERROR_WITH_FSWIN:
+ ff_memfree(fs->win);
+ERROR_WITH_LOCK:
+ unlock_fs(fs, FR_OK);
+ERROR_WITH_MUX:
+ ff_del_syncobj(&fs->sobj);
+ERROR_WITH_FS:
+ free(fs);
+ERROR_PARTNAME:
+ if (part->part_name) {
+ free(part->part_name);
+ part->part_name = NULL;
+ }
+ERROR_EXIT:
+ return -ret;
+}
+
+int fatfs_umount(struct Mount *mnt, struct Vnode **blkdriver)
+{
+ struct Vnode *device;
+ FATFS *fs = (FATFS *)mnt->data;
+ los_part *part;
+ int ret;
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+
+ part = get_part(fs->pdrv);
+ if (part == NULL) {
+ unlock_fs(fs, FR_OK);
+ return -ENODEV;
+ }
+ device = part->dev;
+ if (device == NULL) {
+ unlock_fs(fs, FR_OK);
+ return -ENODEV;
+ }
+#ifdef LOSCFG_FS_FAT_CACHE
+ ret = OsSdSync(part->disk_id);
+ if (ret != 0) {
+ unlock_fs(fs, FR_DISK_ERR);
+ return -EIO;
+ }
+#endif
+ if (part->part_name != NULL) {
+ free(part->part_name);
+ part->part_name = NULL;
+ }
+
+ struct drv_data *dd = device->data;
+ if (dd->ops == NULL) {
+ unlock_fs(fs, FR_OK);
+ return ENODEV;
+ }
+
+ const struct block_operations *bops = dd->ops;
+ if (bops != NULL && bops->close != NULL) {
+ bops->close(*blkdriver);
+ }
+
+ if (fs->win != NULL) {
+ ff_memfree(fs->win);
+ }
+
+ unlock_fs(fs, FR_OK);
+
+ ret = ff_del_syncobj(&fs->sobj);
+ if (ret == FALSE) {
+ return -EINVAL;
+ }
+ free(fs);
+
+ *blkdriver = device;
+
+ return 0;
+}
+
+int fatfs_statfs(struct Mount *mnt, struct statfs *info)
+{
+ FATFS *fs = (FATFS *)mnt->data;
+
+ info->f_type = MSDOS_SUPER_MAGIC;
+#if FF_MAX_SS != FF_MIN_SS
+ info->f_bsize = fs->ssize * fs->csize;
+#else
+ info->f_bsize = FF_MIN_SS * fs->csize;
+#endif
+ info->f_blocks = fs->n_fatent;
+ info->f_bfree = fs->free_clst;
+ info->f_bavail = fs->free_clst;
+
+#if FF_USE_LFN
+ /* Maximum length of filenames */
+ info->f_namelen = FF_MAX_LFN;
+#else
+ /* Maximum length of filenames: 8 is the basename length, 1 is the dot, 3 is the extension length */
+ info->f_namelen = (8 + 1 + 3);
+#endif
+ info->f_fsid.__val[0] = MSDOS_SUPER_MAGIC;
+ info->f_fsid.__val[1] = 1;
+ info->f_frsize = SS(fs) * fs->csize;
+ info->f_files = 0;
+ info->f_ffree = 0;
+ info->f_flags = mnt->mountFlags;
+
+ return 0;
+}
+
+static inline int GET_SECONDS(WORD ftime)
+{
+ return (ftime & BITMASK5) * SEC_MULTIPLIER;
+}
+static inline int GET_MINUTES(WORD ftime)
+{
+ return (ftime >> FTIME_MIN_OFFSET) & BITMASK6;
+}
+static inline int GET_HOURS(WORD ftime)
+{
+ return (ftime >> FTIME_HR_OFFSET) & BITMASK5;
+}
+static inline int GET_DAY(WORD fdate)
+{
+ return fdate & BITMASK5;
+}
+static inline int GET_MONTH(WORD fdate)
+{
+ return (fdate >> FTIME_MTH_OFFSET) & BITMASK4;
+}
+static inline int GET_YEAR(WORD fdate)
+{
+ return (fdate >> FTIME_YEAR_OFFSET) & BITMASK7;
+}
+
+static time_t fattime_transfer(WORD fdate, WORD ftime)
+{
+ struct tm time;
+ time.tm_sec = GET_SECONDS(ftime);
+ time.tm_min = GET_MINUTES(ftime);
+ time.tm_hour = GET_HOURS(ftime);
+ time.tm_mday = GET_DAY(fdate);
+ time.tm_mon = GET_MONTH(fdate);
+ time.tm_year = GET_YEAR(fdate) + YEAR_OFFSET; /* Year start from 1980 in FATFS */
+ time_t ret = mktime(&time);
+ return ret;
+}
+
+DWORD fattime_format(time_t time)
+{
+ struct tm st;
+ DWORD ftime;
+
+ localtime_r(&time, &st);
+
+ ftime = (DWORD)st.tm_mday;
+ ftime |= ((DWORD)st.tm_mon) << FTIME_MTH_OFFSET;
+ ftime |= ((DWORD)((st.tm_year > YEAR_OFFSET) ? (st.tm_year - YEAR_OFFSET) : 0)) << FTIME_YEAR_OFFSET;
+ ftime <<= FTIME_DATE_OFFSET;
+
+ ftime = (DWORD)st.tm_sec / SEC_MULTIPLIER;
+ ftime |= ((DWORD)st.tm_min) << FTIME_MIN_OFFSET;
+ ftime |= ((DWORD)st.tm_hour) << FTIME_HR_OFFSET;
+
+ return ftime;
+}
+
+int fatfs_stat(struct Vnode *vp, struct stat* sp)
+{
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ FILINFO *finfo = &(dfp->fno);
+ time_t time;
+ int ret;
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return EBUSY;
+ }
+
+ sp->st_dev = fs->pdrv;
+ sp->st_mode = vp->mode;
+ sp->st_nlink = 1;
+ sp->st_uid = fs->fs_uid;
+ sp->st_gid = fs->fs_gid;
+ sp->st_size = finfo->fsize;
+ sp->st_blksize = fs->csize * SS(fs);
+ sp->st_blocks = finfo->fsize ? ((finfo->fsize - 1) / SS(fs) / fs->csize + 1) : 0;
+ time = fattime_transfer(finfo->fdate, finfo->ftime);
+ sp->st_mtime = time;
+
+ unlock_fs(fs, FR_OK);
+ return 0;
+}
+
+void fatfs_chtime(DIR *dp, struct IATTR *attr)
+{
+ BYTE *dir = dp->dir;
+ DWORD ftime;
+ if (attr->attr_chg_valid & CHG_ATIME) {
+ ftime = fattime_format(attr->attr_chg_atime);
+ st_word(dir + DIR_LstAccDate, (ftime >> FTIME_DATE_OFFSET));
+ }
+
+ if (attr->attr_chg_valid & CHG_CTIME) {
+ ftime = fattime_format(attr->attr_chg_ctime);
+ st_dword(dir + DIR_CrtTime, ftime);
+ }
+
+ if (attr->attr_chg_valid & CHG_MTIME) {
+ ftime = fattime_format(attr->attr_chg_mtime);
+ st_dword(dir + DIR_ModTime, ftime);
+ }
+}
+
+int fatfs_chattr(struct Vnode *vp, struct IATTR *attr)
+{
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ DIR *dp = &(dfp->f_dir);
+ FILINFO *finfo = &(dfp->fno);
+ BYTE *dir = dp->dir;
+ DWORD ftime;
+ FRESULT result;
+ int ret;
+
+ if (finfo->fname[0] == '/') { /* Is root dir of fatfs ? */
+ return 0;
+ }
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ result = FR_TIMEOUT;
+ goto ERROR_OUT;
+ }
+
+ result = move_window(fs, dp->sect);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+
+ if (attr->attr_chg_valid & CHG_MODE) {
+ /* FAT only support readonly flag */
+ if ((attr->attr_chg_mode & S_IWUSR) == 0 && (finfo->fattrib & AM_RDO) == 0) {
+ dir[DIR_Attr] |= AM_RDO;
+ finfo->fattrib |= AM_RDO;
+ fs->wflag = 1;
+ } else if ((attr->attr_chg_mode & S_IWUSR) != 0 && (finfo->fattrib & AM_RDO) != 0) {
+ dir[DIR_Attr] &= ~AM_RDO;
+ finfo->fattrib &= ~AM_RDO;
+ fs->wflag = 1;
+ }
+ vp->mode = fatfs_get_mode(finfo->fattrib, fs->fs_mode);
+ }
+
+ if (attr->attr_chg_valid & (CHG_ATIME | CHG_CTIME | CHG_MTIME)) {
+ fatfs_chtime(dp, attr);
+ ftime = ld_dword(dp->dir + DIR_ModTime);
+ finfo->fdate = (WORD)(ftime >> FTIME_DATE_OFFSET);
+ finfo->ftime = (WORD)ftime;
+ }
+
+ result = sync_window(fs);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+
+ unlock_fs(fs, FR_OK);
+ return fatfs_sync(vp->originMount->mountFlags, fs);
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ERROR_OUT:
+ return -fatfs_2_vfs(result);
+}
+
+int fatfs_opendir(struct Vnode *vp, struct fs_dirent_s *idir)
+{
+ FATFS *fs = vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ FILINFO *finfo = &(dfp->fno);
+ DIR *dp;
+ DWORD clst;
+ FRESULT result;
+ int ret;
+
+ dp = (DIR*)zalloc(sizeof(DIR));
+ if (dp == NULL) {
+ return -ENOMEM;
+ }
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+ clst = finfo->sclst;
+ dp->obj.fs = fs;
+ dp->obj.sclust = clst;
+
+ result = dir_sdi(dp, 0);
+ if (result != FR_OK) {
+ free(dp);
+ unlock_fs(fs, result);
+ return -fatfs_2_vfs(result);
+ }
+ unlock_fs(fs, result);
+ idir->u.fs_dir = dp;
+
+ return 0;
+}
+
+int fatfs_readdir(struct Vnode *vp, struct fs_dirent_s *idir)
+{
+ FATFS *fs = vp->originMount->data;
+ FILINFO fno;
+ DIR* dp = (DIR*)idir->u.fs_dir;
+ struct dirent *dirp = NULL;
+ FRESULT result;
+ int ret, i;
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) { /* Lock fs failed */
+ return -EBUSY;
+ }
+ DEF_NAMBUF;
+ INIT_NAMBUF(fs);
+ for (i = 0; i < DIR_READ_COUNT && i < idir->read_cnt; i++) {
+ result = dir_read(dp, 0);
+ if (result == FR_NO_FILE) {
break;
- case S_IFREG:
- return -ENOTDIR;
- default:
- /* unknown file type */
- return FAT_ERROR;
+ } else if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ get_fileinfo(dp, &fno);
+ /* 0x00 for end of directory and 0xFF for directory is empty */
+ if (fno.fname[0] == 0x00 || fno.fname[0] == (TCHAR)0xFF) {
+ break;
+ }
+
+ dirp = &(idir->fd_dir[i]);
+ if (fno.fattrib & AM_DIR) { /* is dir */
+ dirp->d_type = DT_DIR;
+ } else {
+ dirp->d_type = DT_REG;
+ }
+ if (strncpy_s(dirp->d_name, sizeof(dirp->d_name), fno.fname, strlen(fno.fname)) != EOK) {
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_UNLOCK;
+ }
+ result = dir_next(dp, 0);
+ if (result != FR_OK && result != FR_NO_FILE) {
+ goto ERROR_UNLOCK;
+ }
+ idir->fd_position++;
+ idir->fd_dir[i].d_off = idir->fd_position;
+ idir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent);
}
-
- if (FatFsCheckPermission(mountpt, true, WRITE_OP | EXEC_OP)) {
- return -EACCES;
- }
-
- fat = (FATFS *)mountpt->i_private;
- FAT_CHECK(fat);
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
- return -ENOMEM;
- }
-
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, relpath);
- if (ret < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- result = f_unlink(filePath);
- free(filePath);
-
- if (result == FR_OK) {
- return FatfsSdSync(mountpt->mountflags, fat);
- }
-
- return fatfs_2_vfs(result);
-#else
- return -ENOSYS;
-#endif
+ unlock_fs(fs, FR_OK);
+ FREE_NAMBUF();
+ return i;
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ return -fatfs_2_vfs(result);
}
-static INT FatFsErase(INT option, los_part *part)
+int fatfs_rewinddir(struct Vnode *vp, struct fs_dirent_s *dir)
{
- INT opt = option;
+ DIR *dp = (DIR *)dir->u.fs_dir;
+ FATFS *fs = dp->obj.fs;
+ FRESULT result;
+ int ret;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ return -EBUSY;
+ }
+
+ result = dir_sdi(dp, 0);
+ unlock_fs(fs, result);
+ return -fatfs_2_vfs(result);
+}
+
+int fatfs_closedir(struct Vnode *vp, struct fs_dirent_s *dir)
+{
+ DIR *dp = (DIR *)dir->u.fs_dir;
+ free(dp);
+ dir->u.fs_dir = NULL;
+ return 0;
+}
+
+static FRESULT rename_check(DIR *dp_new, FILINFO *finfo_new, DIR *dp_old, FILINFO *finfo_old)
+{
+ DIR dir_sub;
+ FRESULT result;
+ if (finfo_new->fattrib & AM_ARC) { /* new path is file */
+ if (finfo_old->fattrib & AM_DIR) { /* but old path is dir */
+ return FR_NO_DIR;
+ }
+ } else if (finfo_new->fattrib & AM_DIR) { /* new path is dir */
+ if (finfo_old->fattrib & AM_ARC) { /* old path is file */
+ return FR_IS_DIR;
+ }
+ dir_sub.obj.fs = dp_old->obj.fs;
+ dir_sub.obj.sclust = finfo_new->sclst;
+ result = dir_sdi(&dir_sub, 0);
+ if (result != FR_OK) {
+ return result;
+ }
+ result = dir_read(&dir_sub, 0);
+ if (result == FR_OK) { /* new path isn't empty file */
+ return FR_NO_EMPTY_DIR;
+ }
+ } else { /* System file or volume label */
+ return FR_DENIED;
+ }
+ return FR_OK;
+}
+
+int fatfs_rename(struct Vnode *old_vnode, struct Vnode *new_parent, const char *oldname, const char *newname)
+{
+ FATFS *fs = (FATFS *)(old_vnode->originMount->data);
+ DIR_FILE *dfp_old = (DIR_FILE *)old_vnode->data;
+ DIR *dp_old = &(dfp_old->f_dir);
+ FILINFO *finfo_old = &(dfp_old->fno);
+ DIR_FILE *dfp_new = NULL;
+ DIR* dp_new = NULL;
+ FILINFO* finfo_new = NULL;
+ DWORD clust;
+ FRESULT result;
+ int ret;
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) { /* Lock fs failed */
+ return -EBUSY;
+ }
+
+ dfp_new = (DIR_FILE *)zalloc(sizeof(DIR_FILE));
+ if (dfp_new == NULL) {
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_UNLOCK;
+ }
+ dp_new = &(dfp_new->f_dir);
+ finfo_new = &(dfp_new->fno);
+
+ dp_new->obj.sclust = ((DIR_FILE *)(new_parent->data))->fno.sclst;
+ dp_new->obj.fs = fs;
+
+ /* Find new path */
+ DEF_NAMBUF;
+ INIT_NAMBUF(fs);
+ result = create_name(dp_new, &newname);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ result = dir_find(dp_new);
+ if (result == FR_OK) { /* new path name exist */
+ get_fileinfo(dp_new, finfo_new);
+ result = rename_check(dp_new, finfo_new, dp_old, finfo_old);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ result = dir_remove(dp_old);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ clust = finfo_new->sclst;
+ if (clust != 0) { /* remove the new path cluster chain if exists */
+ result = remove_chain(&(dp_new->obj), clust, 0);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ }
+ } else { /* new path name not exist */
+ result = dir_remove(dp_old);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ result = dir_register(dp_new);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ }
+
+ /* update new dir entry with old info */
+ result = update_dir(dp_new, finfo_old);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ result = dir_read(dp_new, 0);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
+ }
+ get_fileinfo(dp_new, finfo_new);
+
+ dfp_new->fno.fp_list.pstNext = dfp_old->fno.fp_list.pstNext;
+ dfp_new->fno.fp_list.pstPrev = dfp_old->fno.fp_list.pstPrev;
+ ret = memcpy_s(dfp_old, sizeof(DIR_FILE), dfp_new, sizeof(DIR_FILE));
+ if (ret != 0) {
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_FREE;
+ }
+ free(dfp_new);
+ unlock_fs(fs, FR_OK);
+ FREE_NAMBUF();
+ return fatfs_sync(old_vnode->originMount->mountFlags, fs);
+
+ERROR_FREE:
+ free(dfp_new);
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ return -fatfs_2_vfs(result);
+}
+
+
+static int fatfs_erase(los_part *part, int option)
+{
+ int opt = option;
if ((UINT)opt & FMT_ERASE) {
opt = (UINT)opt & (~FMT_ERASE);
- if (EraseDiskByID(part->disk_id, part->sector_start, part->sector_count) != 0) {
- PRINTK("SD card erase error.\n");
+ if (EraseDiskByID(part->disk_id, part->sector_start, part->sector_count) != LOS_OK) {
+ PRINTK("Disk erase error.\n");
+ return -1;
}
}
@@ -1710,715 +1576,508 @@ static INT FatFsErase(INT option, los_part *part)
return opt;
}
-static INT FatFsMountEmpty(los_part *part, char *drive, INT len, FATFS *fat)
-{
- INT result, index;
-
- index = fatfs_get_vol((FATFS *)NULL);
- if (index == FAT_ERROR) {
- return -EEXIST; /* can't find empty fatfs */
- }
-
- VolToPart[index].di = part->disk_id;
- VolToPart[index].pd = part->part_id;
- VolToPart[index].pt = part->part_no_mbr;
- VolToPart[index].ps = part->sector_start;
- VolToPart[index].pc = part->sector_count;
-
- result = snprintf_s(drive, len, len - 1, "%d:/", index);
- if (result < 0) {
- return -EINVAL;
- }
-
- result = f_mount(fat, drive, 0);
- if (result != FR_OK) {
- return fatfs_2_vfs(result);
- }
-
- return index;
-}
-
-#define DMA_ALLGN 64
-static INT FatFsSetPartInfo(INT index, los_part *part)
+static int fatfs_set_part_info(los_part *part)
{
los_disk *disk = NULL;
- char *mbrBuf = NULL;
- INT result;
+ char *buf = NULL;
+ int ret;
- /* if there is no mbr before, the partition info needs to be changed after formatting. */
- if ((part->type != EMMC) && (part->part_no_mbr == 0)) {
+ /* If there is no MBR before, the partition info needs to be changed after mkfs */
+ if (part->type != EMMC && part->part_no_mbr == 0) {
disk = get_disk(part->disk_id);
if (disk == NULL) {
return -EIO;
}
- mbrBuf = (char *)memalign(DMA_ALLGN, disk->sector_size);
- if (mbrBuf == NULL) {
+ buf = (char *)zalloc(disk->sector_size);
+ if (buf == NULL) {
return -ENOMEM;
}
- (void)memset_s(mbrBuf, disk->sector_size, 0, disk->sector_size);
- result = los_disk_read(part->disk_id, mbrBuf, 0, 1);
- if (result < 0) {
- free(mbrBuf);
+ (void)memset_s(buf, disk->sector_size, 0, disk->sector_size);
+ ret = los_disk_read(part->disk_id, buf, 0, 1);
+ if (ret < 0) {
+ free(buf);
return -EIO;
}
- part->sector_start = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]);
- part->sector_count = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_COUNT_OFFSET]);
+ part->sector_start = LD_DWORD_DISK(&buf[PAR_OFFSET + PAR_START_OFFSET]);
+ part->sector_count = LD_DWORD_DISK(&buf[PAR_OFFSET + PAR_COUNT_OFFSET]);
part->part_no_mbr = 1;
- part->filesystem_type = mbrBuf[PAR_OFFSET + PAR_TYPE_OFFSET];
+ part->filesystem_type = buf[PAR_OFFSET + PAR_TYPE_OFFSET];
- VolToPart[index].pt = part->part_no_mbr;
- VolToPart[index].ps = part->sector_start;
- VolToPart[index].pc = part->sector_count;
- free(mbrBuf);
+ free(buf);
}
-
- return ENOERR;
+ return 0;
}
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
-static INT FatFsVirPartMkFs(UINT flag, struct inode *mmcNode, int option, int index)
+int fatfs_mkfs (struct Vnode *device, int sectors, int option)
{
- INT virRet;
- struct inode_search_s desc;
- FAR struct inode *inode;
- if (flag != 0) {
- return VIRERR_NOTMOUNT;
- }
-
- SETUP_SEARCH(&desc, g_fatVirPart.virtualinfo.devpartpath, false);
- (void)inode_find(&desc);
- inode = desc.node;
-
- if (inode != mmcNode) {
- return VIRERR_NOPARAM;
- }
-
- inode_release(inode);
-
- (void)FatFsUnbindVirPart(f_getfatfs(index));
-
- if (option != FM_FAT32) {
- return VIRERR_NOTFIT;
- }
-
- virRet = FatFsMakeVirPart(f_getfatfs(index), index);
- if (virRet < VIRERR_BASE) {
- return FR_OK;
- }
-
- return virRet;
-}
-#endif
-
-#define INDEX_LABEL_LEN 15
-static INT FatFsSetLabel(int index)
-{
- INT result = FR_OK;
-
-#if FF_USE_LABEL
- char label[INDEX_LABEL_LEN] = {0};
- result = snprintf_s(label, sizeof(label), sizeof(label) - 1, "%d:%s", index, FatLabel);
- if (result < 0) {
- result = -EINVAL;
- }
-
- result = f_setlabel(label);
- if (result != FR_OK) {
- dprintf("Set sd card volume label failed !\n ");
- }
-
-#endif
-
- return result;
-}
-
-/*
- * return : 0 : OK; -ENODEV : "/dev/mmc0" driver not ready
- * sectors : 0~128 0:auto seclect; 1:512Byte; 2:1KB; 4 : 2KB; 128:64KB; if secotrs > 128,auto seclect;
- */
-int fatfs_mkfs(const char *dev, int sectors, int option)
-{
-#if FF_USE_MKFS && !FF_FS_READONLY
- INT result, index, err;
- FATFS fat = {0};
- UINT flag = 0;
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- INT virRet = 0;
-#endif
+ BYTE *work_buff = NULL;
los_part *part = NULL;
- char drive[DRIVER_NAME_LEN] = {0};
- char *work = NULL;
- struct inode *mmcNode = NULL;
- struct inode_search_s desc;
+ FRESULT result;
+ int ret;
- fat.win = NULL;
-
- /* if device not register in system,it may cause serious error,so return -ENODEV */
- SETUP_SEARCH(&desc, dev, false);
- (void)inode_find(&desc);
- mmcNode = desc.node;
-
- if (mmcNode == NULL)
- return -ENODEV; /* "mmc0" driver not ready */
-
- part = los_part_find(mmcNode);
- if (part == NULL || part->dev == NULL) {
- inode_release(mmcNode);
+ part = los_part_find(device);
+ if (part == NULL || device->data == NULL) {
return -ENODEV;
}
- index = FatGetDisk(mmcNode);
- /* if not mount, find an empty fatfs to mount */
- if (index == FAT_ERROR) {
- index = FatFsMountEmpty(part, drive, sizeof(drive), &fat);
- if (index < 0) {
- err = index;
- goto ERROUT;
- }
- DiskDev[index] = mmcNode;
- flag |= 1<<1;
- } else {
- if (f_checkopenlock(index) != FR_OK) { /* format is not allowed when a file or diretory is opened. */
- inode_release(mmcNode);
- return -EBUSY;
- }
- result = snprintf_s(drive, sizeof(drive), sizeof(drive) - 1, "%d:/", index);
- if (result < 0) {
- inode_release(mmcNode);
- return -EINVAL;
- }
-
- flag = 0;
- }
-
- option = FatFsErase(option, part);
- work = (char *)malloc(FF_MAX_SS);
- if (work == NULL) {
- err = -ENOMEM;
- goto ERROUT_WITH_MOUNT;
- }
- if (part->type == EMMC)
- option = (UINT)option | FM_SFD;
- result = f_mkfs(drive, option, sectors, work, FF_MAX_SS);
- free(work);
- if (result != FR_OK) {
- err = fatfs_2_vfs(result);
- goto ERROUT_WITH_MOUNT;
- }
-
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- FatfsVirtLock();
- virRet = FatFsVirPartMkFs(flag, mmcNode, option, index);
- FatfsVirtUnlock();
-#endif
-
- result = FatFsSetLabel(index);
-#ifdef LOSCFG_FS_FAT_CACHE
- if (result == FR_OK) {
- err = OsSdSync(part->disk_id);
- if (err < 0) {
- err = -EIO;
- goto ERROUT_WITH_MOUNT;
- }
- }
-#endif
-
- err = FatFsSetPartInfo(index, part);
-
-ERROUT_WITH_MOUNT:
- if (flag & (1 << 1)) {
- (void)f_mount(NULL, drive, 0); /* unmount the tmp fatfs */
- DiskDev[index] = (struct inode *)NULL;
- }
-
-ERROUT:
- inode_release(mmcNode);
- if (fat.win != NULL)
- free(fat.win);
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- if (err == 0)
- err = virRet;
-#endif
- return err;
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_chattr(struct inode *mountpt, const char *relpath, struct IATTR *fattr)
-{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- FRESULT result;
- FATFS *fat = NULL;
- INT vol, ret;
- char *filePath = NULL;
- unsigned char attr;
- mode_t mode = 0;
-
- if (mountpt == NULL || mountpt->i_private == NULL) {
+ if (sectors < 0 || sectors > FAT32_MAX_CLUSTER_SIZE || (sectors & (sectors - 1))) {
return -EINVAL;
}
- if (strlen(relpath) > MAX_LFNAME_LENTH - VOLUME_CHAR_LENGTH) {
- return -ENAMETOOLONG;
+ if (option != FMT_FAT && option != FMT_FAT32 && option != FMT_ANY && option != FMT_ERASE) {
+ return -EINVAL;
}
- if (mountpt->mountflags == MS_RDONLY) {
- return -EACCES;
+ if (part->part_name != NULL) { /* The part is mounted */
+ return -EBUSY;
}
-
- attr = mode & (AM_RDO | AM_HID | AM_SYS | AM_ARC);
-
- fat = (FATFS *)mountpt->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
-
- filePath = (char *)malloc(MAX_LFNAME_LENTH);
- if (filePath == NULL) {
+ option = fatfs_erase(part, option);
+ work_buff = (BYTE *)zalloc(FF_MAX_SS);
+ if (work_buff == NULL) {
return -ENOMEM;
}
- ret = snprintf_s(filePath, MAX_LFNAME_LENTH, MAX_LFNAME_LENTH - 1, "%d:%s", vol, relpath);
- if (ret < 0) {
- free(filePath);
- return -EINVAL;
- }
-
- result = f_chmod(filePath, attr, 0xff);
-
- free(filePath);
-
- if (result == FR_OK) {
- return FatfsSdSync(mountpt->mountflags, fat);
- }
-
- return fatfs_2_vfs(result);
-
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_getlabel(void *handle, char *label)
-{
-#if FF_USE_LABEL
- BYTE index;
- FATFS *fat = NULL;
- FRESULT result;
- los_part *part = NULL;
- char drive[DRIVER_NAME_LEN];
- DWORD *vsn = NULL;
- INT ret;
-
- if (label == NULL) {
- return -EFAULT;
- }
-
- fat = (FATFS *)handle;
- if (fat == NULL) {
- return -EINVAL;
- }
-
- index = (BYTE)fatfs_get_vol(fat);
- if (index >= FF_VOLUMES || (INT8)index < 0) {
- return -EINVAL;
- }
-
- part = los_part_find(DiskDev[index]);
- if (part == NULL) {
- return -ENODEV;
- }
-
- ret = snprintf_s(drive, sizeof(drive), sizeof(drive) - 1, "%d:/", index);
- if (ret < 0) {
- return -EINVAL;
- }
-
- result = f_getlabel(drive, label, vsn);
+ result = _mkfs(part, sectors, option, work_buff, FF_MAX_SS);
+ free(work_buff);
if (result != FR_OK) {
- return fatfs_2_vfs(result);
+ return -fatfs_2_vfs(result);
}
- return OK;
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_fallocate(FAR struct file *filep, int mode, off_t offset, off_t len)
-{
-#if FF_USE_EXPAND && !FF_FS_READONLY
- FIL *fp = (FIL *)(filep->f_priv);
- FRESULT res;
-
- FAT_CHECK(fp);
-
- if (len <= 0 || offset < 0) {
- return -EINVAL;
- }
-
- if (mode != FALLOC_FL_KEEP_SIZE) {
- return -EINVAL;
- }
-
- if (filep->f_inode->mountflags == MS_RDONLY) {
- return -EACCES;
- }
-
- res = f_expand(fp, (FSIZE_t)offset, (FSIZE_t)len, FALLOC_FL_KEEP_SIZE);
-
- if (res == FR_OK) {
- res = f_sync(fp);
- }
-
- return fatfs_2_vfs(res);
-#else
- return -ENOSYS;
-#endif
-}
-
-int fatfs_fallocate64(FAR struct file *filep, int mode, off64_t offset, off64_t len)
-{
-#if FF_USE_EXPAND && !FF_FS_READONLY
- FIL *fp = (FIL *)(filep->f_priv);
- FRESULT res;
-
- FAT_CHECK(fp);
-
- if (len >= FAT32_MAXSZIE || len <= 0 || offset >= FAT32_MAXSZIE || offset < 0) {
- return -EINVAL;
- }
-
- if (mode != FALLOC_FL_KEEP_SIZE) {
- return -EINVAL;
- }
-
- if (filep->f_inode->mountflags == MS_RDONLY) {
- return -EACCES;
- }
-
- res = f_expand(fp, (FSIZE_t)offset, (FSIZE_t)len, FALLOC_FL_KEEP_SIZE);
-
- if (res == FR_OK) {
- res = f_sync(fp);
- }
-
- return fatfs_2_vfs(res);
-#else
- return -ENOSYS;
-#endif
-}
-
-int los_set_systime_status(BOOL bStatus)
-{
- if (bStatus != FAT_SYSTEM_TIME_ENABLE && bStatus != FAT_SYSTEM_TIME_DISABLE) {
- return -EINVAL;
- }
-
- f_settimestatus(bStatus);
- return FR_OK;
-}
-
-int fatfs_truncate(FAR struct file *filep, off_t length)
-{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- FIL *fp = (FIL *)(filep->f_priv);
- FRESULT res = FR_OK;
- UINT count;
- DWORD n, fclust;
#ifdef LOSCFG_FS_FAT_CACHE
- FATFS *fat = NULL;
-#endif
-
- if (filep->f_inode->mountflags == MS_RDONLY) {
- return -EACCES;
- }
-
- FAT_CHECK(fp);
-
- if (length < 0) {
- return -EINVAL;
- }
-
- res = f_getclustinfo(fp, &fclust, &count);
- if (res != FR_OK) {
- return fatfs_2_vfs(res);
- }
-
- if (count == 0xFFFFFFFF) {
- return -EPERM;
- }
-
- n = (DWORD)(fp->obj.fs)->csize * SS(fp->obj.fs); /* Cluster size */
-
- if ((unsigned long)length > count * n) {
-#if FF_USE_EXPAND
- res = f_expand(fp, 0, (FSIZE_t)(length), FALLOC_FL_KEEP_SIZE);
-#else
- return -ENOSYS;
-#endif
- } else if ((unsigned long)length < n * count) {
- res = f_truncate(fp, (FSIZE_t)length);
- }
- fp->obj.objsize = length; /* Set file size to length */
- fp->flag |= 0x40; /* Set modified flag */
-
- if (res == FR_OK) {
- res = f_sync(fp);
- }
-#ifdef LOSCFG_FS_FAT_CACHE
- if (res == FR_OK) {
- fat = (FATFS *)filep->f_inode->i_private;
- FAT_CHECK(fat);
- return FatfsSdSync(filep->f_inode->mountflags, fat);
+ ret = OsSdSync(part->disk_id);
+ if (ret != 0) {
+ return -EIO;
}
#endif
- return fatfs_2_vfs(res);
-#else
- return -ENOSYS;
-#endif
+
+ ret = fatfs_set_part_info(part);
+ if (ret != 0) {
+ return -EIO;
+ }
+
+ return 0;
}
-int fatfs_truncate64(FAR struct file *filep, off64_t length)
+int fatfs_mkdir(struct Vnode *parent, const char *name, mode_t mode, struct Vnode **vpp)
{
-#if FF_FS_MINIMIZE == 0 && !FF_FS_READONLY
- FIL *fp = (FIL *)(filep->f_priv);
- FRESULT res = FR_OK;
- UINT count;
- DWORD n, fclust;
-#ifdef LOSCFG_FS_FAT_CACHE
- FATFS *fat = NULL;
-#endif
+ struct Vnode *vp = NULL;
+ FATFS *fs = (FATFS *)parent->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)parent->data;
+ FILINFO *finfo = &(dfp->fno);
+ DIR_FILE *dfp_new = NULL;
+ QWORD sect;
+ DWORD clust;
+ BYTE *dir = NULL;
+ DWORD hash;
+ FRESULT result = FR_OK;
+ int ret;
+ UINT n;
- FAT_CHECK(fp);
-
- if (filep->f_inode->mountflags == MS_RDONLY) {
- return -EACCES;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ result = FR_TIMEOUT;
+ goto ERROR_OUT;
}
-
- if (length >= FAT32_MAXSZIE || length < 0) {
- return -EINVAL;
+ if (finfo->fattrib & AM_ARC) {
+ result = FR_NO_DIR;
+ goto ERROR_UNLOCK;
}
+ DEF_NAMBUF;
+ INIT_NAMBUF(fs);
- res = f_getclustinfo(fp, &fclust, &count);
- if (res != FR_OK) {
- return fatfs_2_vfs(res);
+ dfp_new = (DIR_FILE *)zalloc(sizeof(DIR_FILE));
+ if (dfp_new == NULL) {
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_UNLOCK;
}
-
- if (count == 0xFFFFFFFF) {
- return -EPERM;
+ LOS_ListInit(&(dfp_new->fno.fp_list));
+ dfp_new->f_dir.obj.sclust = finfo->sclst;
+ dfp_new->f_dir.obj.fs = fs;
+ result = create_name(&(dfp_new->f_dir), &name);
+ if (result != FR_OK) {
+ goto ERROR_FREE;
}
-
- n = (DWORD)(fp->obj.fs)->csize * SS(fp->obj.fs); /* Cluster size */
-
- if (length > (off64_t)count * n) {
-#if FF_USE_EXPAND
- res = f_expand(fp, 0, (FSIZE_t)(length), FALLOC_FL_KEEP_SIZE);
+ result = dir_find(&(dfp_new->f_dir));
+ if (result == FR_OK) {
+ result = FR_EXIST;
+ goto ERROR_FREE;
+ }
+ /* Allocate new chain for directory */
+ clust = create_chain(&(dfp_new->f_dir.obj), 0);
+ if (clust == 0) {
+ result = FR_NO_SPACE_LEFT;
+ goto ERROR_FREE;
+ }
+ if (clust == 1 || clust == DISK_ERROR) {
+ result = FR_DISK_ERR;
+ goto ERROR_FREE;
+ }
+ result = sync_window(fs); /* Flush FAT */
+ if (result != FR_OK) {
+ goto ERROR_REMOVE_CHAIN;
+ }
+ /* Initialize the new directory */
+#ifndef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+ dir = fs->win;
#else
- return -ENOSYS;
+ dir = PARENTFS(fs)->win;
#endif
- } else if (length < (off64_t)count * n) {
- res = f_truncate(fp, (FSIZE_t)length);
- }
- fp->obj.objsize = length; /* Set file size to length */
- fp->flag |= 0x40; /* Set modified flag */
-
- if (res == FR_OK) {
- res = f_sync(fp);
- }
-#ifdef LOSCFG_FS_FAT_CACHE
- if (res == FR_OK) {
- fat = (FATFS *)filep->f_inode->i_private;
- FAT_CHECK(fat);
- return FatfsSdSync(filep->f_inode->mountflags, fat);
- }
-#endif
- return fatfs_2_vfs(res);
+ sect = clst2sect(fs, clust);
+ mem_set(dir, 0, SS(fs));
+ for (n = fs->csize; n > 0; n--) { /* Write zero to directory */
+#ifndef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+ fs->winsect = sect++;
+ fs->wflag = 1;
#else
- return -ENOSYS;
+ PARENTFS(fs)->winsect = sect++;
+ PARENTFS(fs)->wflag = 1;
+ result = sync_window(fs);
+ if (result != FR_OK) break;
#endif
+ }
+
+ if (result != FR_OK) {
+ goto ERROR_REMOVE_CHAIN;
+ }
+ result = dir_register(&(dfp_new->f_dir));
+ if (result != FR_OK) {
+ goto ERROR_REMOVE_CHAIN;
+ }
+ dir = dfp_new->f_dir.dir;
+ st_dword(dir + DIR_ModTime, 0); /* Set the time */
+ st_clust(fs, dir, clust); /* Set the start cluster */
+ dir[DIR_Attr] = AM_DIR; /* Set the attrib */
+ if ((mode & S_IWUSR) == 0) {
+ dir[DIR_Attr] |= AM_RDO;
+ }
+#ifndef LOSCFG_FS_FAT_VIRTUAL_PARTITION
+ fs->wflag = 1;
+#else
+ PARENTFS(fs)->wflag = 1;
+#endif
+ result = sync_fs(fs);
+ if (result != FR_OK) {
+ goto ERROR_REMOVE_CHAIN;
+ }
+
+ /* Set the FILINFO struct */
+ result = dir_read(&(dfp_new->f_dir), 0);
+ if (result != FR_OK) {
+ goto ERROR_REMOVE_CHAIN;
+ }
+ get_fileinfo(&(dfp_new->f_dir), &(dfp_new->fno));
+
+ ret = VnodeAlloc(&fatfs_vops, &vp);
+ if (ret != 0) {
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_REMOVE_CHAIN;
+ }
+ vp->parent = parent;
+ vp->fop = &fatfs_fops;
+ vp->data = dfp_new;
+ vp->originMount = parent->originMount;
+ vp->uid = fs->fs_uid;
+ vp->gid = fs->fs_gid;
+ vp->mode = fatfs_get_mode(dfp_new->fno.fattrib, fs->fs_mode);
+ vp->type = VNODE_TYPE_DIR;
+
+ hash = fatfs_hash(dfp_new->f_dir.sect, dfp_new->f_dir.dptr, dfp_new->fno.sclst);
+ ret = VfsHashInsert(vp, hash);
+ if (ret != 0) {
+ result = FR_NOT_ENOUGH_CORE;
+ goto ERROR_REMOVE_CHAIN;
+ }
+
+ unlock_fs(fs, FR_OK);
+ FREE_NAMBUF();
+ *vpp = vp;
+ return fatfs_sync(vp->originMount->mountFlags, fs);
+
+ERROR_REMOVE_CHAIN:
+ remove_chain(&(dfp_new->f_dir.obj), clust, 0);
+ERROR_FREE:
+ free(dfp_new);
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ERROR_OUT:
+ return -fatfs_2_vfs(result);
+}
+
+int fatfs_rmdir(struct Vnode *parent, struct Vnode *vp, char *name)
+{
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ FILINFO *finfo = &(dfp->fno);
+ DIR *dp = &(dfp->f_dir);
+ DIR dir_sub;
+ FRESULT result = FR_OK;
+ int ret;
+
+ if (finfo->fattrib & AM_ARC) {
+ result = FR_NO_DIR;
+ goto ERROR_OUT;
+ }
+
+ DEF_NAMBUF;
+ INIT_NAMBUF(fs);
+
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ result = FR_TIMEOUT;
+ goto ERROR_OUT;
+ }
+ dir_sub.obj.fs = fs;
+ dir_sub.obj.sclust = finfo->sclst;
+ result = dir_sdi(&dir_sub, 0);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ result = dir_read(&dir_sub, 0);
+ if (result == FR_OK) {
+ result = FR_NO_EMPTY_DIR;
+ goto ERROR_UNLOCK;
+ }
+ result = dir_remove(dp); /* remove directory entry */
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ /* Directory entry contains at least one cluster */
+ result = remove_chain(&(dp->obj), finfo->sclst, 0);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+
+ unlock_fs(fs, FR_OK);
+ FREE_NAMBUF();
+ return fatfs_sync(vp->originMount->mountFlags, fs);
+
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ FREE_NAMBUF();
+ERROR_OUT:
+ return -fatfs_2_vfs(result);
+}
+
+int fatfs_reclaim(struct Vnode *vp)
+{
+ free(vp->data);
+ vp->data = NULL;
+ return 0;
+}
+
+int fatfs_unlink(struct Vnode *parent, struct Vnode *vp, char *name)
+{
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE *dfp = (DIR_FILE *)vp->data;
+ FILINFO *finfo = &(dfp->fno);
+ DIR *dp = &(dfp->f_dir);
+ FRESULT result = FR_OK;
+ int ret;
+
+ if (finfo->fattrib & AM_DIR) {
+ result = FR_IS_DIR;
+ goto ERROR_OUT;
+ }
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ result = FR_TIMEOUT;
+ goto ERROR_OUT;
+ }
+ result = dir_remove(dp); /* remove directory entry */
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ if (finfo->sclst != 0) { /* if cluster chain exists */
+ result = remove_chain(&(dp->obj), finfo->sclst, 0);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ }
+ result = sync_fs(fs);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ unlock_fs(fs, FR_OK);
+ return fatfs_sync(vp->originMount->mountFlags, fs);
+
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ERROR_OUT:
+ return -fatfs_2_vfs(result);
+}
+
+int fatfs_ioctl(struct file *filep, int req, unsigned long arg)
+{
+ return -ENOSYS;
}
-#define DATE_OFFSET 16
#define CHECK_FILE_NUM 3
-static INT FatFsTimeMin(DIR_FILE dirFile[])
+static inline DWORD combine_time(FILINFO *finfo)
{
- INT min = 0;
- DWORD timeMin = 0;
-
- MIN((dirFile[0].fno.fdate << DATE_OFFSET | dirFile[0].fno.ftime),
- (dirFile[1].fno.fdate << DATE_OFFSET | dirFile[1].fno.ftime), timeMin);
- MIN((DWORD)(dirFile[2].fno.fdate << DATE_OFFSET | dirFile[2].fno.ftime), timeMin, timeMin);
- if (timeMin == (dirFile[0].fno.fdate << DATE_OFFSET | dirFile[0].fno.ftime)) {
- min = 0;
- } else if (timeMin == (dirFile[1].fno.fdate << DATE_OFFSET | dirFile[1].fno.ftime)) {
- min = 1;
- } else if (timeMin == (dirFile[2].fno.fdate << DATE_OFFSET | dirFile[2].fno.ftime)) {
- min = 2; /* check the latest three files */
- }
-
- return min;
+ return (finfo->fdate << FTIME_DATE_OFFSET) | finfo->ftime;
}
-int fatfs_fscheck(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir)
+static UINT get_oldest_time(DIR_FILE df[], DWORD *oldest_time, UINT len)
{
- DIR *fdir = NULL;
- FILINFO fno;
- FRESULT result;
- INT count = 0;
- INT timeOldest = 0;
- DIR dirBackup = {0};
- DIR_FILE dirFile[CHECK_FILE_NUM] = {0};
- INT loop = 0;
-#ifdef LOSCFG_FS_FAT_CACHE
- FATFS *fat = NULL;
- los_part *part = NULL;
- INT vol;
-#endif
- INT ret;
+ int i;
+ DWORD old_time = combine_time(&(df[0].fno));
+ DWORD time;
+ UINT index = 0;
+ for (i = 1; i < len; i++) {
+ time = combine_time(&(df[i].fno));
+ if (time < old_time) {
+ old_time = time;
+ index = i;
+ }
+ }
+ *oldest_time = old_time;
+ return index;
+}
- if (mountpt->mountflags == MS_RDONLY) {
- return -EACCES;
+int fatfs_fscheck(struct Vnode* vp, struct fs_dirent_s *dir)
+{
+ FATFS *fs = (FATFS *)vp->originMount->data;
+ DIR_FILE df[CHECK_FILE_NUM] = {0};
+ DIR *dp = NULL;
+ FILINFO *finfo = &(((DIR_FILE *)(vp->data))->fno);
+ FILINFO fno;
+ DWORD old_time = -1;
+ DWORD time;
+ UINT count;
+ UINT index = 0;
+ los_part *part = NULL;
+ FRESULT result;
+ int ret;
+
+ if (fs->fs_type != FS_FAT32) {
+ return -EINVAL;
}
- FAT_CHECK(dir);
+ if ((finfo->fattrib & AM_DIR) == 0) {
+ return -ENOTDIR;
+ }
- ret = fatfs_opendir(mountpt, relpath, dir);
- if (ret != FR_OK) {
+ ret = fatfs_opendir(vp, dir);
+ if (ret < 0) {
return ret;
}
- fdir = (DIR *)(dir->u.fs_dir);
- if ((fdir->obj.fs)->fs_type != FS_FAT32) {
- (void)fatfs_closedir(mountpt, dir);
- return -EINVAL;
+ ret = lock_fs(fs);
+ if (ret == FALSE) {
+ result = FR_TIMEOUT;
+ goto ERROR_WITH_DIR;
}
- do {
- (void)memcpy_s(&dirBackup, sizeof(DIR), fdir, sizeof(DIR));
- result = f_readdir(fdir, &fno);
- if (result != FR_OK) {
- break;
- }
-
- if ((fno.fname[0] == 0 || fno.fname[0] == (TCHAR)0xFF)) {
- break;
- }
-
- if (fno.fattrib == AM_DIR) {
- continue;
- }
-
- if (count == 0) {
- (void)memcpy_s(&dirFile[0].f_dir, sizeof(DIR), &dirBackup, sizeof(DIR));
- (void)memcpy_s(&dirFile[0].fno, sizeof(FILINFO), &fno, sizeof(FILINFO));
- } else if (count == 1) {
- (void)memcpy_s(&dirFile[1].f_dir, sizeof(DIR), &dirBackup, sizeof(DIR));
- (void)memcpy_s(&dirFile[1].fno, sizeof(FILINFO), &fno, sizeof(FILINFO));
- } else if (count == 2) { /* check the latest three files */
- (void)memcpy_s(&dirFile[2].f_dir, sizeof(DIR), &dirBackup, sizeof(DIR));
- (void)memcpy_s(&dirFile[2].fno, sizeof(FILINFO), &fno, sizeof(FILINFO));
- timeOldest = FatFsTimeMin(dirFile);
+ dp = (DIR *)dir->u.fs_dir;
+ dp->obj.id = fs->id;
+ for (count = 0; count < CHECK_FILE_NUM; count++) {
+ if ((result = f_readdir(dp, &fno)) != FR_OK) {
+ goto ERROR_UNLOCK;
} else {
- if ((fno.fdate << DATE_OFFSET | fno.ftime) >
- (dirFile[timeOldest].fno.fdate << DATE_OFFSET | dirFile[timeOldest].fno.ftime)) {
- (void)memcpy_s(&dirFile[timeOldest].f_dir, sizeof(DIR), &dirBackup, sizeof(DIR));
- (void)memcpy_s(&dirFile[timeOldest].fno, sizeof(FILINFO), &fno, sizeof(FILINFO));
- timeOldest = FatFsTimeMin(dirFile);
+ if (fno.fname[0] == 0 || fno.fname[0] == (TCHAR)0xFF) {
+ break;
+ }
+ (void)memcpy_s(&df[count].f_dir, sizeof(DIR), dp, sizeof(DIR));
+ (void)memcpy_s(&df[count].fno, sizeof(FILINFO), &fno, sizeof(FILINFO));
+ time = combine_time(&(df[count].fno));
+ if (time < old_time) {
+ old_time = time;
+ index = count;
}
}
- count++;
- } while (result == FR_OK);
- if (count >= CHECK_FILE_NUM) {
- loop = CHECK_FILE_NUM;
- } else {
- loop = count;
+ }
+ while ((result = f_readdir(dp, &fno)) == FR_OK) {
+ if (fno.fname[0] == 0 || fno.fname[0] == (TCHAR)0xFF) {
+ break;
+ }
+ time = combine_time(&fno);
+ if (time < old_time) {
+ (void)memcpy_s(&df[index].f_dir, sizeof(DIR), dp, sizeof(DIR));
+ (void)memcpy_s(&df[index].fno, sizeof(FILINFO), &fno, sizeof(FILINFO));
+ index = get_oldest_time(df, &old_time, CHECK_FILE_NUM);
+ }
+ }
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
}
- ret = fatfs_closedir(mountpt, dir);
- if (ret != FR_OK) {
+ for (index = 0; index < count; index++) {
+ result = f_fcheckfat(&df[index]);
+ if (result != FR_OK) {
+ goto ERROR_UNLOCK;
+ }
+ }
+
+ unlock_fs(fs, FR_OK);
+
+ ret = fatfs_closedir(vp, dir);
+ if (ret < 0) {
return ret;
}
- for (count = 0; count < loop; count++) {
- result = f_fcheckfat(&dirFile[count]);
- if (result != FR_OK) {
- return fatfs_2_vfs(result);
- }
- }
#ifdef LOSCFG_FS_FAT_CACHE
- fat = (FATFS *)mountpt->i_private;
- vol = fatfs_get_vol(fat);
- if (vol < 0 || vol > FF_VOLUMES) {
- return -ENOENT;
- }
- part = get_part((INT)fat->pdrv);
+ part = get_part((INT)fs->pdrv);
if (part != NULL) {
(void)OsSdSync(part->disk_id);
}
#endif
- return ENOERR;
-}
-
-int fatfs_virstatfs(struct inode *mountpt, const char *relpath, struct statfs *buf)
-{
-#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- return fatfs_virstatfs_internel(mountpt, relpath, buf);
-#else
return 0;
-#endif
+
+ERROR_UNLOCK:
+ unlock_fs(fs, result);
+ERROR_WITH_DIR:
+ fatfs_closedir(vp, dir);
+ return -fatfs_2_vfs(result);
}
-const struct mountpt_operations fat_operations = {
- fatfs_open, /* open */
- fatfs_close, /* close */
- fatfs_read, /* read */
- fatfs_write, /* write */
- fatfs_seek, /* seek */
- fatfs_ioctl, /* ioctl */
- OsVfsFileMmap, /* mmap */
- fatfs_sync, /* sync */
- fatfs_dup, /* dup */
- NULL, /* fstat */
- fatfs_truncate, /* truncate */
-
- fatfs_opendir, /* opendir */
- fatfs_closedir, /* closedir */
- fatfs_readdir, /* readdir */
- fatfs_rewinddir, /* rewinddir */
-
- fatfs_bind, /* bind */
- fatfs_unbind, /* unbind */
- fatfs_statfs, /* statfs */
- fatfs_virstatfs, /* virstatfs */
- fatfs_unlink, /* unlinke */
- fatfs_mkdir, /* mkdir */
- fatfs_rmdir, /* rmdir */
- fatfs_rename, /* rename */
- fatfs_stat, /* stat */
- fatfs_utime, /* utime */
- fatfs_chattr, /* chattr */
- fatfs_seek64, /* seek64 */
- fatfs_getlabel, /* getlabel */
- fatfs_fallocate, /* fallocate */
- fatfs_fallocate64, /* fallocate64 */
- fatfs_truncate64, /* truncate64 */
- fatfs_fscheck, /* fscheck */
- NULL, /* map_pages */
- NULL, /* readpage */
- NULL, /* writepage */
+struct VnodeOps fatfs_vops = {
+ /* file ops */
+ .Getattr = fatfs_stat,
+ .Chattr = fatfs_chattr,
+ .Lookup = fatfs_lookup,
+ .Rename = fatfs_rename,
+ .Create = fatfs_create,
+ .Unlink = fatfs_unlink,
+ .Reclaim = fatfs_reclaim,
+ .Truncate = fatfs_truncate,
+ .Truncate64 = fatfs_truncate64,
+ /* dir ops */
+ .Opendir = fatfs_opendir,
+ .Readdir = fatfs_readdir,
+ .Rewinddir = fatfs_rewinddir,
+ .Closedir = fatfs_closedir,
+ .Mkdir = fatfs_mkdir,
+ .Rmdir = fatfs_rmdir,
+ .Fscheck = fatfs_fscheck,
};
-FSMAP_ENTRY(fat_fsmap, "vfat", fat_operations, FALSE, TRUE);
+struct MountOps fatfs_mops = {
+ .Mount = fatfs_mount,
+ .Unmount = fatfs_umount,
+ .Statfs = fatfs_statfs,
+};
+
+struct file_operations_vfs fatfs_fops = {
+ .open = fatfs_open,
+ .read = fatfs_read,
+ .write = fatfs_write,
+ .seek = fatfs_lseek,
+ .close = fatfs_close,
+ .mmap = OsVfsFileMmap,
+ .fallocate = fatfs_fallocate,
+ .fallocate64 = fatfs_fallocate64,
+ .fsync = fatfs_fsync,
+ .ioctl = fatfs_ioctl,
+};
+
+FSMAP_ENTRY(fat_fsmap, "vfat", fatfs_mops, FALSE, TRUE);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
-
#endif /* LOSCFG_FS_FAT */
diff --git a/fs/fat/os_adapt/fatfs.h b/fs/fat/os_adapt/fatfs.h
index cae3ec67..5610a3bd 100755
--- a/fs/fat/os_adapt/fatfs.h
+++ b/fs/fat/os_adapt/fatfs.h
@@ -32,6 +32,7 @@
#ifndef _FATFS_H
#define _FATFS_H
+#include "ff.h"
#include "fs/fs.h"
#include "disk.h"
#include "unistd.h"
@@ -42,54 +43,100 @@
#include "sys/stat.h"
#include "sys/statfs.h"
-#include "inode/inode.h"
-#include "fs/dirent_fs.h"
-#include "fcntl.h"
-
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
-#define MAX_LFNAME_LENTH 256
-#define LABEL_LEN 12
-#define FAT32_MAXSZIE 0x100000000
-#define FAT_ERROR (-1)
-extern char FatLabel[LABEL_LEN];
+#define MAX_LFNAME_LENTH 256
+#define LABEL_LEN 12
+#define FAT_RESERVED_NUM 2
+#define FAT32_MAXSIZE 0x100000000
+#define BAD_CLUSTER 0x7FFFFFFF
+#define DISK_ERROR 0xFFFFFFFF
+#define END_OF_FILE 0x0FFFFFFF
+#define FAT_ERROR (-1)
-#define VOLUME_CHAR_LENGTH 4
-#define FAT_CHECK(ptr) \
- do { \
- if ((ptr) == NULL) \
- return -EINVAL; \
- } while (0)
+/* MBR */
+#define MBR_PRIMARY_PART_NUM 4
+#define JUMP_CODE "\xEB\xFE\x90"
-int fatfs_bind (struct inode *blkdriver, const void *data, void **handle, const char *realpath);
-int fatfs_unbind (void *handle, struct inode **blkdriver);
-int fatfs_mkfs (const char *dev, int sectors, int option);
-int fatfs_statfs (struct inode *mountpt, struct statfs *buf);
-int fatfs_open (struct file *filep, const char *relpath, int oflags, mode_t mode);
-int fatfs_close (struct file *filep);
-int fatfs_ioctl (FAR struct file *filep, int cmd, unsigned long arg);
-ssize_t fatfs_read (struct file *filep, char *buffer, size_t buflen);
-ssize_t fatfs_write (struct file *filep, const char *buffer, size_t buflen);
-int fatfs_sync (struct file *filep);
-int fatfs_virstatfs_internel (struct inode *mountpt, const char *relpath, struct statfs *buf);
-int fatfs_dup (FAR const struct file *oldp, FAR struct file *newp);
-off_t fatfs_seek (struct file *filep, off_t offset, int whence);
-int fatfs_unlink (struct inode *mountpt, const char *relpath);
-int fatfs_rename (struct inode *mountpt, const char *oldpath, const char *newpath);
-int fatfs_stat (struct inode *mountpt, const char *path, struct stat *st);
-int fatfs_opendir (struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir);
-int fatfs_closedir (struct inode *mountpt, struct fs_dirent_s *dir);
-int fatfs_readdir (struct inode *mountpt, struct fs_dirent_s *dir);
-int fatfs_rewinddir (struct inode *mountpt, struct fs_dirent_s *dir);
-int fatfs_mkdir (struct inode *mountpt, const char *relpath, mode_t mode);
-int fatfs_rmdir (struct inode *mountpt, const char *relpath);
-int fatfs_utime (struct inode *mountpt, const char *pathname, const struct tm *times);
-int fatfs_getlabel (void *handle, char *label);
-int fatfs_2_vfs (int result);
+/* Partiton type */
+#define FAT12 0x01 /* FAT12 as primary partition in first physical 32MB */
+#define FAT16 0x04 /* FAT16 with less than 65536 sectors(32MB) */
+#define EXTENDED_PARTITION_CHS 0x05
+#define FAT16B 0x06 /* FAT16B with 65536 or more sectors */
+#define FAT32_CHS 0x0B
+#define FAT32_LBA 0x0C
+#define EXTENDED_PARTITION_LBA 0x0F
+#define GPT_PROTECTIVE_MBR 0xEE
+
+/* volume boot record type */
+#define VBR_FAT 0
+#define VBR_BS_NOT_FAT 2
+#define VBR_NOT_BS 3
+#define VBR_DISK_ERR 4
+
+/* Limit and boundary */
+#define FAT_MAX_CLUSTER_SIZE 64 /* (sectors) */
+#define FAT32_MAX_CLUSTER_SIZE 128 /* (sectors) */
+#define FAT32_ENTRY_SIZE 4 /* (bytes) */
+#define FAT16_ENTRY_SIZE 2 /* (bytes) */
+#define VOL_MIN_SIZE 128 /* (sectors) */
+#define SFD_START_SECTOR 63
+#define MAX_BLOCK_SIZE 32768 /* (sectors) */
+
+/* Sector */
+#define FAT32_RESERVED_SECTOR 32
+#define FAT_RESERVED_SECTOR 1
+
+#define DIR_NAME_LEN 11
+#define DIR_READ_COUNT 7
+
+#define VOLUME_CHAR_LENGTH 4
+
+#define FAT_DEBUG
+#ifdef FAT_DEBUG
+#define FDEBUG(format, ...) do { \
+ PRINTK("[%s:%d]"format"\n", __func__, __LINE__, ##__VA_ARGS__); \
+} while (0)
+#else
+#define FDEBUG(...)
+#endif
+
+int fatfs_2_vfs(int result);
+int fatfs_lookup(struct Vnode *parent, const char *name, int len, struct Vnode **vpp);
+int fatfs_create(struct Vnode *parent, const char *name, int mode, struct Vnode **vpp);
+int fatfs_read(struct file *filep, char *buff, size_t count);
+off_t fatfs_lseek64(struct file *filep, off64_t offset, int whence);
+off64_t fatfs_lseek(struct file *filep, off_t offset, int whence);
+int fatfs_write(struct file *filep, const char *buff, size_t count);
+int fatfs_fsync(struct file *filep);
+int fatfs_fallocate64(struct file *filep, int mode, off64_t offset, off64_t len);
+int fatfs_fallocate(struct file *filep, int mode, off_t offset, off_t len);
+int fatfs_truncate64(struct Vnode *vnode, off64_t len);
+int fatfs_truncate(struct Vnode *vnode, off_t len);
+int fatfs_mount(struct Mount *mount, struct Vnode *device, const void *data);
+int fatfs_umount(struct Mount *mount, struct Vnode **device);
+int fatfs_statfs(struct Mount *mount, struct statfs *info);
+int fatfs_stat(struct Vnode *vnode, struct stat *buff);
+int fatfs_chattr(struct Vnode *vnode, struct IATTR *attr);
+int fatfs_opendir(struct Vnode *vnode, struct fs_dirent_s *idir);
+int fatfs_readdir(struct Vnode *vnode, struct fs_dirent_s *idir);
+int fatfs_rewinddir(struct Vnode *vnode, struct fs_dirent_s *dir);
+int fatfs_closedir(struct Vnode *vnode, struct fs_dirent_s *dir);
+int fatfs_rename(struct Vnode *oldvnode, struct Vnode *newparent, const char *oldname, const char *newname);
+int fatfs_mkfs (struct Vnode *device, int sectors, int option);
+int fatfs_mkdir(struct Vnode *parent, const char *name, mode_t mode, struct Vnode **vpp);
+int fatfs_rmdir(struct Vnode *parent, struct Vnode *vp, char *name);
+int fatfs_unlink(struct Vnode *parent, struct Vnode *vp, char *name);
+int fatfs_ioctl(struct file *filep, int req, unsigned long arg);
+int fatfs_fscheck(struct Vnode* vnode, struct fs_dirent_s *dir);
+
+FRESULT find_fat_partition(FATFS *fs, los_part *part, BYTE *format, QWORD *start_sector);
+FRESULT init_fatobj(FATFS *fs, BYTE fmt, QWORD start_sector);
+FRESULT _mkfs(los_part *partition, int sector, int opt, BYTE *work, UINT len);
#ifdef __cplusplus
#if __cplusplus
diff --git a/fs/fat/os_adapt/format.c b/fs/fat/os_adapt/format.c
index 6ffbfb6a..72a1a6f0 100755
--- a/fs/fat/os_adapt/format.c
+++ b/fs/fat/os_adapt/format.c
@@ -38,62 +38,77 @@
#include "integer.h"
#ifdef LOSCFG_FS_FAT
-#define DEV_NAME_SIZE 4
+char FatLabel[LABEL_LEN];
+#define DEV_NAME_SIZE 4
+
int format(const char *dev, int sectors, int option)
{
- INT err;
- if (dev == NULL) {
- set_errno(EINVAL);
- return -1;
- }
+ struct Vnode *device = NULL;
+ INT err;
+ if (dev == NULL) {
+ set_errno(EINVAL);
+ return -1;
+ }
- if (strncmp(dev, "/dev", DEV_NAME_SIZE) != 0) {
- PRINTK("Usage :\n");
- PRINTK(" format \n");
- PRINTK(" dev_inodename : the name of dev\n");
- PRINTK(" sectors : Size of allocation unit in unit of byte or sector, ");
- PRINTK("0 instead of default size\n");
- PRINTK(" options : Index of filesystem. 1 for FAT filesystem, 2 for FAT32 filesystem, ");
- PRINTK("7 for any, 8 for erase\n");
- PRINTK(" label : The volume of device. It will be emptyed when this parameter is null\n");
- PRINTK("Example:\n");
- PRINTK(" format /dev/mmcblk0 128 2\n");
+ if (strncmp(dev, "/dev", DEV_NAME_SIZE) != 0) {
+ PRINTK("Usage :\n");
+ PRINTK(" format \n");
+ PRINTK(" dev_vnodename : the name of dev\n");
+ PRINTK(" sectors : Size of allocation unit in unit of byte or sector, ");
+ PRINTK("0 instead of default size\n");
+ PRINTK(" options : Index of filesystem. 1 for FAT filesystem, 2 for FAT32 filesystem, ");
+ PRINTK("7 for any, 8 for erase\n");
+ PRINTK(" label : The volume of device. It will be emptyed when this parameter is null\n");
+ PRINTK("Example:\n");
+ PRINTK(" format /dev/mmcblk0 128 2\n");
- set_errno(EINVAL);
- return -1;
- }
- err = fatfs_mkfs(dev, sectors, option);
- if (err < 0) {
- set_errno(-err);
- return -1;
- }
+ set_errno(EINVAL);
+ return -1;
+ }
+ VnodeHold();
+ err = VnodeLookup(dev, &device, 0);
+ if (err == -ENOENT || err == -ENOSYS) {
+ VnodeDrop();
+ set_errno(ENODEV);
+ return -1;
+ } else if (err < 0) {
+ VnodeDrop();
+ set_errno(-err);
+ return -1;
+ }
+ err = fatfs_mkfs(device, sectors, option);
+ if (err < 0) {
+ set_errno(-err);
+ return -1;
+ }
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
- else if (err >= VIRERR_BASE) {
- set_errno(err);
- }
+ else if (err >= VIRERR_BASE) {
+ set_errno(err);
+ }
#endif
- return 0;
+ VnodeDrop();
+ return 0;
}
void set_label(const char *name)
{
- INT len;
- INT err;
+ INT len;
+ INT err;
- (void)memset_s(FatLabel, LABEL_LEN, 0, LABEL_LEN);
+ (void)memset_s(FatLabel, LABEL_LEN, 0, LABEL_LEN);
- if (name == NULL || *name == '\0') {
- return;
- }
+ if (name == NULL || *name == '\0') {
+ return;
+ }
- len = strlen(name);
- if (len >= LABEL_LEN) {
- len = LABEL_LEN - 1;
- }
+ len = strlen(name);
+ if (len >= LABEL_LEN) {
+ len = LABEL_LEN - 1;
+ }
- err = strncpy_s(FatLabel, LABEL_LEN, name, len);
- if (err != EOK) {
- PRINT_ERR("Fat set_label error");
- }
+ err = strncpy_s(FatLabel, LABEL_LEN, name, len);
+ if (err != EOK) {
+ PRINT_ERR("Fat set_label error");
+ }
}
-#endif /* #ifdef CONFIG_FS_FAT */
+#endif /* #ifdef CONFIG_FS_FAT */
diff --git a/fs/fat/virpart/src/virpart.c b/fs/fat/virpart/src/virpart.c
old mode 100644
new mode 100755
index dd5700c4..2b712172
--- a/fs/fat/virpart/src/virpart.c
+++ b/fs/fat/virpart/src/virpart.c
@@ -32,7 +32,6 @@
#include "virpart.h"
#include "errno.h"
#include "fatfs.h"
-#include "dirop_fat.h"
#include "errcode_fat.h"
#include "disk.h"
@@ -442,15 +441,17 @@ INT FatFsMakeVirPart(void *handle, BYTE vol)
return fatfs_2_vfs(ret);
}
-INT fatfs_virstatfs_internel(struct inode *mountpt, const char *relpath, struct statfs *buf)
+INT fatfs_virstatfs_internel(struct Vnode *mountpt, const char *relpath, struct statfs *buf)
{
char drive[MAX_LFNAME_LENTH];
DWORD freClust, allClust;
FATFS *fat = NULL;
INT result, vol;
- fat = (FATFS *)mountpt->i_private;
- FAT_CHECK(fat);
+ fat = (FATFS *)(mountpt->originMount->data);
+ if (fat == NULL) {
+ return -EINVAL;
+ }
if (fat->vir_flag != FS_PARENT) {
return -EINVAL;
@@ -500,4 +501,4 @@ EXIT:
return result;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/fs/fat/virpart/src/virpartff.c b/fs/fat/virpart/src/virpartff.c
old mode 100644
new mode 100755
index f20b6ed9..f6ac5bfd
--- a/fs/fat/virpart/src/virpartff.c
+++ b/fs/fat/virpart/src/virpartff.c
@@ -36,39 +36,6 @@
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
-#if FF_USE_LFN == 0 /* Non-LFN configuration */
-#define DEF_NAMBUF
-#define INIT_NAMBUF(fs)
-#define FREE_NAMBUF()
-
-#else /* LFN configuration */
-#if (FF_MAX_LFN < 12) || (FF_MAX_LFN > 255)
-#error Wrong _MAX_LFN value
-#endif
-
-#if FF_USE_LFN == 1 /* LFN enabled with static working buffer */
-static WCHAR g_lfnBuf[FF_MAX_LFN + 1]; /* LFN enabled with static working buffer */
-#define DEF_NAMBUF
-#define INIT_NAMBUF(fs)
-#define FREE_NAMBUF()
-
-#elif FF_USE_LFN == 2 /* LFN enabled with dynamic working buffer on the stack */
-#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN + 1];
-#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; }
-#define FREE_NAMBUF()
-
-#elif FF_USE_LFN == 3 /* LFN enabled with dynamic working buffer on the heap */
-#define DEF_NAMBUF WCHAR *lfn;
-#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN + 1) * 2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; }
-#define FREE_NAMBUF() ff_memfree(lfn)
-
-#else
-#error Wrong FF_USE_LFN setting
-
-#endif
-#endif /* else FF_USE_LFN == 0 */
-
-
#if FF_FS_REENTRANT
#if FF_USE_LFN == 1
#error Static LFN work area cannot be used at thread-safe configuration
diff --git a/fs/include/disk.h b/fs/include/disk.h
old mode 100755
new mode 100644
index 77737dc3..6e6c9321
--- a/fs/include/disk.h
+++ b/fs/include/disk.h
@@ -41,10 +41,6 @@
#ifdef LOSCFG_FS_FAT_CACHE
#include "bcache.h"
-#else
-
-#include "inode/inode.h"
-
#endif
#include "pthread.h"
@@ -178,7 +174,7 @@ typedef struct _los_disk_ {
UINT32 disk_status : 2; /* status of disk */
UINT32 part_count : 8; /* current partition count */
UINT32 reserved : 14;
- struct inode *dev; /* device */
+ struct Vnode *dev; /* device */
#ifdef LOSCFG_FS_FAT_CACHE
OsBcache *bcache; /* cache of the disk, shared in all partitions */
#endif
@@ -199,7 +195,7 @@ typedef struct _los_part_ {
UINT32 reserved : 3;
UINT8 filesystem_type; /* filesystem used in the partition */
UINT8 type;
- struct inode *dev; /* dev devices used in the partition */
+ struct Vnode *dev; /* dev devices used in the partition */
CHAR *part_name;
UINT64 sector_start; /*
* offset of a partition to the primary devices
@@ -249,7 +245,7 @@ struct disk_divide_info {
*
* @param diskName [IN] Type #const CHAR * disk driver name.
* @param bops [IN] Type #const struct block_operations * block driver control sturcture.
- * @param priv [IN] Type #VOID * private data of inode.
+ * @param priv [IN] Type #VOID * private data of vnode.
* @param diskID [IN] Type #INT32 disk id number, less than SYS_MAX_DISK.
* @param info [IN] Type #VOID * disk driver partition information.
*
@@ -537,14 +533,14 @@ INT32 los_part_access(const CHAR *dev, mode_t mode);
* @brief Find disk partition.
*
* @par Description:
- * By driver partition inode to find disk partition.
+ * By driver partition vnode to find disk partition.
*
* @attention
*
*
- * @param blkDriver [IN] Type #struct inode * partition driver inode.
+ * @param blkDriver [IN] Type #struct Vnode * partition driver vnode.
*
* @retval #NULL Can't find chosen disk partition.
* @retval #los_part * This is partition structure pointer of chosen disk partition.
@@ -554,7 +550,7 @@ INT32 los_part_access(const CHAR *dev, mode_t mode);
* @see None
*
*/
-los_part *los_part_find(struct inode *blkDriver);
+los_part *los_part_find(struct Vnode *blkDriver);
/**
* @ingroup disk
diff --git a/fs/include/fs/fs_operation.h b/fs/include/fs/fs_operation.h
old mode 100755
new mode 100644
index e85cf5b4..23898d88
--- a/fs/include/fs/fs_operation.h
+++ b/fs/include/fs/fs_operation.h
@@ -82,18 +82,7 @@ extern struct page_mapping *find_mapping(const char *path);
*
****************************************************************************/
-extern int remove_mapping(const char *fullpath, const struct file *ex_filp);
-
-/****************************************************************************
- * Name: remove_mapping_nolock
- *
- * Description:
- * This function is similar with the function "remove_mapping" above,
- * except that this function do not protect global file list.
- *
- ****************************************************************************/
-
-extern int remove_mapping_nolock(const char *fullpath, const struct file *ex_filp);
+extern int remove_mapping(const char *fullpath);
/****************************************************************************
* Name: rename_mapping
@@ -113,7 +102,18 @@ extern void rename_mapping(const char *src, const char *dst);
*
****************************************************************************/
-extern void dec_mapping(struct page_mapping *mapping);
+extern void dec_mapping_nolock(struct page_mapping *mapping);
+
+
+/****************************************************************************
+ * Name: update_file_path
+ *
+ * Description:
+ * Update the path in file descriptors when do renaming.
+ *
+ ****************************************************************************/
+
+extern int update_file_path(char *old_path, char *new_path);
/**
* @ingroup fs
@@ -317,7 +317,7 @@ extern int los_set_systime_status(BOOL b_status);
*
*/
-FAR int fscheck(FAR const char *path);
+int fscheck(const char *path);
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
/**
@@ -347,7 +347,7 @@ FAR int fscheck(FAR const char *path);
*
*/
-extern int virstatfs(FAR const char *path, FAR struct statfs *buf);
+extern int virstatfs(const char *path, struct statfs *buf);
/**
* @ingroup fs
@@ -379,8 +379,9 @@ extern int virstatfs(FAR const char *path, FAR struct statfs *buf);
* @see
*
*/
-
+#ifdef VFS_IMPL_LATER
int los_set_virpartparam(virpartinfo virtualinfo);
+#endif
#endif
@@ -416,6 +417,7 @@ int los_set_virpartparam(virpartinfo virtualinfo);
* @see None
*/
+struct IATTR;
extern int chattr(const char *pathname, struct IATTR *attr);
@@ -545,4 +547,4 @@ extern INT32 LOS_SetSyncThreadPrio(UINT32 prio, const CHAR *name);
}
#endif /* __cplusplus */
#endif /* __cplusplus */
-#endif
\ No newline at end of file
+#endif
diff --git a/fs/include/fs/mount.h b/fs/include/fs/mount.h
new file mode 100644
index 00000000..c2a3a46d
--- /dev/null
+++ b/fs/include/fs/mount.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MOUNT_H_
+#define _MOUNT_H_
+
+#include "los_mux.h"
+#include "fs/vfs_util.h"
+#include "fs/vnode.h"
+#include
+
+struct MountOps;
+
+struct Mount {
+ LIST_ENTRY mountList; /* mount list */
+ const struct MountOps *ops; /* operations of mount */
+ struct Vnode *vnodeBeCovered; /* vnode we mounted on */
+ struct Vnode *vnodeCovered; /* syncer vnode */
+ LIST_HEAD vnodeList; /* list of vnodes */
+ int vnodeSize; /* size of vnode list */
+ LIST_HEAD activeVnodeList; /* list of active vnodes */
+ int activeVnodeSize; /* szie of active vnodes list */
+ void *data; /* private data */
+ uint32_t hashseed; /* Random seed for vfshash */
+ unsigned long mountFlags; /* Flags for mount */
+};
+
+struct MountOps {
+ int (*Mount)(struct Mount *mount, struct Vnode *vnode, const void *data);
+ int (*Unmount)(struct Mount *mount, struct Vnode **blkdriver);
+ int (*Statfs)(struct Mount *mount, struct statfs *sbp);
+};
+
+struct Mount* MountAlloc(struct Vnode* vnode, struct MountOps* mop);
+LIST_HEAD* GetMountList(void);
+#endif
diff --git a/fs/include/fs/path_cache.h b/fs/include/fs/path_cache.h
new file mode 100644
index 00000000..43bce86c
--- /dev/null
+++ b/fs/include/fs/path_cache.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PATH_CACHE_H
+#define _PATH_CACHE_H
+
+#include "los_list.h"
+#include "fs/mount.h"
+#include "fs/vnode.h"
+
+struct PathCache {
+ struct Vnode *parentVnode; /* vnode points to the cache */
+ struct Vnode *childVnode; /* vnode the cache points to */
+ LIST_ENTRY parentEntry; /* list entry for cache list in the parent vnode */
+ LIST_ENTRY childEntry; /* list entry for cache list in the child vnode */
+ LIST_ENTRY hashEntry; /* list entry for buckets in the hash table */
+ uint8_t nameLen; /* length of path component */
+ char name[0]; /* path component name */
+};
+
+int PathCacheInit(void);
+int PathCacheFree(struct PathCache *cache);
+struct PathCache *PathCacheAlloc(struct Vnode *parent, struct Vnode *vnode, const char *name, uint8_t len);
+int PathCacheAllocDummy(struct Vnode *parent, struct Vnode **vnode, const char *name, uint8_t len);
+int PathCacheLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode);
+void VnodePathCacheFree(struct Vnode *vnode);
+void PathCacheMemoryDump(void);
+
+#endif /* _PATH_CACHE_H */
diff --git a/fs/include/fs/vfs_util.h b/fs/include/fs/vfs_util.h
new file mode 100644
index 00000000..fad55ab4
--- /dev/null
+++ b/fs/include/fs/vfs_util.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VFS_UTIL_H_
+#define _VFS_UTIL_H_
+
+#include "los_list.h"
+
+typedef LOS_DL_LIST LIST_HEAD;
+typedef LOS_DL_LIST LIST_ENTRY;
+
+#define FNV1_32_INIT ((uint32_t) 33554467UL)
+#define FNV1_64_INIT ((uint64_t) 0xcbf29ce484222325ULL)
+
+#define FNV_32_PRIME ((uint32_t) 0x01000193UL)
+#define FNV_64_PRIME ((uint64_t) 0x100000001b3ULL)
+
+#define V_CREATE 0x0001
+#define V_CACHE 0x0002
+#define V_DUMMY 0x0004
+
+
+static __inline uint32_t fnv_32_buf(const void *buf, size_t len, uint32_t hval)
+{
+ const uint8_t *s = (const uint8_t *)buf;
+
+ while (len-- != 0) {
+ hval *= FNV_32_PRIME;
+ hval ^= *s++;
+ }
+ return hval;
+}
+
+int vfs_normalize_path(const char *directory, const char *filename, char **pathname);
+int vfs_normalize_pathat(int fd, const char *filename, char **pathname);
+
+#endif /* !_VFS_UTIL_H_ */
diff --git a/fs/include/fs/vnode.h b/fs/include/fs/vnode.h
new file mode 100644
index 00000000..6c4bf4e8
--- /dev/null
+++ b/fs/include/fs/vnode.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VNODE_H_
+#define _VNODE_H_
+
+#include
+#include "fs/fs_operation.h"
+#include "fs/file.h"
+#include "fs/vfs_util.h"
+#include "fs/path_cache.h"
+
+#define VNODE_FLAG_MOUNT_NEW 1
+#define VNODE_FLAG_MOUNT_ORIGIN 2
+#define DEV_PATH_LEN 5
+
+ /*
+ * Vnode types. VNODE_TYPE_UNKNOWN means no type.
+ */
+enum VnodeType {
+ VNODE_TYPE_UNKNOWN, /* unknown type */
+ VNODE_TYPE_REG, /* regular fle */
+ VNODE_TYPE_DIR, /* directory */
+ VNODE_TYPE_BLK, /* block device */
+ VNODE_TYPE_CHR, /* char device */
+ VNODE_TYPE_BCHR, /* block char mix device */
+ VNODE_TYPE_FIFO, /* pipe */
+ VNODE_TYPE_LNK, /* link */
+};
+
+struct fs_dirent_s;
+struct VnodeOps;
+struct IATTR;
+
+struct Vnode {
+ enum VnodeType type; /* vnode type */
+ int useCount; /* ref count of users */
+ uint32_t hash; /* vnode hash */
+ uint uid; /* uid for dac */
+ uint gid; /* gid for dac */
+ mode_t mode; /* mode for dac */
+ LIST_HEAD parentPathCaches; /* pathCaches point to parents */
+ LIST_HEAD childPathCaches; /* pathCaches point to children */
+ struct Vnode *parent; /* parent vnode */
+ struct VnodeOps *vop; /* vnode operations */
+ struct file_operations_vfs *fop; /* file operations */
+ void *data; /* private data */
+ uint32_t flag; /* vnode flag */
+ LIST_ENTRY hashEntry; /* list entry for bucket in hash table */
+ LIST_ENTRY actFreeEntry; /* vnode active/free list entry */
+ struct Mount *originMount; /* fs info about this vnode */
+ struct Mount *newMount; /* fs info about who mount on this vnode */
+};
+
+struct VnodeOps {
+ int (*Create)(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode);
+ int (*Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode);
+ int (*Open)(struct Vnode *vnode, int fd, int mode, int flags);
+ int (*Close)(struct Vnode *vnode);
+ int (*Reclaim)(struct Vnode *vnode);
+ int (*Unlink)(struct Vnode *parent, struct Vnode *vnode, char *fileName);
+ int (*Rmdir)(struct Vnode *parent, struct Vnode *vnode, char *dirName);
+ int (*Mkdir)(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode);
+ int (*Readdir)(struct Vnode *vnode, struct fs_dirent_s *dir);
+ int (*Opendir)(struct Vnode *vnode, struct fs_dirent_s *dir);
+ int (*Rewinddir)(struct Vnode *vnode, struct fs_dirent_s *dir);
+ int (*Closedir)(struct Vnode *vnode, struct fs_dirent_s *dir);
+ int (*Getattr)(struct Vnode *vnode, struct stat *st);
+ int (*Setattr)(struct Vnode *vnode, struct stat *st);
+ int (*Chattr)(struct Vnode *vnode, struct IATTR *attr);
+ int (*Rename)(struct Vnode *src, struct Vnode *dstParent, const char *srcName, const char *dstName);
+ int (*Truncate)(struct Vnode *vnode, off_t len);
+ int (*Truncate64)(struct Vnode *vnode, off64_t len);
+ int (*Fscheck)(struct Vnode *vnode, struct fs_dirent_s *dir);
+};
+
+typedef int VfsHashCmp(struct Vnode *vnode, void *arg);
+
+int VnodesInit(void);
+int VnodeDevInit(void);
+int VnodeAlloc(struct VnodeOps *vop, struct Vnode **vnode);
+int VnodeFree(struct Vnode *vnode);
+int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags);
+int VnodeHold(void);
+int VnodeDrop(void);
+void VnodeRefDec(struct Vnode *vnode);
+int VnodeFreeIter(struct Vnode *vnode);
+int VnodeFreeAll(struct Mount *mnt);
+int VnodeHashInit(void);
+uint32_t VfsHashIndex(struct Vnode *vnode);
+int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fun, void *arg);
+void VfsHashRemove(struct Vnode *vnode);
+int VfsHashInsert(struct Vnode *vnode, uint32_t hash);
+void ChangeRoot(struct Vnode *newRoot);
+BOOL VnodeInUseIter(struct Vnode *vnode);
+struct Vnode *VnodeGetRoot(void);
+void VnodeMemoryDump(void);
+
+#endif /* !_VNODE_H_ */
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index 3ab5ddbe..77a48a95 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -31,17 +31,12 @@ include $(LITEOSTOPDIR)/config.mk
MODULE_NAME := $(notdir $(shell pwd))
-LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/Linux_Kernel/fs/jffs2/*.c) \
- $(wildcard $(LITEOSTHIRDPARTY)/rt-thread/components/dfs/filesystems/jffs2/*.c) \
- $(wildcard $(LITEOSTHIRDPARTY)/rt-thread/components/dfs/filesystems/jffs2/src/fs-ecos.c)
+LOCAL_SRCS := $(wildcard src/*.c) \
+ $(wildcard $(LITEOSTHIRDPARTY)/Linux_Kernel/fs/jffs2/*.c)
LOCAL_INCLUDE := \
- -I $(LITEOSTHIRDPARTY)/Linux_Kernel/fs/jffs2 \
- -I $(LITEOSTHIRDPARTY)/Linux_Kernel/fs \
- -I $(LITEOSTHIRDPARTY)/rt-thread/components/dfs/filesystems/jffs2 \
- -I $(LITEOSTHIRDPARTY)/rt-thread/components/dfs/filesystems/jffs2/src \
- -I $(LITEOSTHIRDPARTY)/rt-thread/components/dfs/filesystems/jffs2/include/ \
- -I $(LITEOSTHIRDPARTY)/rt-thread/components/dfs/filesystems/jffs2/cyg/fileio
-
+ -I $(LITEOSTOPDIR)/fs/jffs2/include \
+ -I $(LITEOSTHIRDPARTY)/Linux_Kernel/fs/jffs2 \
+ -I $(LITEOSTHIRDPARTY)/Linux_Kernel/fs
LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS)
include $(MODULE)
diff --git a/fs/jffs2/include/jffs2_hash.h b/fs/jffs2/include/jffs2_hash.h
new file mode 100755
index 00000000..8da07117
--- /dev/null
+++ b/fs/jffs2/include/jffs2_hash.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __JFFS2_HASH_H__
+#define __JFFS2_HASH_H__
+
+#include "vfs_jffs2.h"
+#include "los_mux.h"
+#include "los_list.h"
+#include "jffs2_fs_i.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+int Jffs2HashInit(LosMux *lock, LOS_DL_LIST *heads);
+int Jffs2HashDeinit(LosMux *lock);
+void Jffs2HashDump(LosMux *lock, LOS_DL_LIST *heads);
+int Jffs2HashGet(LosMux *lock, LOS_DL_LIST *heads, const void *sb, const uint32_t ino, struct jffs2_inode **ppNode);
+void Jffs2HashRemove(LosMux *lock, struct jffs2_inode *node);
+int Jffs2HashInsert(LosMux *lock, LOS_DL_LIST *heads, struct jffs2_inode *node, const uint32_t ino);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/fs/jffs2/include/vfs_jffs2.h b/fs/jffs2/include/vfs_jffs2.h
new file mode 100644
index 00000000..1a704b91
--- /dev/null
+++ b/fs/jffs2/include/vfs_jffs2.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __VFS_JFFS2_H__
+#define __VFS_JFFS2_H__
+
+#include
+#include
+#include "los_config.h"
+#include "los_typedef.h"
+#include "los_list.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#ifndef NOR_FLASH_BOOT_SIZE
+#define NOR_FLASH_BOOT_SIZE 0x100000
+#endif
+
+#define BLOCK_SIZE 4096
+#define JFFS2_NODE_HASH_BUCKETS 128
+#define JFFS2_NODE_HASH_MASK (JFFS2_NODE_HASH_BUCKETS - 1)
+
+
+#define JFFS2_WAITING_FOREVER -1 /* Block forever until get resource. */
+
+/* block/char not support */
+#define JFFS2_F_I_RDEV_MIN(f) (0)
+#define JFFS2_F_I_RDEV_MAJ(f) (0)
+
+static inline unsigned int full_name_hash(const unsigned char *name, unsigned int len)
+{
+ unsigned hash = 0;
+ while (len--) {
+ hash = (hash << 4) | (hash >> 28);
+ hash ^= *(name++);
+ }
+ return hash;
+}
+
+int Jffs2MutexCreate(void);
+void Jffs2MutexDelete(void);
+void Jffs2NodeLock(void); /* lock for inode ops */
+void Jffs2NodeUnlock(void);
+time_t Jffs2CurSec(void);
+
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
diff --git a/fs/jffs2/src/jffs2_hash.c b/fs/jffs2/src/jffs2_hash.c
new file mode 100755
index 00000000..6e5d5919
--- /dev/null
+++ b/fs/jffs2/src/jffs2_hash.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "jffs2_hash.h"
+
+#ifdef LOSCFG_FS_JFFS
+
+int Jffs2HashInit(LosMux *lock, LOS_DL_LIST *heads)
+{
+ int ret;
+ for (int i = 0; i < JFFS2_NODE_HASH_BUCKETS; i++) {
+ LOS_ListInit(&heads[i]);
+ }
+
+ ret = LOS_MuxInit(lock, NULL);
+ if (ret != LOS_OK) {
+ PRINT_ERR("Create mutex for vnode hash list fail, status: %d", ret);
+ return ret;
+ }
+
+ return LOS_OK;
+}
+
+int Jffs2HashDeinit(LosMux *lock)
+{
+ int ret;
+ ret = LOS_MuxDestroy(lock);
+ if (ret != LOS_OK) {
+ PRINT_ERR("Destroy mutex for vnode hash list fail, status: %d", ret);
+ return ret;
+ }
+
+ return LOS_OK;
+}
+
+void Jffs2HashDump(LosMux *lock, LOS_DL_LIST *heads)
+{
+ PRINTK("-------->Jffs2HashDump in\n");
+ (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER);
+ for (int i = 0; i < JFFS2_NODE_HASH_BUCKETS; i++) {
+ LIST_HEAD *nhead = &heads[i];
+ struct jffs2_inode *node = NULL;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(node, nhead, struct jffs2_inode, i_hashlist) {
+ PRINTK(" vnode dump: col %d item %p\n", i, node);
+ }
+ }
+ (void)LOS_MuxUnlock(lock);
+ PRINTK("-------->Jffs2HashDump out\n");
+}
+
+static LOS_DL_LIST *Jffs2HashBucket(LOS_DL_LIST *heads, const uint32_t ino)
+{
+ LOS_DL_LIST *head = &(heads[ino & JFFS2_NODE_HASH_MASK]);
+ return head;
+}
+
+int Jffs2HashGet(LosMux *lock, LOS_DL_LIST *heads, const void *sb, const uint32_t ino, struct jffs2_inode **ppNode)
+{
+ struct jffs2_inode *node = NULL;
+
+ while (1) {
+ (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER);
+ LOS_DL_LIST *list = Jffs2HashBucket(heads, ino);
+ LOS_DL_LIST_FOR_EACH_ENTRY(node, list, struct jffs2_inode, i_hashlist) {
+ if (node->i_ino != ino)
+ continue;
+ if (node->i_sb != sb)
+ continue;
+ (void)LOS_MuxUnlock(lock);
+ *ppNode = node;
+ return 0;
+ }
+ (void)LOS_MuxUnlock(lock);
+ *ppNode = NULL;
+ return 0;
+ }
+}
+
+void Jffs2HashRemove(LosMux *lock, struct jffs2_inode *node)
+{
+ (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER);
+ LOS_ListDelete(&node->i_hashlist);
+ (void)LOS_MuxUnlock(lock);
+}
+
+int Jffs2HashInsert(LosMux *lock, LOS_DL_LIST *heads, struct jffs2_inode *node, const uint32_t ino)
+{
+ (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER);
+ LOS_ListHeadInsert(Jffs2HashBucket(heads, ino), &node->i_hashlist);
+ (void)LOS_MuxUnlock(lock);
+ return 0;
+}
+
+#endif
+
diff --git a/fs/jffs2/src/vfs_jffs2.c b/fs/jffs2/src/vfs_jffs2.c
new file mode 100755
index 00000000..f82f9c5f
--- /dev/null
+++ b/fs/jffs2/src/vfs_jffs2.c
@@ -0,0 +1,805 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vfs_jffs2.h"
+
+#include "fcntl.h"
+#include "sys/stat.h"
+#include "sys/statfs.h"
+#include "errno.h"
+
+#include "los_config.h"
+#include "los_typedef.h"
+#include "los_mux.h"
+#include "los_tables.h"
+#include "los_vm_filemap.h"
+#include "los_crc32.h"
+#include "capability_type.h"
+#include "capability_api.h"
+
+#include "fs/dirent_fs.h"
+#include "fs/fs.h"
+#include "fs/vnode.h"
+#include "mtd_list.h"
+#include "mtd_partition.h"
+#include "jffs2_hash.h"
+
+#include "os-linux.h"
+#include "jffs2/nodelist.h"
+
+#ifdef LOSCFG_FS_JFFS
+
+/* forward define */
+struct VnodeOps g_jffs2Vops;
+struct file_operations_vfs g_jffs2Fops;
+
+static LosMux g_jffs2FsLock; /* lock for all jffs2 ops */
+
+static pthread_mutex_t g_jffs2NodeLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+struct Vnode *g_jffs2PartList[CONFIG_MTD_PATTITION_NUM];
+
+static void Jffs2SetVtype(struct jffs2_inode *node, struct Vnode *pVnode)
+{
+ switch (node->i_mode & S_IFMT) {
+ case S_IFREG:
+ pVnode->type = VNODE_TYPE_REG;
+ break;
+ case S_IFDIR:
+ pVnode->type = VNODE_TYPE_DIR;
+ break;
+ default:
+ pVnode->type = VNODE_TYPE_UNKNOWN;
+ break;
+ }
+}
+
+time_t Jffs2CurSec(void)
+{
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL))
+ return 0;
+ return (uint32_t)(tv.tv_sec);
+}
+
+void Jffs2NodeLock(void)
+{
+ (void)pthread_mutex_lock(&g_jffs2NodeLock);
+}
+
+void Jffs2NodeUnlock(void)
+{
+ (void)pthread_mutex_unlock(&g_jffs2NodeLock);
+}
+
+int VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data)
+{
+ int ret;
+ int partNo;
+ mtd_partition *p = NULL;
+ struct MtdDev *mtd = NULL;
+ struct Vnode *pv = NULL;
+ struct jffs2_inode *rootNode = NULL;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+ p = (mtd_partition *)((struct drv_data *)blkDriver->data)->priv;
+ mtd = (struct MtdDev *)(p->mtd_info);
+
+ /* find a empty mte in partition table */
+ if (mtd == NULL || mtd->type != MTD_NORFLASH) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return -EINVAL;
+ }
+
+ partNo = p->patitionnum;
+
+ ret = jffs2_mount(partNo, &rootNode);
+ if (ret != 0) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+
+ ret = VnodeAlloc(&g_jffs2Vops, &pv);
+ if (ret != 0) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ goto ERROR_WITH_VNODE;
+ }
+ rootNode->i_vnode = pv;
+ pv->type = VNODE_TYPE_DIR;
+ pv->data = (void *)rootNode;
+ pv->originMount = mnt;
+ pv->fop = &g_jffs2Fops;
+ mnt->data = p;
+ mnt->vnodeCovered = pv;
+ pv->uid = rootNode->i_uid;
+ pv->gid = rootNode->i_gid;
+ pv->mode = rootNode->i_mode;
+
+ (void)VfsHashInsert(pv, rootNode->i_ino);
+
+ g_jffs2PartList[partNo] = blkDriver;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return 0;
+ERROR_WITH_VNODE:
+ return ret;
+}
+
+int VfsJffs2Unbind(struct Mount *mnt, struct Vnode **blkDriver)
+{
+ int ret;
+ mtd_partition *p = NULL;
+ int partNo;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ p = (mtd_partition *)mnt->data;
+ if (p == NULL) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return -EINVAL;
+ }
+
+ partNo = p->patitionnum;
+ ret = jffs2_umount((struct jffs2_inode *)mnt->vnodeCovered->data);
+ if (ret) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+
+ free(p->mountpoint_name);
+ p->mountpoint_name = NULL;
+ *blkDriver = g_jffs2PartList[partNo];
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return 0;
+}
+
+int VfsJffs2Lookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **ppVnode)
+{
+ int ret;
+ struct Vnode *newVnode = NULL;
+ struct jffs2_inode *node = NULL;
+ struct jffs2_inode *parentNode = NULL;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ parentNode = (struct jffs2_inode *)parentVnode->data;
+ node = jffs2_lookup(parentNode, (const unsigned char *)path, len);
+ if (!node) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return -ENOENT;
+ }
+
+ if (node->i_vnode) {
+ *ppVnode = node->i_vnode;
+ (void)VfsHashGet(parentVnode->originMount, node->i_ino, &newVnode, NULL, NULL);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ if (newVnode) {
+ *ppVnode = newVnode;
+ return 0;
+ }
+ }
+ ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
+ if (ret != 0) {
+ PRINT_ERR("%s-%d, ret: %x\n", __FUNCTION__, __LINE__, ret);
+ (void)jffs2_iput(node);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+
+ Jffs2SetVtype(node, newVnode);
+ node->i_vnode = newVnode;
+ newVnode->vop = parentVnode->vop;
+ newVnode->fop = parentVnode->fop;
+ newVnode->data = node;
+ newVnode->parent = parentVnode;
+ newVnode->originMount = parentVnode->originMount;
+ newVnode->uid = node->i_uid;
+ newVnode->gid = node->i_gid;
+ newVnode->mode = node->i_mode;
+
+ (void)VfsHashInsert(newVnode, node->i_ino);
+
+ *ppVnode = newVnode;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return 0;
+}
+
+int VfsJffs2Create(struct Vnode *parentVnode, const char *path, int mode, struct Vnode **ppVnode)
+{
+ int ret;
+ struct jffs2_inode *newNode = NULL;
+ struct Vnode *newVnode = NULL;
+
+ ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
+ if (ret != 0) {
+ return -ENOMEM;
+ }
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+ ret = jffs2_create((struct jffs2_inode *)parentVnode->data, (const unsigned char *)path, mode, &newNode);
+ if (ret != 0) {
+ VnodeFree(newVnode);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+
+ newVnode->type = VNODE_TYPE_REG;
+ newNode->i_vnode = newVnode;
+ newVnode->vop = parentVnode->vop;
+ newVnode->fop = parentVnode->fop;
+ newVnode->data = newNode;
+ newVnode->parent = parentVnode;
+ newVnode->originMount = parentVnode->originMount;
+ newVnode->uid = newNode->i_uid;
+ newVnode->gid = newNode->i_gid;
+ newVnode->mode = newNode->i_mode;
+
+ (void)VfsHashInsert(newVnode, newNode->i_ino);
+
+ *ppVnode = newVnode;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return 0;
+}
+
+int VfsJffs2Close(struct file *filep)
+{
+ return 0;
+}
+
+ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
+{
+ struct jffs2_inode *node = NULL;
+ struct jffs2_inode_info *f = NULL;
+ struct jffs2_sb_info *c = NULL;
+ int ret;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ node = (struct jffs2_inode *)filep->f_vnode->data;
+ f = JFFS2_INODE_INFO(node);
+ c = JFFS2_SB_INFO(node->i_sb);
+
+ off_t pos = min(node->i_size, filep->f_pos);
+ off_t len = min(bufLen, (node->i_size - pos));
+ ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, filep->f_pos, len);
+ if (ret) {
+ PRINTK("VfsJffs2Read(): read_inode_range failed %d\n", ret);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+ node->i_atime = Jffs2CurSec();
+ filep->f_pos += len;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return len;
+}
+
+ssize_t VfsJffs2Write(struct file *filep, const char *buffer, size_t bufLen)
+{
+ struct jffs2_inode *node = NULL;
+ struct jffs2_inode_info *f = NULL;
+ struct jffs2_sb_info *c = NULL;
+ struct jffs2_raw_inode ri = {0};
+ struct IATTR attr = {0};
+ int ret;
+ off_t pos;
+ uint32_t writtenLen;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ node = (struct jffs2_inode *)filep->f_vnode->data;
+ f = JFFS2_INODE_INFO(node);
+ c = JFFS2_SB_INFO(node->i_sb);
+ pos = filep->f_pos;
+
+#if (LOSCFG_KERNEL_SMP == YES)
+ struct super_block *sb = node->i_sb;
+ UINT16 gcCpuMask = LOS_TaskCpuAffiGet(sb->s_gc_thread);
+ UINT32 curTaskId = LOS_CurTaskIDGet();
+ UINT16 curCpuMask = LOS_TaskCpuAffiGet(curTaskId);
+ if (curCpuMask != gcCpuMask) {
+ if (curCpuMask != LOSCFG_KERNEL_CPU_MASK) {
+ (void)LOS_TaskCpuAffiSet(sb->s_gc_thread, curCpuMask);
+ } else {
+ (void)LOS_TaskCpuAffiSet(curTaskId, gcCpuMask);
+ }
+ }
+#endif
+ // If the APPEND mode bit was supplied, force all writes to
+ // the end of the file.
+ if (filep->f_oflags & O_APPEND)
+ pos = node->i_size;
+ if (pos < 0) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return -EINVAL;
+ }
+
+ ri.ino = cpu_to_je32(f->inocache->ino);
+ ri.mode = cpu_to_jemode(node->i_mode);
+ ri.uid = cpu_to_je16(node->i_uid);
+ ri.gid = cpu_to_je16(node->i_gid);
+ ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec());
+
+ if (pos > node->i_size) {
+ int err;
+ attr.attr_chg_valid = CHG_SIZE;
+ attr.attr_chg_size = pos;
+ err = jffs2_setattr(node, &attr);
+ if (err) {
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return err;
+ }
+ }
+ ri.isize = cpu_to_je32(node->i_size);
+
+ ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, bufLen, &writtenLen);
+ if (ret) {
+ pos += writtenLen;
+
+ node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
+ if (pos > node->i_size)
+ node->i_size = pos;
+
+ filep->f_pos = pos;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return ret;
+ }
+
+ if (writtenLen != bufLen) {
+ pos += writtenLen;
+
+ node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
+ if (pos > node->i_size)
+ node->i_size = pos;
+
+ filep->f_pos = pos;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return -ENOSPC;
+ }
+
+ pos += bufLen;
+
+ node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
+ if (pos > node->i_size)
+ node->i_size = pos;
+
+ filep->f_pos = pos;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return writtenLen;
+}
+
+off_t VfsJffs2Seek(struct file *filep, off_t offset, int whence)
+{
+ struct jffs2_inode *node = NULL;
+ loff_t filePos;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ node = (struct jffs2_inode *)filep->f_vnode->data;
+ filePos = filep->f_pos;
+
+ switch (whence) {
+ case SEEK_SET:
+ filePos = offset;
+ break;
+
+ case SEEK_CUR:
+ filePos += offset;
+ break;
+
+ case SEEK_END:
+ filePos = node->i_size + offset;
+ break;
+
+ default:
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return -EINVAL;
+ }
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ if (filePos < 0)
+ return -EINVAL;
+
+ return filePos;
+}
+
+int VfsJffs2Ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+ PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__);
+ return -ENOSYS;
+}
+
+int VfsJffs2Fsync(struct file *filep)
+{
+ /* jffs2_write directly write to flash, sync is OK.
+ BUT after pagecache enabled, pages need to be flushed to flash */
+ return 0;
+}
+
+int VfsJffs2Dup(const struct file *oldFile, struct file *newFile)
+{
+ PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__);
+ return -ENOSYS;
+}
+
+int VfsJffs2Opendir(struct Vnode *pVnode, struct fs_dirent_s *dir)
+{
+ dir->fd_int_offset = 0;
+ return 0;
+}
+
+int VfsJffs2Readdir(struct Vnode *pVnode, struct fs_dirent_s *dir)
+{
+ int ret;
+ int i = 0;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ /* set jffs2_d */
+ while (i < MAX_DIRENT_NUM && i < dir->read_cnt) {
+ ret = jffs2_readdir((struct jffs2_inode *)pVnode->data, &dir->fd_position,
+ &dir->fd_int_offset, &dir->fd_dir[i]);
+ if (ret) {
+ break;
+ }
+
+ i++;
+ }
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return i;
+}
+
+int VfsJffs2Seekdir(struct Vnode *pVnode, struct fs_dirent_s *dir, unsigned long offset)
+{
+ return 0;
+}
+
+int VfsJffs2Rewinddir(struct Vnode *pVnode, struct fs_dirent_s *dir)
+{
+ dir->fd_int_offset = 0;
+
+ return 0;
+}
+
+int VfsJffs2Closedir(struct Vnode *node, struct fs_dirent_s *dir)
+{
+ return 0;
+}
+
+int VfsJffs2Mkdir(struct Vnode *parentNode, const char *dirName, mode_t mode, struct Vnode **ppVnode)
+{
+ int ret;
+ struct jffs2_inode *node = NULL;
+ struct Vnode *newVnode = NULL;
+
+ ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
+ if (ret != 0) {
+ return -ENOMEM;
+ }
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ ret = jffs2_mkdir((struct jffs2_inode *)parentNode->data, (const unsigned char *)dirName, mode, &node);
+ if (ret != 0) {
+ VnodeFree(newVnode);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+
+ newVnode->type = VNODE_TYPE_DIR;
+ node->i_vnode = newVnode;
+ newVnode->vop = parentNode->vop;
+ newVnode->fop = parentNode->fop;
+ newVnode->data = node;
+ newVnode->parent = parentNode;
+ newVnode->originMount = parentNode->originMount;
+ newVnode->uid = node->i_uid;
+ newVnode->gid = node->i_gid;
+ newVnode->mode = node->i_mode;
+
+ *ppVnode = newVnode;
+
+ (void)VfsHashInsert(newVnode, node->i_ino);
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return 0;
+}
+
+static int Jffs2Truncate(struct Vnode *pVnode, unsigned int len)
+{
+ int ret;
+ struct IATTR attr = {0};
+
+ attr.attr_chg_size = len;
+ attr.attr_chg_valid = CHG_SIZE;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+ ret = jffs2_setattr((struct jffs2_inode *)pVnode->data, &attr);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+}
+
+int VfsJffs2Truncate(struct Vnode *pVnode, off_t len)
+{
+ int ret = Jffs2Truncate(pVnode, (unsigned int)len);
+ return ret;
+}
+
+int VfsJffs2Truncate64(struct Vnode *pVnode, off64_t len)
+{
+ int ret = Jffs2Truncate(pVnode, (unsigned int)len);
+ return ret;
+}
+
+int VfsJffs2Chattr(struct Vnode *pVnode, struct IATTR *attr)
+{
+ int ret;
+ struct jffs2_inode *node = NULL;
+
+ if (pVnode == NULL) {
+ return -EINVAL;
+ }
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ node = pVnode->data;
+ ret = jffs2_setattr(node, attr);
+ if (ret == 0) {
+ pVnode->uid = node->i_uid;
+ pVnode->gid = node->i_gid;
+ pVnode->mode = node->i_mode;
+ }
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+}
+
+int VfsJffs2Rmdir(struct Vnode *parentVnode, struct Vnode *targetVnode, char *path)
+{
+ int ret;
+
+ if (!parentVnode || !targetVnode) {
+ return -EINVAL;
+ }
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ ret = jffs2_rmdir((struct jffs2_inode *)parentVnode->data, (struct jffs2_inode *)targetVnode->data,
+ (const unsigned char *)path);
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+}
+
+int VfsJffs2Unlink(struct Vnode *parentVnode, struct Vnode *targetVnode, char *path)
+{
+ int ret;
+
+ if (!parentVnode || !targetVnode) {
+ PRINTK("%s-%d parentVnode=%x, targetVnode=%x\n", __FUNCTION__, __LINE__, parentVnode, targetVnode);
+ return -EINVAL;
+ }
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ ret = jffs2_unlink((struct jffs2_inode *)parentVnode->data, (struct jffs2_inode *)targetVnode->data,
+ (const unsigned char *)path);
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+}
+
+int VfsJffs2Rename(struct Vnode *fromVnode, struct Vnode *toParentVnode, const char *fromName, const char *toName)
+{
+ int ret;
+ struct Vnode *fromParentVnode = NULL;
+ struct Vnode *toVnode = NULL;
+ struct jffs2_inode *fromNode = NULL;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+ fromParentVnode = fromVnode->parent;
+
+ ret = VfsJffs2Lookup(toParentVnode, toName, strlen(toName), &toVnode);
+ if (ret == 0) {
+ if (toVnode->type == VNODE_TYPE_DIR) {
+ ret = VfsJffs2Rmdir(toParentVnode, toVnode, (char *)toName);
+ } else {
+ ret = VfsJffs2Unlink(toParentVnode, toVnode, (char *)toName);
+ }
+ if (ret) {
+ PRINTK("%s-%d remove newname(%s) failed ret=%d\n", __FUNCTION__, __LINE__, toName, ret);
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return ret;
+ }
+ }
+ fromNode = (struct jffs2_inode *)fromVnode->data;
+ ret = jffs2_rename((struct jffs2_inode *)fromParentVnode->data, fromNode,
+ (const unsigned char *)fromName, (struct jffs2_inode *)toParentVnode->data, (const unsigned char *)toName);
+ /* Careful with this: we can safely free the fromVnode AND toVnode but not fromNode, so reset the i_vnode field OR
+ it will be a jungle field. With a new lookup process, we'll allocate a new vnode for it. */
+ fromVnode->parent = toParentVnode;
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+int VfsJffs2Stat(struct Vnode *pVnode, struct stat *buf)
+{
+ struct jffs2_inode *node = NULL;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ node = (struct jffs2_inode *)pVnode->data;
+ switch (node->i_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFDIR:
+ buf->st_mode = node->i_mode;
+ break;
+
+ default:
+ buf->st_mode = DT_UNKNOWN;
+ break;
+ }
+
+ buf->st_dev = 0;
+ buf->st_ino = node->i_ino;
+ buf->st_nlink = node->i_nlink;
+ buf->st_uid = node->i_uid;
+ buf->st_gid = node->i_gid;
+ buf->st_size = node->i_size;
+ buf->st_blksize = BLOCK_SIZE;
+ buf->st_blocks = buf->st_size / buf->st_blksize;
+ buf->st_atime = node->i_atime;
+ buf->st_mtime = node->i_mtime;
+ buf->st_ctime = node->i_ctime;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return 0;
+}
+
+int VfsJffs2Reclaim(struct Vnode *pVnode)
+{
+ int ret;
+ struct jffs2_inode *node = NULL;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ node = pVnode->data;
+ if (node == NULL) {
+ return LOS_OK;
+ }
+
+ ret = jffs2_iput(node);
+ node->i_vnode = NULL;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+
+ return ret;
+}
+
+int VfsJffs2Statfs(struct Mount *mnt, struct statfs *buf)
+{
+ unsigned long freeSize;
+ struct jffs2_sb_info *c = NULL;
+ struct jffs2_inode *rootNode = NULL;
+
+ LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
+
+ rootNode = (struct jffs2_inode *)mnt->vnodeCovered->data;
+ c = JFFS2_SB_INFO(rootNode->i_sb);
+
+ freeSize = c->free_size + c->dirty_size;
+ buf->f_type = JFFS2_SUPER_MAGIC;
+ buf->f_bsize = PAGE_SIZE;
+ buf->f_blocks = (((uint64_t)c->nr_blocks) * c->sector_size) / PAGE_SIZE;
+ buf->f_bfree = freeSize / PAGE_SIZE;
+ buf->f_bavail = buf->f_bfree;
+ buf->f_namelen = NAME_MAX;
+ buf->f_fsid.__val[0] = JFFS2_SUPER_MAGIC;
+ buf->f_fsid.__val[1] = 1;
+ buf->f_frsize = BLOCK_SIZE;
+ buf->f_files = 0;
+ buf->f_ffree = 0;
+ buf->f_flags = mnt->mountFlags;
+
+ LOS_MuxUnlock(&g_jffs2FsLock);
+ return 0;
+}
+
+int Jffs2MutexCreate(void)
+{
+ if (LOS_MuxInit(&g_jffs2FsLock, NULL) != LOS_OK) {
+ PRINT_ERR("%s, LOS_MuxCreate failed\n", __FUNCTION__);
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+void Jffs2MutexDelete(void)
+{
+ (void)LOS_MuxDestroy(&g_jffs2FsLock);
+}
+
+const struct MountOps jffs_operations = {
+ .Mount = VfsJffs2Bind,
+ .Unmount = VfsJffs2Unbind,
+ .Statfs = VfsJffs2Statfs,
+};
+
+struct VnodeOps g_jffs2Vops = {
+ .Lookup = VfsJffs2Lookup,
+ .Create = VfsJffs2Create,
+ .Rename = VfsJffs2Rename,
+ .Mkdir = VfsJffs2Mkdir,
+ .Getattr = VfsJffs2Stat,
+ .Opendir = VfsJffs2Opendir,
+ .Readdir = VfsJffs2Readdir,
+ .Closedir = VfsJffs2Closedir,
+ .Rewinddir = VfsJffs2Rewinddir,
+ .Unlink = VfsJffs2Unlink,
+ .Rmdir = VfsJffs2Rmdir,
+ .Chattr = VfsJffs2Chattr,
+ .Reclaim = VfsJffs2Reclaim,
+ .Truncate = VfsJffs2Truncate,
+ .Truncate64 = VfsJffs2Truncate64,
+};
+
+struct file_operations_vfs g_jffs2Fops = {
+ .read = VfsJffs2Read,
+ .write = VfsJffs2Write,
+ .mmap = OsVfsFileMmap,
+ .seek = VfsJffs2Seek,
+ .close = VfsJffs2Close,
+ .fsync = VfsJffs2Fsync,
+};
+
+
+FSMAP_ENTRY(jffs_fsmap, "jffs2", jffs_operations, TRUE, TRUE);
+
+#endif
diff --git a/fs/proc/include/proc_file.h b/fs/proc/include/proc_file.h
index 245ad39e..5d6b9fda 100755
--- a/fs/proc/include/proc_file.h
+++ b/fs/proc/include/proc_file.h
@@ -181,4 +181,7 @@ int LseekDirProcFile(struct ProcDirEntry *pde, off_t *pos, int whence);
*/
extern int CloseProcFile(struct ProcDirEntry *pde);
+extern struct ProcDirEntry *GetProcRootEntry(void);
+extern int ProcOpen(struct ProcFile *procFile);
+
#endif
diff --git a/fs/proc/include/proc_fs.h b/fs/proc/include/proc_fs.h
index 3106fc5b..3cc4ea9d 100755
--- a/fs/proc/include/proc_fs.h
+++ b/fs/proc/include/proc_fs.h
@@ -50,7 +50,6 @@ extern "C" {
#endif /* __cplusplus */
typedef unsigned short fmode_t;
-#define MAX_NAMELEN 32
#define PROC_ERROR (-1)
/* 64bit hashes as llseek() offset (for directories) */
@@ -83,8 +82,8 @@ struct ProcFile;
struct ProcFileOperations {
char *name;
ssize_t (*write)(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos);
- int (*open)(struct inode *inode, struct ProcFile *pf);
- int (*release)(struct inode *inode, struct ProcFile *pf);
+ int (*open)(struct Vnode *vnode, struct ProcFile *pf);
+ int (*release)(struct Vnode *vnode, struct ProcFile *pf);
int (*read)(struct SeqBuf *m, void *v);
};
@@ -100,7 +99,8 @@ struct ProcDirEntry {
int nameLen;
struct ProcDirEntry *pdirCurrent;
- char name[MAX_NAMELEN];
+ char name[NAME_MAX];
+ enum VnodeType type;
};
struct ProcFile {
@@ -111,13 +111,13 @@ struct ProcFile {
struct ProcDirEntry *pPDE;
unsigned long long fVersion;
loff_t fPos;
- char name[MAX_NAMELEN];
+ char name[NAME_MAX];
};
struct ProcStat {
mode_t stMode;
struct ProcDirEntry *pPDE;
- char name[MAX_NAMELEN];
+ char name[NAME_MAX];
};
struct ProcData {
@@ -138,7 +138,7 @@ struct ProcData {
* @brief create a proc node
*
* @par Description:
- * This API is used to create the node by 'name' and parent inode
+ * This API is used to create the node by 'name' and parent vnode
*
* @attention
*
@@ -165,7 +165,7 @@ extern struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struc
* @brief remove a proc node
*
* @par Description:
- * This API is used to remove the node by 'name' and parent inode
+ * This API is used to remove the node by 'name' and parent vnode
*
* @attention
*
@@ -188,7 +188,7 @@ extern void RemoveProcEntry(const char *name, struct ProcDirEntry *parent);
* @brief create a proc directory node
*
* @par Description:
- * This API is used to create the directory node by 'name' and parent inode
+ * This API is used to create the directory node by 'name' and parent vnode
*
* @attention
*
@@ -214,7 +214,7 @@ extern struct ProcDirEntry *ProcMkdir(const char *name, struct ProcDirEntry *par
* @brief create a proc node
*
* @par Description:
- * This API is used to create the node by 'name' and parent inode,
+ * This API is used to create the node by 'name' and parent vnode,
* And assignment operation function
*
* @attention
diff --git a/fs/proc/os_adapt/mounts_proc.c b/fs/proc/os_adapt/mounts_proc.c
index 692511d6..644a0cc1 100755
--- a/fs/proc/os_adapt/mounts_proc.c
+++ b/fs/proc/os_adapt/mounts_proc.c
@@ -29,13 +29,16 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "internal.h"
+#include "proc_fs.h"
+
#include
#include
#include
-#include "proc_fs.h"
-static int ShowType(FAR const char *mountPoint, FAR struct statfs *statBuf, FAR void *arg)
+#include "fs/file.h"
+#include "internal.h"
+
+static int ShowType(const char *mountPoint, struct statfs *statBuf, void *arg)
{
struct SeqBuf *seqBuf = (struct SeqBuf *)arg;
char *type = NULL;
@@ -47,8 +50,8 @@ static int ShowType(FAR const char *mountPoint, FAR struct statfs *statBuf, FAR
name = "proc";
break;
case JFFS2_SUPER_MAGIC:
- type = "jffs";
- name = "jffs";
+ type = "jffs2";
+ name = "jffs2";
break;
case NFS_SUPER_MAGIC:
type = "nfs";
@@ -78,7 +81,7 @@ static int ShowType(FAR const char *mountPoint, FAR struct statfs *statBuf, FAR
static int MountsProcFill(struct SeqBuf *m, void *v)
{
foreach_mountpoint_t handler = ShowType;
- (void)foreach_mountpoint(handler, (FAR void *)m);
+ (void)foreach_mountpoint(handler, (void *)m);
return 0;
}
diff --git a/fs/proc/os_adapt/proc_init.c b/fs/proc/os_adapt/proc_init.c
index 5718ab94..7b24058b 100755
--- a/fs/proc/os_adapt/proc_init.c
+++ b/fs/proc/os_adapt/proc_init.c
@@ -33,6 +33,7 @@
#include
#include
#include "proc_fs.h"
+#include "sys/stat.h"
#ifdef LOSCFG_FS_PROC
@@ -42,7 +43,7 @@ void ProcFsInit(void)
ret = mkdir(PROCFS_MOUNT_POINT, 0);
if (ret < 0) {
- PRINT_ERR("failed to reserve inode %s\n", PROCFS_MOUNT_POINT);
+ PRINT_ERR("failed to mkdir %s, errno = %d\n", PROCFS_MOUNT_POINT, get_errno());
return;
}
diff --git a/fs/proc/os_adapt/proc_vfs.c b/fs/proc/os_adapt/proc_vfs.c
new file mode 100755
index 00000000..3e3374f7
--- /dev/null
+++ b/fs/proc/os_adapt/proc_vfs.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "proc_file.h"
+
+#include
+#include
+#include
+#include
+
+#include "fs/dirent_fs.h"
+#include "los_tables.h"
+#include "internal.h"
+
+#define PROCFS_DEFAULT_MODE 0555
+
+#ifdef LOSCFG_FS_PROC
+static struct VnodeOps g_procfsVops;
+static struct file_operations_vfs g_procfsFops;
+
+static struct ProcDirEntry *VnodeToEntry(struct Vnode *node)
+{
+ return (struct ProcDirEntry *)(node->data);
+}
+
+static struct Vnode *EntryToVnode(struct ProcDirEntry *entry)
+{
+ struct Vnode *node = NULL;
+
+ (void)VnodeAlloc(&g_procfsVops, &node);
+ node->fop = &g_procfsFops;
+ node->data = entry;
+ node->type = entry->type;
+ if (node->type == VNODE_TYPE_DIR) {
+ node->mode = S_IFDIR | PROCFS_DEFAULT_MODE;
+ } else {
+ node->mode = S_IFREG | PROCFS_DEFAULT_MODE;
+ }
+ return node;
+}
+
+static int EntryMatch(const char *name, int len, const struct ProcDirEntry *pn)
+{
+ if (len != pn->nameLen) {
+ return 0;
+ }
+ return !strncmp(name, pn->name, len);
+}
+
+int VfsProcfsRead(struct file *filep, char *buffer, size_t buflen)
+{
+ ssize_t size;
+ struct ProcDirEntry *entry = NULL;
+ if ((filep == NULL) || (filep->f_vnode == NULL) || (buffer == NULL)) {
+ return -EINVAL;
+ }
+
+ entry = VnodeToEntry(filep->f_vnode);
+ size = (ssize_t)ReadProcFile(entry, (void *)buffer, buflen);
+ filep->f_pos = entry->pf->fPos;
+
+ return size;
+}
+
+int VfsProcfsLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vpp)
+{
+ if (parent == NULL || name == NULL || len <= 0 || vpp == NULL) {
+ return -EINVAL;
+ }
+ struct ProcDirEntry *entry = VnodeToEntry(parent);
+ if (entry == NULL) {
+ return -ENODATA;
+ }
+ entry = entry->subdir;
+ while (1) {
+ if (entry == NULL) {
+ return -ENOENT;
+ }
+ if (EntryMatch(name, len, entry)) {
+ break;
+ }
+ entry = entry->next;
+ }
+
+ *vpp = EntryToVnode(entry);
+ if ((*vpp) == NULL) {
+ return -ENOMEM;
+ }
+ (*vpp)->originMount = parent->originMount;
+ (*vpp)->parent = parent;
+ return LOS_OK;
+}
+
+int VfsProcfsMount(struct Mount *mnt, struct Vnode *device, const void *data)
+{
+ struct Vnode *vp = NULL;
+ int ret;
+
+ spin_lock_init(&procfsLock);
+ procfsInit = true;
+
+ ret = VnodeAlloc(&g_procfsVops, &vp);
+ if (ret != 0) {
+ return -ENOMEM;
+ }
+
+ struct ProcDirEntry *root = GetProcRootEntry();
+ vp->data = root;
+ vp->originMount = mnt;
+ vp->fop = &g_procfsFops;
+ mnt->data = NULL;
+ mnt->vnodeCovered = vp;
+ vp->type = root->type;
+ if (vp->type == VNODE_TYPE_DIR) {
+ vp->mode = S_IFDIR | PROCFS_DEFAULT_MODE;
+ } else {
+ vp->mode = S_IFREG | PROCFS_DEFAULT_MODE;
+ }
+
+ return LOS_OK;
+}
+
+int VfsProcfsUnmount(void *handle, struct Vnode **blkdriver)
+{
+ (void)handle;
+ (void)blkdriver;
+ return -EPERM;
+}
+
+int VfsProcfsStat(struct Vnode *node, struct stat *buf)
+{
+ struct ProcDirEntry *entry = VnodeToEntry(node);
+
+ (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
+ buf->st_mode = entry->mode;
+
+ return LOS_OK;
+}
+
+int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
+{
+ int result;
+ char *buffer = NULL;
+ int buflen = NAME_MAX;
+ unsigned int min_size;
+ unsigned int dst_name_size;
+ struct ProcDirEntry *pde = NULL;
+ int i = 0;
+
+ if (dir == NULL) {
+ return -EINVAL;
+ }
+ if (node->type != VNODE_TYPE_DIR) {
+ return -ENOTDIR;
+ }
+ pde = VnodeToEntry(node);
+
+ while ((i < MAX_DIRENT_NUM) || (i < dir->read_cnt)) {
+ buffer = (char *)zalloc(sizeof(char) * NAME_MAX);
+ if (buffer == NULL) {
+ PRINT_ERR("malloc failed\n");
+ return -ENOMEM;
+ }
+
+ result = ReadProcFile(pde, (void *)buffer, buflen);
+ if (result != ENOERR) {
+ free(buffer);
+ break;
+ }
+ dst_name_size = sizeof(dir->fd_dir[i].d_name);
+ min_size = (dst_name_size < NAME_MAX) ? dst_name_size : NAME_MAX;
+ result = strncpy_s(dir->fd_dir[i].d_name, dst_name_size, buffer, min_size);
+ if (result != EOK) {
+ free(buffer);
+ return -ENAMETOOLONG;
+ }
+ dir->fd_dir[i].d_name[dst_name_size - 1] = '\0';
+ dir->fd_position++;
+ dir->fd_dir[i].d_off = dir->fd_position;
+ dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent);
+
+ i++;
+ free(buffer);
+ }
+
+ return i;
+}
+
+int VfsProcfsOpendir(struct Vnode *node, struct fs_dirent_s *dir)
+{
+ struct ProcDirEntry *pde = VnodeToEntry(node);
+ if (pde == NULL) {
+ return -EINVAL;
+ }
+ pde->pdirCurrent = pde->subdir;
+ pde->pf->fPos = 0;
+
+ return LOS_OK;
+}
+
+int VfsProcfsOpen(struct file *filep)
+{
+ if (filep == NULL) {
+ return -EINVAL;
+ }
+ struct Vnode *node = filep->f_vnode;
+ struct ProcDirEntry *pde = VnodeToEntry(node);
+ if (ProcOpen(pde->pf) != OK) {
+ return -ENOMEM;
+ }
+ filep->f_priv = (void *)pde;
+ return LOS_OK;
+}
+
+int VfsProcfsClose(struct file *filep)
+{
+ int result = 0;
+ if (filep == NULL) {
+ return -EINVAL;
+ }
+ struct Vnode *node = filep->f_vnode;
+ struct ProcDirEntry *pde = VnodeToEntry(node);
+ pde->pf->fPos = 0;
+ if ((pde->procFileOps != NULL) && (pde->procFileOps->release != NULL)) {
+ result = pde->procFileOps->release((struct Vnode *)pde, pde->pf);
+ }
+ LosBufRelease(pde->pf->sbuf);
+ pde->pf->sbuf = NULL;
+
+ return result;
+}
+
+const struct MountOps procfs_operations = {
+ .Mount = VfsProcfsMount,
+ .Unmount = NULL,
+};
+
+static struct VnodeOps g_procfsVops = {
+ .Lookup = VfsProcfsLookup,
+ .Getattr = VfsProcfsStat,
+ .Readdir = VfsProcfsReaddir,
+ .Opendir = VfsProcfsOpendir,
+};
+
+static struct file_operations_vfs g_procfsFops = {
+ .read = VfsProcfsRead,
+ .open = VfsProcfsOpen,
+ .close = VfsProcfsClose
+};
+
+FSMAP_ENTRY(procfs_fsmap, "procfs", procfs_operations, FALSE, FALSE);
+#endif
diff --git a/fs/proc/os_adapt/vfs_proc.c b/fs/proc/os_adapt/vfs_proc.c
deleted file mode 100755
index a45c980b..00000000
--- a/fs/proc/os_adapt/vfs_proc.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
- * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. Neither the name of the copyright holder nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include
-#include
-#include
-#include
-#include "internal.h"
-#include "fs/dirent_fs.h"
-#include "los_tables.h"
-#include "proc_file.h"
-
-#ifdef LOSCFG_FS_PROC
-
-static char *ProcfsChangePath(const char *relpath, int namelen)
-{
- char *path = (char *)relpath;
-
- if (*relpath != 0) {
- path = path - (namelen + 1); /* "/proc/xxx" need left avertence "/proc/" */
- } else {
- path = path - namelen;
- }
-
- return path;
-}
-
-int VfsProcfsOpen(struct file *filep, const char *relpath, int oflags, mode_t mode)
-{
- struct ProcDirEntry *pde = NULL;
- if (filep == NULL) {
- return -EINVAL;
- }
- if ((unsigned int)oflags & O_DIRECTORY) {
- return -EACCES;
- }
- pde = OpenProcFile(filep->f_path, oflags);
- if (pde == NULL) {
- if ((unsigned int)oflags & O_CREAT) {
- return -EPERM;
- }
- return -ENOENT;
- }
- if (((unsigned int)oflags & O_CREAT) && ((unsigned int)oflags & O_EXCL)) {
- (void)CloseProcFile(pde);
- return -EEXIST;
- }
- if (S_ISDIR(pde->mode)) {
- (void)CloseProcFile(pde);
- return -EISDIR;
- }
- filep->f_priv = (void *)pde;
- filep->f_pos = 0;
-
- return 0;
-}
-
-int VfsProcfsClose(struct file *filep)
-{
- if (filep == NULL) {
- return -EINVAL;
- }
- return CloseProcFile((struct ProcDirEntry *)filep->f_priv);
-}
-
-ssize_t VfsProcfsRead(struct file *filep, FAR char *buffer, size_t buflen)
-{
- ssize_t size;
- struct ProcDirEntry *pde = NULL;
- if ((filep == NULL) || (buffer == NULL)) {
- return -EINVAL;
- }
-
- pde = (struct ProcDirEntry *)filep->f_priv;
- size = (ssize_t)ReadProcFile(pde, (void *)buffer, buflen);
- filep->f_pos = pde->pf->fPos;
-
- return size;
-}
-
-ssize_t VfsProcfsWrite(struct file *filep, const char *buffer, size_t buflen)
-{
- ssize_t size;
- struct ProcDirEntry *pde = NULL;
- if ((filep == NULL) || (buffer == NULL)) {
- return -EINVAL;
- }
-
- pde = (struct ProcDirEntry *)filep->f_priv;
- size = (ssize_t)WriteProcFile(pde, (void *)buffer, buflen);
- filep->f_pos = pde->pf->fPos;
-
- return size;
-}
-
-off_t VfsProcfsLseek(struct file *filep, off_t offset, int whence)
-{
- loff_t off;
- struct ProcDirEntry *pde = NULL;
- if (filep == NULL) {
- return -EINVAL;
- }
-
- pde = (struct ProcDirEntry *)filep->f_priv;
- if (pde == NULL) {
- return -EINVAL;
- }
-
- off = LseekProcFile(pde, (loff_t)offset, whence);
- filep->f_pos = pde->pf->fPos;
-
- return (off_t)off;
-}
-
-loff_t VfsProcfsLseek64(struct file *filep, loff_t offset, int whence)
-{
- loff_t off;
- struct ProcDirEntry *pde = NULL;
- if (filep == NULL) {
- return -EINVAL;
- }
-
- pde = (struct ProcDirEntry *)filep->f_priv;
- if (pde == NULL) {
- return -EINVAL;
- }
-
- off = LseekProcFile(pde, offset, whence);
- filep->f_pos = pde->pf->fPos;
-
- return off;
-}
-
-int VfsProcfsIoctl(struct file *filep, int cmd, unsigned long arg)
-{
- return -ENOSYS;
-}
-
-int VfsProcfsSync(struct file *filep)
-{
- return -ENOSYS;
-}
-
-int VfsProcfsDup(const struct file *oldp, struct file *newp)
-{
- return -ENOSYS;
-}
-
-int VfsProcfsOpenDir(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir)
-{
- struct ProcDirEntry *pde = NULL;
- char *path = NULL;
- int oflags = O_APPEND;
-
- if (dir == NULL) {
- return -EINVAL;
- }
-
- path = ProcfsChangePath(relpath, PROCFS_MOUNT_POINT_SIZE);
- pde = OpenProcFile(path, oflags);
- if (pde == NULL) {
- return -ENOENT;
- }
- if (S_ISREG(pde->mode)) {
- (void)CloseProcFile(pde);
- return -ENOTDIR;
- }
-
- dir->u.fs_dir = (fs_dir_s)pde;
-
- return 0;
-}
-
-int VfsProcfsCloseDir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- if (dir == NULL) {
- return -EINVAL;
- }
-
- return CloseProcFile((struct ProcDirEntry *)dir->u.fs_dir);
-}
-
-int VfsProcfsReadDir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- int result;
- char *buffer = NULL;
- int buflen = MAX_NAMELEN;
- unsigned int min_size;
- unsigned int dst_name_size;
- struct ProcDirEntry *pde = NULL;
- int i = 0;
- if (dir == NULL) {
- return -EINVAL;
- }
- pde = (struct ProcDirEntry *)dir->u.fs_dir;
-
- buffer = (char *)malloc(sizeof(char) * MAX_NAMELEN);
- if (buffer == NULL) {
- PRINT_ERR("malloc failed\n");
- return -ENOMEM;
- }
-
- while (i < dir->read_cnt) {
- (void)memset_s(buffer, MAX_NAMELEN, 0, MAX_NAMELEN);
-
- result = ReadProcFile(pde, (void *)buffer, buflen);
- if (result != ENOERR) {
- break;
- }
- dst_name_size = sizeof(dir->fd_dir[i].d_name);
- min_size = (dst_name_size < MAX_NAMELEN) ? dst_name_size : MAX_NAMELEN;
- result = strncpy_s(dir->fd_dir[i].d_name, dst_name_size, buffer, min_size);
- if (result != EOK) {
- free(buffer);
- return -ENAMETOOLONG;
- }
- dir->fd_dir[i].d_name[dst_name_size - 1] = '\0';
- dir->fd_position++;
- dir->fd_dir[i].d_off = dir->fd_position;
- dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent);
- i++;
- }
-
- free(buffer);
- return i;
-}
-
-int VfsProcfsRewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- int ret;
- off_t pos = 0;
-
- if (dir == NULL) {
- return -EINVAL;
- }
-
- ret = LseekDirProcFile((struct ProcDirEntry *)dir->u.fs_dir, &pos, SEEK_SET);
- if (ret != ENOERR) {
- return -ret;
- }
-
- return 0;
-}
-
-int VfsProcfsBind(struct inode *blkdriver, const void *data, FAR void **handle, const char *relpath)
-{
- int len, length;
-
- if (relpath == NULL) {
- return -EINVAL;
- }
-
- len = strlen(relpath) + 1;
- length = strlen(PROCFS_MOUNT_POINT) + 1;
- if ((len == length) && !strncmp(relpath, PROCFS_MOUNT_POINT, length)) {
- spin_lock_init(&procfsLock);
- procfsInit = true;
- return ENOERR;
- }
-
- return -EPERM;
-}
-
-int VfsProcfsUnbind(void *handle, struct inode **blkdriver)
-{
- return -EPERM;
-}
-
-int VfsProcfsStatfs(struct inode *mountpt, struct statfs *buf)
-{
- if (buf == NULL) {
- return -EINVAL;
- }
-
- (void)memset_s(buf, sizeof(struct statfs), 0, sizeof(struct statfs));
- buf->f_type = PROCFS_MAGIC;
-
- return OK;
-}
-
-int VfsProcfsUnlink(struct inode *mountpt, const char *relpath)
-{
- struct ProcDirEntry *pde = NULL;
- char *path = NULL;
-
- if (relpath == NULL) {
- return -EINVAL;
- }
-
- path = ProcfsChangePath(relpath, PROCFS_MOUNT_POINT_SIZE);
- pde = ProcFindEntry(path);
- if (pde == NULL) {
- return -ENOENT;
- }
- if (S_ISDIR(pde->mode)) {
- return -EISDIR;
- }
-
- return -EACCES;
-}
-
-int VfsProcfsMkdir(struct inode *mountpt, const char *relpath, mode_t mode)
-{
- struct ProcDirEntry *pde = NULL;
- char *path = NULL;
-
- if (relpath == NULL) {
- return -EINVAL;
- }
-
- path = ProcfsChangePath(relpath, PROCFS_MOUNT_POINT_SIZE);
- pde = ProcFindEntry(path);
- if (pde == NULL) {
- return -ENOENT;
- }
-
- return -EEXIST;
-}
-
-int VfsProcfsRmdir(struct inode *mountpt, const char *relpath)
-{
- struct ProcDirEntry *pde = NULL;
- char *path = NULL;
-
- if (relpath == NULL) {
- return -EINVAL;
- }
-
- path = ProcfsChangePath(relpath, PROCFS_MOUNT_POINT_SIZE);
- pde = ProcFindEntry(path);
- if (pde == NULL) {
- return -ENOENT;
- }
-
- return -EACCES;
-}
-
-int VfsProcfsRename(struct inode *mountpt, const char *oldrelpath, const char *newrelpath)
-{
- return -ENOSYS;
-}
-
-int VfsProcfsStat(struct inode *mountpt, const char *relpath, struct stat *buf)
-{
- int result;
- struct ProcStat statbuf;
- char *path = NULL;
-
- if ((relpath == NULL) || (buf == NULL)) {
- return -EINVAL;
- }
-
- path = ProcfsChangePath(relpath, PROCFS_MOUNT_POINT_SIZE);
- result = ProcStat(path, &statbuf);
- if (result != ENOERR) {
- return -result;
- }
- (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
- buf->st_mode = statbuf.stMode;
-
- return 0;
-}
-
-const struct mountpt_operations procfs_operations = {
- VfsProcfsOpen, /* open */
- VfsProcfsClose, /* close */
- VfsProcfsRead, /* read */
- VfsProcfsWrite, /* write */
- VfsProcfsLseek, /* seek */
- VfsProcfsIoctl, /* ioctl */
- NULL, /* mmap */
- VfsProcfsSync, /* sync */
- VfsProcfsDup, /* dup */
- NULL, /* fstat */
- NULL, /* truncate */
- VfsProcfsOpenDir, /* opendir */
- VfsProcfsCloseDir, /* closedir */
- VfsProcfsReadDir, /* readdir */
- VfsProcfsRewinddir, /* rewinddir */
- VfsProcfsBind, /* bind */
- VfsProcfsUnbind, /* unbind */
- VfsProcfsStatfs, /* statfs */
- NULL, /* virstatfs */
- VfsProcfsUnlink, /* unlink */
- VfsProcfsMkdir, /* mkdir */
- VfsProcfsRmdir, /* rmdir */
- VfsProcfsRename, /* rename */
- VfsProcfsStat, /* stat */
- NULL, /* for utime */
- NULL, /* chattr */
- VfsProcfsLseek64, /* seek64 */
- NULL, /* getlabel */
- NULL, /* fallocate */
- NULL, /* fallocate64 */
- NULL, /* truncate64 */
- NULL, /* fscheck */
- NULL, /* map_pages */
- NULL, /* readpage */
- NULL, /* writepage */
-};
-
-FSMAP_ENTRY(procfs_fsmap, "procfs", procfs_operations, FALSE, FALSE);
-
-#endif
diff --git a/fs/proc/src/proc_file.c b/fs/proc/src/proc_file.c
index 6acffeb3..331be79c 100755
--- a/fs/proc/src/proc_file.c
+++ b/fs/proc/src/proc_file.c
@@ -29,7 +29,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "proc_fs.h"
+#include "proc_file.h"
#include
#include
#include
@@ -57,6 +57,7 @@ static struct ProcDirEntry g_procRootDirEntry = {
.subdir = NULL,
.next = NULL,
.pf = &g_procPf,
+ .type = VNODE_TYPE_DIR,
};
int ProcMatch(unsigned int len, const char *name, struct ProcDirEntry *pn)
@@ -212,7 +213,7 @@ static struct ProcDirEntry *ProcAllocNode(struct ProcDirEntry **parent, const ch
return pn;
}
- if (strlen(lastName) > MAX_NAMELEN) {
+ if (strlen(lastName) > NAME_MAX) {
return pn;
}
@@ -326,6 +327,7 @@ static struct ProcDirEntry *ProcCreateDir(struct ProcDirEntry *parent, const cha
return pn;
}
pn->procFileOps = procFileOps;
+ pn->type = VNODE_TYPE_DIR;
ret = ProcAddNode(parent, pn);
if (ret != 0) {
free(pn->pf);
@@ -348,6 +350,7 @@ static struct ProcDirEntry *ProcCreateFile(struct ProcDirEntry *parent, const ch
}
pn->procFileOps = procFileOps;
+ pn->type = VNODE_TYPE_REG;
ret = ProcAddNode(parent, pn);
if (ret != 0) {
free(pn->pf);
@@ -486,7 +489,8 @@ static int GetNextDir(struct ProcDirEntry *pn, void *buf, size_t len)
*buff = '\0';
return -ENOENT;
}
- int ret = memcpy_s(buff, len, pn->pdirCurrent->name, pn->pdirCurrent->nameLen);
+ int namelen = pn->pdirCurrent->nameLen;
+ int ret = memcpy_s(buff, len, pn->pdirCurrent->name, namelen);
if (ret != EOK) {
return -ENAMETOOLONG;
}
@@ -496,7 +500,7 @@ static int GetNextDir(struct ProcDirEntry *pn, void *buf, size_t len)
return ENOERR;
}
-static int ProcOpen(struct ProcFile *procFile)
+int ProcOpen(struct ProcFile *procFile)
{
if (procFile == NULL) {
return PROC_ERROR;
@@ -567,7 +571,7 @@ struct ProcDirEntry *OpenProcFile(const char *fileName, int flags, ...)
return NULL;
}
if (S_ISREG(pn->mode) && (pn->procFileOps != NULL) && (pn->procFileOps->open != NULL)) {
- (void)pn->procFileOps->open((struct inode *)pn, pn->pf);
+ (void)pn->procFileOps->open((struct Vnode *)pn, pn->pf);
}
if (S_ISDIR(pn->mode)) {
pn->pdirCurrent = pn->subdir;
@@ -584,7 +588,6 @@ int ReadProcFile(struct ProcDirEntry *pde, void *buf, size_t len)
if (pde == NULL) {
return result;
}
-
if (S_ISREG(pde->mode)) {
if ((pde->procFileOps != NULL) && (pde->procFileOps->read != NULL)) {
result = ProcRead(pde, (char *)buf, len);
@@ -592,7 +595,6 @@ int ReadProcFile(struct ProcDirEntry *pde, void *buf, size_t len)
} else if (S_ISDIR(pde->mode)) {
result = GetNextDir(pde, buf, len);
}
-
return result;
}
@@ -672,7 +674,7 @@ int CloseProcFile(struct ProcDirEntry *pde)
}
if ((pde->procFileOps != NULL) && (pde->procFileOps->release != NULL)) {
- result = pde->procFileOps->release((struct inode *)pde, pde->pf);
+ result = pde->procFileOps->release((struct Vnode *)pde, pde->pf);
}
LosBufRelease(pde->pf->sbuf);
pde->pf->sbuf = NULL;
@@ -683,3 +685,7 @@ int CloseProcFile(struct ProcDirEntry *pde)
return result;
}
+struct ProcDirEntry *GetProcRootEntry(void)
+{
+ return &g_procRootDirEntry;
+}
diff --git a/fs/proc/src/proc_shellcmd.c b/fs/proc/src/proc_shellcmd.c
index c5c894f1..2ec4809e 100644
--- a/fs/proc/src/proc_shellcmd.c
+++ b/fs/proc/src/proc_shellcmd.c
@@ -44,7 +44,6 @@
#include "shell.h"
#include "shcmd.h"
#include "proc_file.h"
-#include "inode/inode.h"
#include "dirent.h"
#include "fs/fs.h"
#include "proc_fs.h"
diff --git a/fs/vfs/Makefile b/fs/vfs/Makefile
old mode 100755
new mode 100644
index 1da78b0a..c2758a89
--- a/fs/vfs/Makefile
+++ b/fs/vfs/Makefile
@@ -32,7 +32,10 @@ include $(LITEOSTOPDIR)/config.mk
MODULE_NAME := $(notdir $(shell pwd))
LOCAL_SRCS := \
-$(LITEOSTHIRDPARTY)/NuttX/fs/fs_initialize.c \
+$(LITEOSTOPDIR)/fs/vfs/mount.c \
+$(LITEOSTOPDIR)/fs/vfs/vnode.c \
+$(LITEOSTOPDIR)/fs/vfs/path_cache.c \
+$(LITEOSTOPDIR)/fs/vfs/vnode_hash.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_close.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_dup2.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_dup.c \
@@ -65,14 +68,7 @@ $(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_write.c \
$(wildcard operation/*.c) \
\
$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_files.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_foreachinode.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inodeaddref.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inode.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inodefind.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inoderelease.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inoderemove.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inodereserve.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_inodesearch.c \
\
$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_closedir.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_opendir.c \
@@ -81,15 +77,15 @@ $(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_rewinddir.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_seekdir.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_telldir.c \
\
-$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_foreachmountpoint.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_mount.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_umount.c \
\
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_blockproxy.c \
-$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_closeblockdriver.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_devsyslog.c \
+$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_foreachmountpoint.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_findblockdriver.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_openblockdriver.c \
+$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_closeblockdriver.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_registerblockdriver.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_registerdriver.c \
$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_unregisterblockdriver.c \
@@ -105,7 +101,7 @@ LOCAL_INCLUDE := \
-I $(LITEOSTOPDIR)/fs/vfs/include/multi_partition\
-I $(LITEOSTOPDIR)/fs/vfs/include/operation\
-I $(LITEOSTOPDIR)/fs/include/inode\
- -I $(LITEOSTOPDIR)/syscall
+ -I $(LITEOSTOPDIR)/syscall\
ifeq ($(LOSCFG_FS_FAT), y)
LOCAL_INCLUDE += -I $(LITEOSTHIRDPARTY)/FatFs/source
diff --git a/fs/vfs/bcache/src/bcache.c b/fs/vfs/bcache/src/bcache.c
old mode 100755
new mode 100644
index 0676b2cb..a28fe701
--- a/fs/vfs/bcache/src/bcache.c
+++ b/fs/vfs/bcache/src/bcache.c
@@ -721,9 +721,11 @@ static INT32 BcacheInitCache(OsBcache *bc,
return ENOERR;
}
-static INT32 DrvBread(struct inode *priv, UINT8 *buf, UINT32 len, UINT64 pos)
+static INT32 DrvBread(struct Vnode *priv, UINT8 *buf, UINT32 len, UINT64 pos)
{
- INT32 ret = priv->u.i_bops->read(priv, buf, pos, len);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)priv->data)->ops;
+
+ INT32 ret = bops->read(priv, buf, pos, len);
if (ret != (INT32)len) {
PRINT_ERR("%s failure\n", __FUNCTION__);
return ret;
@@ -731,9 +733,10 @@ static INT32 DrvBread(struct inode *priv, UINT8 *buf, UINT32 len, UINT64 pos)
return ENOERR;
}
-static INT32 DrvBwrite(struct inode *priv, const UINT8 *buf, UINT32 len, UINT64 pos)
+static INT32 DrvBwrite(struct Vnode *priv, const UINT8 *buf, UINT32 len, UINT64 pos)
{
- INT32 ret = priv->u.i_bops->write(priv, buf, pos, len);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)priv->data)->ops;
+ INT32 ret = bops->write(priv, buf, pos, len);
if (ret != (INT32)len) {
PRINT_ERR("%s failure\n", __FUNCTION__);
return ret;
@@ -999,11 +1002,11 @@ VOID BcacheSyncThreadDeinit(const OsBcache *bc)
}
#endif
-OsBcache *BlockCacheInit(struct inode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock,
+OsBcache *BlockCacheInit(struct Vnode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock,
UINT32 blockNum, UINT64 blockCount)
{
OsBcache *bcache = NULL;
- struct inode *blkDriver = devNode;
+ struct Vnode *blkDriver = devNode;
UINT8 *bcacheMem = NULL;
UINT8 *rwBuffer = NULL;
UINT32 blockSize, memSize;
diff --git a/fs/vfs/disk/disk.c b/fs/vfs/disk/disk.c
index 2d6db3a7..c4b7cd9d 100755
--- a/fs/vfs/disk/disk.c
+++ b/fs/vfs/disk/disk.c
@@ -35,7 +35,8 @@
#include "unistd.h"
#include "sys/mount.h"
#include "linux/spinlock.h"
-#include "inode/inode.h"
+
+#include "fs/path_cache.h"
#ifdef LOSCFG_DRIVERS_MMC
#include "mmc/block.h"
@@ -258,7 +259,7 @@ static VOID DiskPartDelFromDisk(los_disk *disk, los_part *part)
disk->part_count--;
}
-static los_part *DiskPartAllocate(struct inode *dev, UINT64 start, UINT64 count)
+static los_part *DiskPartAllocate(struct Vnode *dev, UINT64 start, UINT64 count)
{
UINT32 i;
los_part *part = get_part(0); /* traversing from the beginning of the array */
@@ -307,11 +308,10 @@ static VOID DiskPartRelease(los_part *part)
static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart)
{
CHAR devName[DEV_NAME_BUFF_SIZE];
- struct inode *diskDev = NULL;
- struct inode *partDev = NULL;
+ struct Vnode *diskDev = NULL;
+ struct Vnode *partDev = NULL;
los_part *part = NULL;
INT32 ret;
- struct inode_search_s desc;
if ((disk == NULL) || (disk->disk_status == STAT_UNUSED) ||
(disk->dev == NULL)) {
@@ -331,23 +331,21 @@ static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount,
return VFS_ERROR;
}
- if (register_blockdriver(devName, diskDev->u.i_bops, RWE_RW_RW, diskDev->i_private)) {
+ if (register_blockdriver(devName, ((struct drv_data *)diskDev->data)->ops,
+ RWE_RW_RW, ((struct drv_data *)diskDev->data)->priv)) {
PRINT_ERR("DiskAddPart : register %s fail!\n", devName);
return VFS_ERROR;
}
- SETUP_SEARCH(&desc, devName, false);
- ret = inode_find(&desc);
+ VnodeHold();
+ VnodeLookup(devName, &partDev, 0);
if (ret < 0) {
+ VnodeDrop();
PRINT_ERR("DiskAddPart : find %s fail!\n", devName);
return VFS_ERROR;
}
- partDev = desc.node;
-
- PRINTK("DiskAddPart : register %s ok!\n", devName);
-
part = DiskPartAllocate(partDev, sectorStart, sectorCount);
- inode_release(partDev);
+ VnodeDrop();
if (part == NULL) {
(VOID)unregister_blockdriver(devName);
return VFS_ERROR;
@@ -439,11 +437,13 @@ static INT32 DiskPartitionMemZalloc(size_t boundary, size_t size, CHAR **gptBuf,
return ENOERR;
}
-static INT32 GPTInfoGet(struct inode *blkDrv, CHAR *gptBuf)
+static INT32 GPTInfoGet(struct Vnode *blkDrv, CHAR *gptBuf)
{
INT32 ret;
- ret = blkDrv->u.i_bops->read(blkDrv, (UINT8 *)gptBuf, 1, 1); /* Read the device first sector */
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+
+ ret = bops->read(blkDrv, (UINT8 *)gptBuf, 1, 1); /* Read the device first sector */
if (ret != 1) { /* Read failed */
PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
return -EIO;
@@ -481,12 +481,13 @@ static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const C
return ENOERR;
}
-static INT32 OsGPTPartitionRecognition(struct inode *blkDrv, struct disk_divide_info *info,
+static INT32 OsGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info,
const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount)
{
UINT32 j;
INT32 ret = VFS_ERROR;
UINT64 partitionStart, partitionEnd;
+ struct block_operations *bops = NULL;
for (j = 0; j < PAR_ENTRY_NUM_PER_SECTOR; j++) {
if (!VERITY_AVAILABLE_PAR(&gptBuf[j * TABLE_SIZE])) {
@@ -507,7 +508,10 @@ static INT32 OsGPTPartitionRecognition(struct inode *blkDrv, struct disk_divide_
}
(VOID)memset_s(partitionBuf, info->sector_size, 0, info->sector_size);
- ret = blkDrv->u.i_bops->read(blkDrv, (UINT8 *)partitionBuf, partitionStart, 1);
+
+ bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+
+ ret = bops->read(blkDrv, (UINT8 *)partitionBuf, partitionStart, 1);
if (ret != 1) { /* read failed */
PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
return -EIO;
@@ -522,7 +526,7 @@ static INT32 OsGPTPartitionRecognition(struct inode *blkDrv, struct disk_divide_
return ret;
}
-static INT32 DiskGPTPartitionRecognition(struct inode *blkDrv, struct disk_divide_info *info)
+static INT32 DiskGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
{
CHAR *gptBuf = NULL;
CHAR *partitionBuf = NULL;
@@ -550,7 +554,8 @@ static INT32 DiskGPTPartitionRecognition(struct inode *blkDrv, struct disk_divid
for (i = 0; i < index; i++) {
(VOID)memset_s(gptBuf, info->sector_size, 0, info->sector_size);
- ret = blkDrv->u.i_bops->read(blkDrv, (UINT8 *)gptBuf, TABLE_START_SECTOR + i, 1);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+ ret = bops->read(blkDrv, (UINT8 *)gptBuf, TABLE_START_SECTOR + i, 1);
if (ret != 1) { /* read failed */
PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
ret = -EIO;
@@ -573,12 +578,14 @@ OUT_WITH_MEM:
return ret;
}
-static INT32 OsMBRInfoGet(struct inode *blkDrv, CHAR *mbrBuf)
+static INT32 OsMBRInfoGet(struct Vnode *blkDrv, CHAR *mbrBuf)
{
INT32 ret;
/* read MBR, start from sector 0, length is 1 sector */
- ret = blkDrv->u.i_bops->read(blkDrv, (UINT8 *)mbrBuf, 0, 1);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+
+ ret = bops->read(blkDrv, (UINT8 *)mbrBuf, 0, 1);
if (ret != 1) { /* read failed */
PRINT_ERR("driver read return error: %d\n", ret);
return -EIO;
@@ -592,7 +599,7 @@ static INT32 OsMBRInfoGet(struct inode *blkDrv, CHAR *mbrBuf)
return ENOERR;
}
-static INT32 OsEBRInfoGet(struct inode *blkDrv, const struct disk_divide_info *info,
+static INT32 OsEBRInfoGet(struct Vnode *blkDrv, const struct disk_divide_info *info,
CHAR *ebrBuf, const CHAR *mbrBuf)
{
INT32 ret;
@@ -602,8 +609,8 @@ static INT32 OsEBRInfoGet(struct inode *blkDrv, const struct disk_divide_info *i
return VFS_ERROR;
}
- ret = blkDrv->u.i_bops->read(blkDrv, (UINT8 *)ebrBuf,
- LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]), 1);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+ ret = bops->read(blkDrv, (UINT8 *)ebrBuf, LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]), 1);
if ((ret != 1) || (!VERIFY_FS(ebrBuf))) { /* read failed */
PRINT_ERR("OsEBRInfoGet, verify_fs error, ret = %d\n", ret);
return -EIO;
@@ -640,7 +647,7 @@ static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divid
return extendedFlag;
}
-static INT32 OsLogicalPartitionRecognition(struct inode *blkDrv, struct disk_divide_info *info,
+static INT32 OsLogicalPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info,
UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
{
INT32 ret;
@@ -655,8 +662,8 @@ static INT32 OsLogicalPartitionRecognition(struct inode *blkDrv, struct disk_div
extendedAddress, extendedOffset);
break;
}
- ret = blkDrv->u.i_bops->read(blkDrv, (UINT8 *)ebrBuf,
- extendedAddress + extendedOffset, 1);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+ ret = bops->read(blkDrv, (UINT8 *)ebrBuf, extendedAddress + extendedOffset, 1);
if (ret != 1) { /* read failed */
PRINT_ERR("driver read return error: %d, extendedAddress = %u, extendedOffset = %u\n", ret,
extendedAddress, extendedOffset);
@@ -679,7 +686,7 @@ static INT32 OsLogicalPartitionRecognition(struct inode *blkDrv, struct disk_div
return ebrCount;
}
-static INT32 DiskPartitionRecognition(struct inode *blkDrv, struct disk_divide_info *info)
+static INT32 DiskPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
{
INT32 ret;
INT32 extendedFlag;
@@ -689,7 +696,9 @@ static INT32 DiskPartitionRecognition(struct inode *blkDrv, struct disk_divide_i
CHAR *mbrBuf = NULL;
CHAR *ebrBuf = NULL;
- if ((blkDrv == NULL) || (blkDrv->u.i_bops == NULL) || (blkDrv->u.i_bops->read == NULL)) {
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
+
+ if ((blkDrv == NULL) || (bops == NULL) || (bops->read == NULL)) {
return -EINVAL;
}
@@ -823,8 +832,9 @@ INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count)
}
} else {
#endif
- if ((disk->dev != NULL) && (disk->dev->u.i_bops != NULL) && (disk->dev->u.i_bops->read != NULL)) {
- result = disk->dev->u.i_bops->read(disk->dev, (UINT8 *)buf, sector, count);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
+ if ((disk->dev != NULL) && (bops != NULL) && (bops->read != NULL)) {
+ result = bops->read(disk->dev, (UINT8 *)buf, sector, count);
if (result == (INT32)count) {
result = ENOERR;
}
@@ -882,8 +892,9 @@ INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count)
}
} else {
#endif
- if ((disk->dev != NULL) && (disk->dev->u.i_bops != NULL) && (disk->dev->u.i_bops->write != NULL)) {
- result = disk->dev->u.i_bops->write(disk->dev, (UINT8 *)buf, sector, count);
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
+ if ((disk->dev != NULL) && (bops != NULL) && (bops->write != NULL)) {
+ result = bops->write(disk->dev, (UINT8 *)buf, sector, count);
if (result == (INT32)count) {
result = ENOERR;
}
@@ -928,8 +939,10 @@ INT32 los_disk_ioctl(INT32 drvID, INT32 cmd, VOID *buf)
}
(VOID)memset_s(&info, sizeof(info), 0, sizeof(info));
- if ((disk->dev->u.i_bops == NULL) || (disk->dev->u.i_bops->geometry == NULL) ||
- (disk->dev->u.i_bops->geometry(disk->dev, &info) != 0)) {
+
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
+ if ((bops == NULL) || (bops->geometry == NULL) ||
+ (bops->geometry(disk->dev, &info) != 0)) {
goto ERROR_HANDLE;
}
@@ -1097,8 +1110,10 @@ INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf)
}
(VOID)memset_s(&info, sizeof(info), 0, sizeof(info));
- if ((part->dev->u.i_bops == NULL) || (part->dev->u.i_bops->geometry == NULL) ||
- (part->dev->u.i_bops->geometry(part->dev, &info) != 0)) {
+
+ struct block_operations *bops = (struct block_operations *)((struct drv_data *)part->dev->data)->ops;
+ if ((bops == NULL) || (bops->geometry == NULL) ||
+ (bops->geometry(part->dev, &info) != 0)) {
goto ERROR_HANDLE;
}
@@ -1110,8 +1125,8 @@ INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf)
} else if (cmd == DISK_GET_SECTOR_SIZE) {
*(size_t *)buf = info.geo_sectorsize;
} else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */
- if ((part->dev->u.i_bops->ioctl == NULL) ||
- (part->dev->u.i_bops->ioctl(part->dev, GET_ERASE_BLOCK_SIZE, (UINTPTR)buf) != 0)) {
+ if ((bops->ioctl == NULL) ||
+ (bops->ioctl(part->dev, GET_ERASE_BLOCK_SIZE, (UINTPTR)buf) != 0)) {
goto ERROR_HANDLE;
}
} else {
@@ -1147,7 +1162,7 @@ static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
}
}
-static OsBcache *DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct inode *blkDriver)
+static OsBcache *DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver)
{
#define SECTOR_SIZE 512
@@ -1192,7 +1207,7 @@ static VOID DiskCacheDeinit(los_disk *disk)
#endif
static VOID DiskStructInit(const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo,
- struct inode *blkDriver, los_disk *disk)
+ struct Vnode *blkDriver, los_disk *disk)
{
size_t nameLen;
disk->disk_id = diskID;
@@ -1293,7 +1308,7 @@ static INT32 DiskDeinit(los_disk *disk)
}
static VOID OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk,
- struct geometry *diskInfo, struct inode *blkDriver)
+ struct geometry *diskInfo, struct Vnode *blkDriver)
{
pthread_mutexattr_t attr;
#ifdef LOSCFG_FS_FAT_CACHE
@@ -1312,9 +1327,8 @@ INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
VOID *priv, INT32 diskID, VOID *info)
{
struct geometry diskInfo;
- struct inode *blkDriver = NULL;
+ struct Vnode *blkDriver = NULL;
los_disk *disk = get_disk(diskID);
- struct inode_search_s desc;
INT32 ret;
if ((diskName == NULL) || (disk == NULL) ||
@@ -1327,28 +1341,27 @@ INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
return VFS_ERROR;
}
- SETUP_SEARCH(&desc, diskName, false);
- ret = inode_find(&desc);
+ VnodeHold();
+ ret = VnodeLookup(diskName, &blkDriver, 0);
if (ret < 0) {
+ VnodeDrop();
PRINT_ERR("disk_init : find %s fail!\n", diskName);
ret = ENOENT;
goto DISK_FIND_ERROR;
}
- blkDriver = desc.node;
+ struct block_operations *bops2 = (struct block_operations *)((struct drv_data *)blkDriver->data)->ops;
- if ((blkDriver->u.i_bops == NULL) || (blkDriver->u.i_bops->geometry == NULL) ||
- (blkDriver->u.i_bops->geometry(blkDriver, &diskInfo) != 0)) {
+ if ((bops2 == NULL) || (bops2->geometry == NULL) ||
+ (bops2->geometry(blkDriver, &diskInfo) != 0)) {
goto DISK_BLKDRIVER_ERROR;
}
+
if (diskInfo.geo_sectorsize < DISK_MAX_SECTOR_SIZE) {
goto DISK_BLKDRIVER_ERROR;
}
- PRINTK("disk_init : register %s ok!\n", diskName);
-
OsDiskInitSub(diskName, diskID, disk, &diskInfo, blkDriver);
- inode_release(blkDriver);
-
+ VnodeDrop();
if (DiskDivideAndPartitionRegister(info, disk) != ENOERR) {
(VOID)DiskDeinit(disk);
return VFS_ERROR;
@@ -1364,7 +1377,7 @@ INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
DISK_BLKDRIVER_ERROR:
PRINT_ERR("disk_init : register %s ok but get disk info fail!\n", diskName);
- inode_release(blkDriver);
+ VnodeDrop();
DISK_FIND_ERROR:
(VOID)unregister_blockdriver(diskName);
return VFS_ERROR;
@@ -1479,7 +1492,7 @@ ERROR_HANDLE:
#endif
}
-static los_part *OsPartFind(los_disk *disk, const struct inode *blkDriver)
+static los_part *OsPartFind(los_disk *disk, const struct Vnode *blkDriver)
{
los_part *part = NULL;
@@ -1505,7 +1518,7 @@ EXIT:
return part;
}
-los_part *los_part_find(struct inode *blkDriver)
+los_part *los_part_find(struct Vnode *blkDriver)
{
INT32 i;
los_disk *disk = NULL;
@@ -1532,18 +1545,16 @@ los_part *los_part_find(struct inode *blkDriver)
INT32 los_part_access(const CHAR *dev, mode_t mode)
{
los_part *part = NULL;
- struct inode *node = NULL;
- struct inode_search_s desc;
- (VOID)mode;
+ struct Vnode *node = NULL;
- SETUP_SEARCH(&desc, dev, false);
- if (inode_find(&desc) < 0) {
+ VnodeHold();
+ if (VnodeLookup(dev, &node, 0) < 0) {
+ VnodeDrop();
return VFS_ERROR;
}
- node = desc.node;
part = los_part_find(node);
- inode_release(node);
+ VnodeDrop();
if (part == NULL) {
return VFS_ERROR;
}
@@ -1639,7 +1650,6 @@ VOID show_part(los_part *part)
PRINTK("part no in disk : %u\n", part->part_no_disk);
PRINTK("part no in mbr : %u\n", part->part_no_mbr);
PRINTK("part filesystem : %02X\n", part->filesystem_type);
- PRINTK("part dev name : %s\n", part->dev->i_name);
PRINTK("part sec start : %llu\n", part->sector_start);
PRINTK("part sec count : %llu\n", part->sector_count);
}
diff --git a/fs/vfs/disk/disk_shellcmd.c b/fs/vfs/disk/disk_shellcmd.c
index 90f877ee..d92d6251 100644
--- a/fs/vfs/disk/disk_shellcmd.c
+++ b/fs/vfs/disk/disk_shellcmd.c
@@ -32,41 +32,40 @@
#include "stdio.h"
#include "stdlib.h"
#include "los_config.h"
-
#ifdef LOSCFG_SHELL_CMD_DEBUG
#include "disk.h"
#include "shcmd.h"
#include "shell.h"
+#include "fs/path_cache.h"
INT32 osShellCmdPartInfo(INT32 argc, const CHAR **argv)
{
- struct inode *node = NULL;
+ struct Vnode *node = NULL;
los_part *part = NULL;
const CHAR *str = "/dev";
- struct inode_search_s desc;
int ret;
if ((argc != 1) || (strncmp(argv[0], str, strlen(str)) != 0)) {
PRINTK("Usage :\n");
- PRINTK(" partinfo \n");
- PRINTK(" dev_inodename : the name of dev\n");
+ PRINTK(" partinfo \n");
+ PRINTK(" dev_vnodename : the name of dev\n");
PRINTK("Example:\n");
PRINTK(" partinfo /dev/sdap0 \n");
set_errno(EINVAL);
return -LOS_NOK;
}
- SETUP_SEARCH(&desc, argv[0], false);
- ret = inode_find(&desc);
+ VnodeHold();
+ ret = VnodeLookup(argv[0], &node, 0);
if (ret < 0) {
PRINT_ERR("no part found\n");
+ VnodeDrop();
set_errno(ENOENT);
return -LOS_NOK;
}
- node = desc.node;
part = los_part_find(node);
- inode_release(node);
+ VnodeDrop();
show_part(part);
return LOS_OK;
diff --git a/fs/vfs/include/bcache/bcache.h b/fs/vfs/include/bcache/bcache.h
old mode 100755
new mode 100644
index 22bc1c50..8fc3efd9
--- a/fs/vfs/include/bcache/bcache.h
+++ b/fs/vfs/include/bcache/bcache.h
@@ -35,8 +35,7 @@
#include "pthread.h"
#include "linux/rbtree.h"
#include "los_list.h"
-
-#include "inode/inode.h"
+#include "fs/vnode.h"
#ifdef __cplusplus
#if __cplusplus
@@ -76,12 +75,12 @@ typedef struct {
BOOL allDirty; /* the whole block is dirty */
} OsBcacheBlock;
-typedef INT32 (*BcacheReadFun)(struct inode *, /* private data */
+typedef INT32 (*BcacheReadFun)(struct Vnode *, /* private data */
UINT8 *, /* block buffer */
UINT32, /* number of blocks to read */
UINT64); /* starting block number */
-typedef INT32 (*BcacheWriteFun)(struct inode *, /* private data */
+typedef INT32 (*BcacheWriteFun)(struct Vnode *, /* private data */
const UINT8 *, /* block buffer */
UINT32, /* number of blocks to write */
UINT64); /* starting block number */
@@ -225,7 +224,7 @@ INT32 BlockCacheSync(OsBcache *bc);
*
*
*/
-OsBcache *BlockCacheInit(struct inode *devNode,
+OsBcache *BlockCacheInit(struct Vnode *devNode,
UINT32 sectorSize,
UINT32 sectorPerBlock,
UINT32 blockNum,
diff --git a/fs/vfs/include/driver/driver.h b/fs/vfs/include/driver/driver.h
old mode 100755
new mode 100644
index 274841af..87648eea
--- a/fs/vfs/include/driver/driver.h
+++ b/fs/vfs/include/driver/driver.h
@@ -54,8 +54,6 @@ extern "C" {
* Global Variables
****************************************************************************/
-extern FAR struct inode *g_root_inode;
-
/**
* @ingroup disk
* @brief Set usb mode.
diff --git a/fs/vfs/include/operation/fs_other.h b/fs/vfs/include/operation/fs_other.h
old mode 100755
new mode 100644
index f765a6e9..c67ddf6c
--- a/fs/vfs/include/operation/fs_other.h
+++ b/fs/vfs/include/operation/fs_other.h
@@ -33,6 +33,7 @@
#define _FS_OTHER_H
#include "sys/types.h"
+#include "fs/vnode.h"
#ifdef __cplusplus
#if __cplusplus
@@ -44,7 +45,7 @@ extern void lsfd(void);
extern void set_sd_sync_fn(int (*sync_fn)(int));
-extern struct inode *files_get_openfile(int fd);
+extern struct Vnode *files_get_openfile(int fd);
#define READ_OP 4
#define WRITE_OP 2
@@ -58,6 +59,7 @@ extern struct inode *files_get_openfile(int fd);
mode_t GetUmask(void);
int VfsPermissionCheck(uint fuid, uint fgid, mode_t fileMode, int accMode);
+int VfsVnodePermissionCheck(const struct Vnode *node, int accMode);
#ifdef __cplusplus
#if __cplusplus
diff --git a/fs/vfs/mount.c b/fs/vfs/mount.c
new file mode 100644
index 00000000..28da1086
--- /dev/null
+++ b/fs/vfs/mount.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fs/mount.h"
+#include "los_mux.h"
+#include "fs/vfs_util.h"
+#include "fs/path_cache.h"
+#include "fs/vnode.h"
+#ifdef LOSCFG_DRIVERS_RANDOM
+#include "hisoc/random.h"
+#else
+#include "stdlib.h"
+#endif
+
+static LIST_HEAD *g_mountList = NULL;
+
+struct Mount* MountAlloc(struct Vnode* vnodeBeCovered, struct MountOps* fsop)
+{
+ struct Mount* mnt = (struct Mount*)zalloc(sizeof(struct Mount));
+ if (mnt == NULL) {
+ PRINT_ERR("MountAlloc failed no memory!\n");
+ return NULL;
+ }
+
+ LOS_ListInit(&mnt->activeVnodeList);
+ LOS_ListInit(&mnt->vnodeList);
+
+ mnt->vnodeBeCovered = vnodeBeCovered;
+ vnodeBeCovered->newMount = mnt;
+#ifdef LOSCFG_DRIVERS_RANDOM
+ HiRandomHwInit();
+ (VOID)HiRandomHwGetInteger(&mnt->hashseed);
+ HiRandomHwDeinit();
+#else
+ mnt->hashseed = (uint32_t)random();
+#endif
+ return mnt;
+}
+
+LIST_HEAD* GetMountList()
+{
+ if (g_mountList == NULL) {
+ g_mountList = zalloc(sizeof(LIST_HEAD));
+ if (g_mountList == NULL) {
+ PRINT_ERR("init mount list failed, no memory.");
+ return NULL;
+ }
+ LOS_ListInit(g_mountList);
+ }
+ return g_mountList;
+}
diff --git a/fs/vfs/multi_partition/src/mtd_partition.c b/fs/vfs/multi_partition/src/mtd_partition.c
index 1c92ab0e..d1688c6a 100755
--- a/fs/vfs/multi_partition/src/mtd_partition.c
+++ b/fs/vfs/multi_partition/src/mtd_partition.c
@@ -36,7 +36,6 @@
#include "mtd_list.h"
#include "los_config.h"
#include "los_mux.h"
-#include "inode/inode.h"
#include "mtd_common.h"
@@ -51,8 +50,8 @@ pthread_mutex_t g_mtdPartitionLock = PTHREAD_MUTEX_INITIALIZER;
static VOID YaffsLockInit(VOID) __attribute__((weakref("yaffsfs_OSInitialisation")));
static VOID YaffsLockDeinit(VOID) __attribute__((weakref("yaffsfs_OsDestroy")));
-static INT32 JffsLockInit(VOID) __attribute__((weakref("JffsMutexCreate")));
-static VOID JffsLockDeinit(VOID) __attribute__((weakref("JffsMutexDelete")));
+static INT32 Jffs2LockInit(VOID) __attribute__((weakref("Jffs2MutexCreate")));
+static VOID Jffs2LockDeinit(VOID) __attribute__((weakref("Jffs2MutexDelete")));
partition_param *g_nandPartParam = NULL;
partition_param *g_spinorPartParam = NULL;
@@ -154,8 +153,8 @@ static VOID MtdNorParamAssign(partition_param *spinorParam, const struct MtdDev
static VOID MtdDeinitSpinorParam(VOID)
{
- if (JffsLockDeinit != NULL) {
- JffsLockDeinit();
+ if (Jffs2LockDeinit != NULL) {
+ Jffs2LockDeinit();
}
}
@@ -171,8 +170,8 @@ static partition_param *MtdInitSpinorParam(partition_param *spinorParam)
return NULL;
}
if (spinorParam == NULL) {
- if (JffsLockInit != NULL) {
- if (JffsLockInit() != 0) { /* create jffs2 lock failed */
+ if (Jffs2LockInit != NULL) {
+ if (Jffs2LockInit() != 0) { /* create jffs2 lock failed */
return NULL;
}
}
diff --git a/fs/vfs/multi_partition/src/mtd_shellcmd.c b/fs/vfs/multi_partition/src/mtd_shellcmd.c
index 62202f94..ef72e50b 100755
--- a/fs/vfs/multi_partition/src/mtd_shellcmd.c
+++ b/fs/vfs/multi_partition/src/mtd_shellcmd.c
@@ -29,11 +29,10 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "mtd_partition.h"
#include "stdlib.h"
#include "stdio.h"
#include "los_config.h"
-#include "mtd_partition.h"
-#include "inode/inode.h"
#ifdef LOSCFG_SHELL_CMD_DEBUG
#include "shcmd.h"
diff --git a/fs/vfs/operation/fs_chattr.c b/fs/vfs/operation/fs_chattr.c
old mode 100755
new mode 100644
index a3242a5c..60c6536e
--- a/fs/vfs/operation/fs_chattr.c
+++ b/fs/vfs/operation/fs_chattr.c
@@ -33,70 +33,17 @@
* Included Files
****************************************************************************/
-#include "fs/fs.h"
-
+#include "capability_api.h"
#include "errno.h"
+#include "fs/fs_operation.h"
+#include "fs/fs.h"
#include "string.h"
#include "stdlib.h"
-#include "capability_api.h"
-#include "inode/inode.h"
#include "sys/stat.h"
/****************************************************************************
* Static Functions
****************************************************************************/
-
-/****************************************************************************
- * Name: pseudo_chattr
- *
- * Returned Value:
- * Zero on success; -EPERM on failure:
- *
- ****************************************************************************/
-
-static int pseudo_chattr(struct inode *inode, struct IATTR *attr)
-{
- unsigned int valid;
- mode_t tmp_mode;
- uint c_uid = OsCurrUserGet()->effUserID;
- uint c_gid = OsCurrUserGet()->effGid;
- valid = attr->attr_chg_valid;
- inode_semtake();
-
- tmp_mode = inode->i_mode;
- if (valid & CHG_UID) {
- if (((c_uid != inode->i_uid) || (attr->attr_chg_uid != inode->i_uid)) && (!IsCapPermit(CAP_CHOWN))) {
- inode_semgive();
- return -EPERM;
- } else {
- inode->i_uid = attr->attr_chg_uid;
- }
- }
-
- if (valid & CHG_GID) {
- if (((c_gid != inode->i_gid) || (attr->attr_chg_gid != inode->i_gid)) && (!IsCapPermit(CAP_CHOWN))) {
- inode_semgive();
- return -EPERM;
- } else {
- inode->i_gid = attr->attr_chg_gid;
- }
- }
-
- if (valid & CHG_MODE) {
- if (!IsCapPermit(CAP_FOWNER) && (c_uid != inode->i_uid)) {
- inode_semgive();
- return -EPERM;
- } else {
- attr->attr_chg_mode &= ~S_IFMT; /* delete file type */
- tmp_mode &= S_IFMT;
- tmp_mode = attr->attr_chg_mode | tmp_mode; /* add old file type */
- }
- }
- inode->i_mode = tmp_mode;
- inode_semgive();
- return 0;
-}
-
/****************************************************************************
* Name: chattr
*
@@ -107,95 +54,42 @@ static int pseudo_chattr(struct inode *inode, struct IATTR *attr)
int chattr(const char *pathname, struct IATTR *attr)
{
- struct inode *inode = NULL;
- const char *relpath = NULL;
- int error;
+ struct Vnode *vnode = NULL;
int ret;
- char *fullpath = NULL;
- char *relativepath = NULL;
- int dirfd = AT_FDCWD;
- struct stat statBuff;
- struct inode_search_s desc;
if (pathname == NULL || attr == NULL) {
set_errno(EINVAL);
return VFS_ERROR;
}
- ret = get_path_from_fd(dirfd, &relativepath); /* Get absolute path by dirfd */
- if (ret < 0) {
- error = -ret;
- goto errout;
+ VnodeHold();
+ ret = VnodeLookup(pathname, &vnode, 0);
+ if (ret != LOS_OK) {
+ goto errout_with_lock;
}
- ret = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
- if (relativepath) {
- free(relativepath);
- }
+ /* The way we handle the stat depends on the type of vnode that we
+ * are dealing with.
+ */
- if (ret < 0) {
- error = -ret;
- goto errout;
- }
-
- ret = stat(fullpath, &statBuff);
- if (ret < 0) {
- free(fullpath);
- return VFS_ERROR;
- }
-
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
- error = EACCES;
- free(fullpath);
- goto errout;
- }
- inode = desc.node;
- relpath = desc.relpath;
-
- if (inode) {
-#ifndef CONFIG_DISABLE_MOUNTPOINT /* Check inode is not mount and has i_ops or like /dev dir */
- if ((!INODE_IS_MOUNTPT(inode)) && ((inode->u.i_ops != NULL) || S_ISDIR(statBuff.st_mode))) {
- ret = pseudo_chattr(inode, attr);
- if (ret < 0) {
- error = -ret;
- goto err_free_inode;
- }
- } else if (INODE_IS_MOUNTPT(inode) && (inode->u.i_mops->chattr)) /* Inode is match the relpath */
- {
- if (!strlen(relpath)) {
- error = EEXIST;
- goto err_free_inode;
- }
-
- ret = inode->u.i_mops->chattr(inode, relpath, attr);
- if (ret < 0) {
- error = -ret;
- goto err_free_inode;
- }
- } else {
- error = ENOSYS;
- goto err_free_inode;
- }
- inode_release(inode); /* Release inode */
-#else
- error = EEXIST;
- goto err_free_inode;
-#endif
+ if (vnode->vop != NULL && vnode->vop->Chattr != NULL) {
+ ret = vnode->vop->Chattr(vnode, attr);
} else {
- error = ENXIO;
- free(fullpath);
+ ret = -ENOSYS;
+ }
+ VnodeDrop();
+
+ if (ret < 0) {
goto errout;
}
- free(fullpath);
return OK;
- err_free_inode:
- inode_release(inode);
- free(fullpath);
- errout:
- set_errno(error);
+ /* Failure conditions always set the errno appropriately */
+
+errout_with_lock:
+ VnodeDrop();
+errout:
+ set_errno(-ret);
return VFS_ERROR;
}
diff --git a/fs/vfs/operation/fs_check.c b/fs/vfs/operation/fs_check.c
old mode 100755
new mode 100644
index 95c5a872..17c6e48d
--- a/fs/vfs/operation/fs_check.c
+++ b/fs/vfs/operation/fs_check.c
@@ -42,93 +42,52 @@
#include "sys/stat.h"
#include "sys/prctl.h"
#include "fs/dirent_fs.h"
-#include "inode/inode.h"
+#include "fs/vnode.h"
/****************************************************************************
* Name: fscheck
****************************************************************************/
-FAR int fscheck(FAR const char *path)
+int fscheck(const char *path)
{
- FAR struct inode *inode = NULL;
- FAR struct fs_dirent_s *dir = NULL;
- FAR const char *relpath = NULL;
int ret;
- char *fullpath = NULL;
- char *fullpath_bak = NULL;
+ struct Vnode *vnode = NULL;
+ struct fs_dirent_s *dir = NULL;
- ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
- if (ret < 0) {
- ret = -ret;
+ /* Find the node matching the path. */
+ VnodeHold();
+ ret = VnodeLookup(path, &vnode, 0);
+ if (ret != OK) {
+ VnodeDrop();
goto errout;
}
- fullpath_bak = fullpath;
- inode_semtake();
-
- if (!fullpath || *fullpath == 0) {
- ret = EINVAL;
- goto errout_with_semaphore;
- } else {
- /* We don't know what to do with relative pathes */
-
- if (*fullpath != '/') {
- ret = ENOTDIR;
- goto errout_with_semaphore;
- }
-
- /* Find the node matching the path. */
-
- inode = inode_search((FAR
- const char **)&fullpath, (FAR struct inode **)NULL, (FAR struct inode **)NULL, &relpath);
- }
-
- if (!inode) {
- /* 'path' is not a directory.*/
-
- ret = ENOTDIR;
- goto errout_with_semaphore;
- }
-
- dir = (FAR struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s));
+ dir = (struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s));
if (!dir) {
/* Insufficient memory to complete the operation.*/
-
- ret = ENOMEM;
- goto errout_with_semaphore;
+ ret = -ENOMEM;
+ VnodeDrop();
+ goto errout;
}
-#ifndef CONFIG_DISABLE_MOUNTPOINT
- if (INODE_IS_MOUNTPT(inode)) {
- if (!inode->u.i_mops || !inode->u.i_mops->fscheck) {
- ret = ENOSYS;
- goto errout_with_direntry;
- }
-
- /* Perform the fscheck() operation */
-
- ret = inode->u.i_mops->fscheck(inode, relpath, dir);
+ if (vnode->vop && vnode->vop->Fscheck) {
+ ret = vnode->vop->Fscheck(vnode, dir);
if (ret != OK) {
- ret = -ret;
+ VnodeDrop();
goto errout_with_direntry;
}
- } else
-#endif
- {
- ret = EINVAL;
+ } else {
+ ret = -ENOSYS;
+ VnodeDrop();
goto errout_with_direntry;
}
- inode_semgive();
+ VnodeDrop();
+
free(dir);
- free(fullpath_bak);
return 0;
errout_with_direntry:
free(dir);
-
-errout_with_semaphore:
- inode_semgive();
- free(fullpath_bak);
errout:
- set_errno(ret);
- return -1;
+ set_errno(-ret);
+ return VFS_ERROR;
}
diff --git a/fs/vfs/operation/fs_fallocate.c b/fs/vfs/operation/fs_fallocate.c
old mode 100755
new mode 100644
index e4eca2de..34b017c5
--- a/fs/vfs/operation/fs_fallocate.c
+++ b/fs/vfs/operation/fs_fallocate.c
@@ -33,58 +33,51 @@
* Included Files
****************************************************************************/
-#include "vfs_config.h"
-#include "sys/types.h"
#include "assert.h"
#include "errno.h"
#include "fcntl.h"
+#include "fs/fs.h"
+#include "sys/types.h"
#include "sched.h"
#include "unistd.h"
-
-#include "inode/inode.h"
+#include "vfs_config.h"
/****************************************************************************
* Name: file_fallocate
****************************************************************************/
-static ssize_t file_fallocate(FAR struct file *filep, int mode, off_t offset, off_t len)
+static ssize_t file_fallocate(struct file *filep, int mode, off_t offset, off_t len)
{
- FAR struct inode *inode = NULL;
int ret;
- int err;
if (len <= 0) {
- err = EINVAL;
+ ret = EINVAL;
goto errout;
}
/* Was this file opened for write access? */
if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY) {
- err = EACCES;
+ ret = -EACCES;
goto errout;
}
- /* Is a driver registered? Does it support the fallocate method? */
-
- inode = filep->f_inode;
- if (!inode || !inode->u.i_mops || !inode->u.i_mops->fallocate) {
- err = EBADF;
+ if (!filep->ops || !filep->ops->fallocate) {
+ ret = -EBADF;
goto errout;
}
/* Yes, then let the driver perform the fallocate */
- ret = inode->u.i_mops->fallocate(filep, mode, offset, len);
+ ret = filep->ops->fallocate(filep, mode, offset, len);
if (ret < 0) {
- err = -ret;
goto errout;
}
return ret;
errout:
- set_errno(err);
+ set_errno(-ret);
return VFS_ERROR;
}
@@ -112,7 +105,7 @@ errout:
int fallocate(int fd, int mode, off_t offset, off_t len)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
- FAR struct file *filep = NULL;
+ struct file *filep = NULL;
#endif
/* Did we get a valid file descriptor? */
diff --git a/fs/vfs/operation/fs_fallocate64.c b/fs/vfs/operation/fs_fallocate64.c
old mode 100755
new mode 100644
index 063254aa..57cf6fbc
--- a/fs/vfs/operation/fs_fallocate64.c
+++ b/fs/vfs/operation/fs_fallocate64.c
@@ -33,24 +33,21 @@
* Included Files
****************************************************************************/
-#include "vfs_config.h"
-#include "sys/types.h"
#include "assert.h"
#include "errno.h"
#include "fcntl.h"
+#include "fs/fs.h"
#include "sched.h"
+#include "sys/types.h"
#include "unistd.h"
-
-#include "inode/inode.h"
-
+#include "vfs_config.h"
/****************************************************************************
* Name: file_fallocate
****************************************************************************/
-ssize_t file_fallocate64(FAR struct file *filep, int mode, off64_t offset, off64_t len)
+ssize_t file_fallocate64(struct file *filep, int mode, off64_t offset, off64_t len)
{
- FAR struct inode *inode = NULL;
int ret;
int err;
@@ -67,16 +64,14 @@ ssize_t file_fallocate64(FAR struct file *filep, int mode, off64_t offset, off64
}
/* Is a driver registered? Does it support the fallocate method? */
-
- inode = filep->f_inode;
- if (!inode || !inode->u.i_mops || !inode->u.i_mops->fallocate64) {
+ if (!filep->ops || !filep->ops->fallocate64) {
err = EBADF;
goto errout;
}
/* Yes, then let the driver perform the fallocate */
- ret = inode->u.i_mops->fallocate64(filep, mode, offset, len);
+ ret = filep->ops->fallocate64(filep, mode, offset, len);
if (ret < 0) {
err = -ret;
goto errout;
@@ -113,7 +108,7 @@ errout:
int fallocate64(int fd, int mode, off64_t offset, off64_t len)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
- FAR struct file *filep = NULL;
+ struct file *filep = NULL;
#endif
/* Did we get a valid file descriptor? */
diff --git a/fs/vfs/operation/fs_file_mapping.c b/fs/vfs/operation/fs_file_mapping.c
old mode 100755
new mode 100644
index 0b85c81a..a8f6b1f7
--- a/fs/vfs/operation/fs_file_mapping.c
+++ b/fs/vfs/operation/fs_file_mapping.c
@@ -29,9 +29,9 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "fs/file.h"
#include "fs/fs.h"
#include "fs/fs_operation.h"
-#include "fs_other.h"
#include "unistd.h"
#include "los_mux.h"
#include "los_list.h"
@@ -54,121 +54,7 @@ uint init_file_mapping()
return ret;
}
-static struct page_mapping *find_mapping_nolock(const char *fullpath)
-{
- struct file_map *fmap = NULL;
-
- LOS_DL_LIST_FOR_EACH_ENTRY(fmap, &g_file_mapping.head, struct file_map, head) {
- if (!strcmp(fmap->owner, fullpath)) {
- return &fmap->mapping;
- }
- }
-
- return NULL;
-}
-
-void add_mapping(struct file *filep, const char *fullpath)
-{
- void *tmp = NULL;
- struct file_map *fmap = NULL;
- int fmap_len = sizeof(struct file_map);
- int path_len;
- struct page_mapping *mapping = NULL;
- status_t retval;
-
- if (filep == NULL || fullpath == NULL) {
- return;
- }
-
- (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
-
- path_len = strlen(fullpath) + 1;
- mapping = find_mapping_nolock(fullpath);
- if (mapping) {
- LOS_AtomicInc(&mapping->ref);
- filep->f_mapping = mapping;
- mapping->host = filep;
- (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
- return;
- }
-
- (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
-
- fmap = (struct file_map *)LOS_MemAlloc(m_aucSysMem0, fmap_len);
-
- /* page-cache as a optimization feature, just return when out of memory */
-
- if (!fmap) {
- PRINT_WARN("%s-%d: Mem alloc failed. fmap length(%d)\n",
- __FUNCTION__, __LINE__, fmap_len);
- return;
- }
- tmp = LOS_MemAlloc(m_aucSysMem0, path_len);
-
- /* page-cache as a optimization feature, just return when out of memory */
-
- if (!tmp) {
- PRINT_WARN("%s-%d: Mem alloc failed. fmap length(%d), fmap(%p), path length(%d)\n",
- __FUNCTION__, __LINE__, fmap_len, fmap, path_len);
- LOS_MemFree(m_aucSysMem0, fmap);
- return;
- }
-
- (void)memset_s(fmap, fmap_len, 0, fmap_len);
- fmap->owner = tmp;
- LOS_AtomicSet(&fmap->mapping.ref, 1);
- (void)strcpy_s(fmap->owner, path_len, fullpath);
-
- LOS_ListInit(&fmap->mapping.page_list);
- LOS_SpinInit(&fmap->mapping.list_lock);
- retval = LOS_MuxInit(&fmap->mapping.mux_lock, NULL);
- if (retval != LOS_OK) {
- PRINT_ERR("%s %d, Create mutex for mapping.mux_lock failed, status: %d\n", __FUNCTION__, __LINE__, retval);
- }
- (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
- LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);
- (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
-
- filep->f_mapping = &fmap->mapping;
- filep->f_mapping->host = filep;
-
- return;
-}
-
-struct page_mapping *find_mapping(const char *fullpath)
-{
- struct page_mapping *mapping = NULL;
-
- if (fullpath == NULL) {
- return NULL;
- }
-
- (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
-
- mapping = find_mapping_nolock(fullpath);
- if (mapping) {
- LOS_AtomicInc(&mapping->ref);
- }
-
- (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
-
- return mapping;
-}
-
-void dec_mapping(struct page_mapping *mapping)
-{
- if (mapping == NULL) {
- return;
- }
-
- (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
- if (LOS_AtomicRead(&mapping->ref) > 0) {
- LOS_AtomicDec(&mapping->ref);
- }
- (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
-}
-
-void clear_file_mapping_nolock(const struct page_mapping *mapping)
+static void clear_file_mapping(const struct page_mapping *mapping)
{
unsigned int i = 3; /* file start fd */
struct file *filp = NULL;
@@ -182,72 +68,119 @@ void clear_file_mapping_nolock(const struct page_mapping *mapping)
}
}
-int remove_mapping_nolock(const char *fullpath, const struct file *ex_filp)
+static struct page_mapping *find_mapping_nolock(const char *fullpath)
{
- int fd;
- struct file *filp = NULL;
+ char *map_name = NULL;
+ struct file_map *fmap = NULL;
+ int name_len = strlen(fullpath);
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(fmap, &g_file_mapping.head, struct file_map, head) {
+ map_name = fmap->rename ? fmap->rename: fmap->owner;
+ if ((name_len == fmap->name_len) && !strcmp(map_name, fullpath)) {
+ return &fmap->mapping;
+ }
+ }
+
+ return NULL;
+}
+
+void add_mapping(struct file *filep, const char *fullpath)
+{
+ int path_len;
+ status_t retval;
struct file_map *fmap = NULL;
struct page_mapping *mapping = NULL;
- struct inode *node = NULL;
- if (fullpath == NULL) {
+ if (filep == NULL || fullpath == NULL) {
+ return;
+ }
+
+ (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
+ mapping = find_mapping_nolock(fullpath);
+ if (mapping) {
+ LOS_AtomicInc(&mapping->ref);
+ filep->f_mapping = mapping;
+ mapping->host = filep;
+ goto out;
+ }
+
+ path_len = strlen(fullpath);
+
+ fmap = (struct file_map *)zalloc(sizeof(struct file_map) + path_len + 1);
+ if (!fmap) {
+ PRINT_WARN("%s %d, Mem alloc failed.\n", __FUNCTION__, __LINE__);
+ goto out;
+ }
+
+ LOS_AtomicSet(&fmap->mapping.ref, 1);
+
+ fmap->name_len = path_len;
+ (void)strcpy_s(fmap->owner, path_len + 1, fullpath);
+
+ LOS_ListInit(&fmap->mapping.page_list);
+ LOS_SpinInit(&fmap->mapping.list_lock);
+ retval = LOS_MuxInit(&fmap->mapping.mux_lock, NULL);
+ if (retval != LOS_OK) {
+ PRINT_ERR("%s %d, Create mutex for mapping.mux_lock failed, status: %d\n", __FUNCTION__, __LINE__, retval);
+ goto out;
+ }
+
+ LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);
+
+ filep->f_mapping = &fmap->mapping;
+ filep->f_mapping->host = filep;
+
+out:
+ (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
+}
+
+int remove_mapping_nolock(struct page_mapping *mapping)
+{
+ struct file_map *fmap = NULL;
+
+ if (mapping == NULL) {
set_errno(EINVAL);
return EINVAL;
}
- /* file start fd */
-
- for (fd = 3; fd < CONFIG_NFILE_DESCRIPTORS; fd++) {
- node = files_get_openfile(fd);
- if (node == NULL) {
- continue;
- }
- filp = &tg_filelist.fl_files[fd];
-
- /* ex_filp NULL: do not exclude any file, just matching the file name ; ex_filp not NULL: exclude it.
- * filp != ex_filp includes the two scenarios.
- */
-
- if (filp != ex_filp) {
- if (filp->f_path == NULL) {
- continue;
- }
- if ((strcmp(filp->f_path, fullpath) == 0)) {
- PRINT_WARN("%s is open(fd=%d), remove cache failed.\n", fullpath, fd);
- set_errno(EBUSY);
- return EBUSY;
- }
- }
- }
-
- (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
-
- mapping = find_mapping_nolock(fullpath);
- if (!mapping) {
- /* this scenario is a normal case */
-
- goto out;
- }
-
(VOID)LOS_MuxDestroy(&mapping->mux_lock);
- clear_file_mapping_nolock(mapping);
+ clear_file_mapping(mapping);
OsFileCacheRemove(mapping);
- fmap = LOS_DL_LIST_ENTRY(mapping,
- struct file_map, mapping);
+ fmap = LOS_DL_LIST_ENTRY(mapping, struct file_map, mapping);
LOS_ListDelete(&fmap->head);
- LOS_MemFree(m_aucSysMem0, fmap->owner);
+ if (fmap->rename) {
+ LOS_MemFree(m_aucSysMem0, fmap->rename);
+ }
LOS_MemFree(m_aucSysMem0, fmap);
-out:
- (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
-
return OK;
}
-int remove_mapping(const char *fullpath, const struct file *ex_filp)
+void dec_mapping_nolock(struct page_mapping *mapping)
+{
+ if (mapping == NULL) {
+ return;
+ }
+
+ (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
+ if (LOS_AtomicRead(&mapping->ref) > 0) {
+ LOS_AtomicDec(&mapping->ref);
+ }
+
+ if (LOS_AtomicRead(&mapping->ref) <= 0) {
+ remove_mapping_nolock(mapping);
+ } else {
+ OsFileCacheFlush(mapping);
+ }
+
+ (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
+}
+
+int remove_mapping(const char *fullpath)
{
int ret;
struct filelist *f_list = NULL;
+ struct page_mapping *mapping = NULL;
f_list = &tg_filelist;
ret = sem_wait(&f_list->fl_sem);
@@ -256,7 +189,14 @@ int remove_mapping(const char *fullpath, const struct file *ex_filp)
return VFS_ERROR;
}
- ret = remove_mapping_nolock(fullpath, ex_filp);
+ (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
+
+ mapping = find_mapping_nolock(fullpath);
+ if (mapping) {
+ ret = remove_mapping_nolock(mapping);
+ }
+
+ (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
(void)sem_post(&f_list->fl_sem);
return OK;
@@ -265,7 +205,7 @@ int remove_mapping(const char *fullpath, const struct file *ex_filp)
void rename_mapping(const char *src_path, const char *dst_path)
{
int ret;
- void *tmp = NULL;
+ char *tmp = NULL;
int path_len;
struct file_map *fmap = NULL;
struct page_mapping *mapping = NULL;
@@ -274,7 +214,7 @@ void rename_mapping(const char *src_path, const char *dst_path)
return;
}
- path_len = strlen(dst_path) + 1;
+ path_len = strlen(dst_path);
/* protect the whole list in case of this node been deleted just after we found it */
@@ -282,34 +222,58 @@ void rename_mapping(const char *src_path, const char *dst_path)
mapping = find_mapping_nolock(src_path);
if (!mapping) {
- /* this scenario is a normal case */
-
goto out;
}
- fmap = LOS_DL_LIST_ENTRY(mapping,
- struct file_map, mapping);
+ fmap = LOS_DL_LIST_ENTRY(mapping, struct file_map, mapping);
- tmp = LOS_MemAlloc(m_aucSysMem0, path_len);
+ tmp = LOS_MemAlloc(m_aucSysMem0, path_len + 1);
if (!tmp) {
- /* in this extremly low-memory situation, un-referenced page caches can be recycled by Pagecache LRU */
-
PRINT_ERR("%s-%d: Mem alloc failed, path length(%d)\n", __FUNCTION__, __LINE__, path_len);
goto out;
}
- ret = strcpy_s(tmp, path_len, dst_path);
+ ret = strncpy_s(tmp, path_len, dst_path, strlen(dst_path));
if (ret != 0) {
(VOID)LOS_MemFree(m_aucSysMem0, tmp);
goto out;
}
- /* whole list is locked, so we don't protect this node here */
-
- (VOID)LOS_MemFree(m_aucSysMem0, fmap->owner);
- fmap->owner = tmp;
+ tmp[path_len] = '\0';
+ fmap->rename = tmp;
out:
(VOID)LOS_MuxUnlock(&g_file_mapping.lock);
- return;
}
+int update_file_path(char *old_path, char *new_path)
+{
+ unsigned int i = 3;
+ struct filelist *f_list = NULL;
+ struct file *filp = NULL;
+ int ret;
+
+ f_list = &tg_filelist;
+ ret = sem_wait(&f_list->fl_sem);
+ if (ret < 0) {
+ PRINTK("sem_wait error, ret=%d\n", ret);
+ return VFS_ERROR;
+ }
+
+ (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);
+ while (i < CONFIG_NFILE_DESCRIPTORS) {
+ i++;
+ if (!get_bit(i)) {
+ continue;
+ }
+ filp = &tg_filelist.fl_files[i];
+ if (filp->f_path == NULL || strcmp(filp->f_path, old_path)) {
+ continue;
+ }
+ int len = strlen(new_path) + 1;
+ filp->f_path = zalloc(len);
+ strncpy_s(filp->f_path, strlen(new_path) + 1, new_path, len);
+ }
+ (VOID)LOS_MuxUnlock(&g_file_mapping.lock);
+ (void)sem_post(&f_list->fl_sem);
+ return LOS_OK;
+}
diff --git a/fs/vfs/operation/fs_getlabel.c b/fs/vfs/operation/fs_getlabel.c
old mode 100755
new mode 100644
index 6c375c90..b36ad195
--- a/fs/vfs/operation/fs_getlabel.c
+++ b/fs/vfs/operation/fs_getlabel.c
@@ -39,7 +39,6 @@
#include "errno.h"
#include "fs/fs.h"
-#include "inode/inode.h"
#include "stdlib.h"
#include "string.h"
@@ -95,7 +94,8 @@
int getlabel(const char *target, char *label)
{
- FAR struct inode *mountpt_inode = NULL;
+#ifdef VFS_IMPL_LATER
+ struct inode *mountpt_inode = NULL;
int errcode = OK;
int status;
char *fullpath = NULL;
@@ -132,8 +132,8 @@ int getlabel(const char *target, char *label)
goto errout_with_release;
}
- if (mountpt_inode->u.i_mops && mountpt_inode->u.i_mops->getlabel) {
- status = mountpt_inode->u.i_mops->getlabel(mountpt_inode->i_private, label);
+ if (mountpt_inode->u.i_mops) {
+ status = LOS_OK;
if (status < 0) {
/* The inode is unhappy with the blkdrvr for some reason */
@@ -157,4 +157,6 @@ errout_with_fullpath:
errout:
set_errno(errcode);
return VFS_ERROR;
+#endif
+ return 0;
}
diff --git a/fs/vfs/operation/fs_init.c b/fs/vfs/operation/fs_init.c
old mode 100755
new mode 100644
index 22e3ffcb..5d5bf57d
--- a/fs/vfs/operation/fs_init.c
+++ b/fs/vfs/operation/fs_init.c
@@ -29,22 +29,23 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "los_printf.h"
-#include "fs/fs.h"
-#include "inode/inode.h"
-#include "unistd.h"
-#include "fcntl.h"
-#include "sys/statfs.h"
-#include "linux/spinlock.h"
#include "disk_pri.h"
+#include "fcntl.h"
+#include "fs/fs.h"
+#include "fs/fs_operation.h"
+#include "linux/spinlock.h"
+#include "los_printf.h"
+#include "fs/mount.h"
+#include "fs/path_cache.h"
+#include "sys/statfs.h"
+#include "unistd.h"
+#include "fs/vfs_util.h"
+#include "fs/vnode.h"
void los_vfs_init(void)
{
- int err;
uint retval;
static bool g_vfs_init = false;
- struct inode *dev = NULL;
-
if (g_vfs_init) {
return;
}
@@ -55,18 +56,29 @@ void los_vfs_init(void)
#endif
files_initialize();
files_initlist(&tg_filelist);
- fs_initialize();
- if ((err = inode_reserve("/", &g_root_inode)) < 0) {
- PRINT_ERR("los_vfs_init failed error %d\n", -err);
- return;
- }
- g_root_inode->i_mode |= S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
- if ((err = inode_reserve("/dev", &dev)) < 0) {
- PRINT_ERR("los_vfs_init failed error %d\n", -err);
+ retval = VnodesInit();
+ if (retval != LOS_OK) {
+ PRINT_ERR("los_vfs_init VnodeInit failed error %d\n", retval);
+ return;
+ }
+
+ retval = PathCacheInit();
+ if (retval != LOS_OK) {
+ PRINT_ERR("los_vfs_init PathCacheInit failed error %d\n", retval);
+ return;
+ }
+ retval = VnodeHashInit();
+ if (retval != LOS_OK) {
+ PRINT_ERR("los_vfs_init VnodeHashInit failed error %d\n", retval);
+ return;
+ }
+
+ retval = VnodeDevInit();
+ if (retval != LOS_OK) {
+ PRINT_ERR("los_vfs_init VnodeDevInit failed error %d\n", retval);
return;
}
- dev->i_mode |= S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
retval = init_file_mapping();
if (retval != LOS_OK) {
diff --git a/fs/vfs/operation/fs_other.c b/fs/vfs/operation/fs_other.c
index 27315672..feded8ab 100755
--- a/fs/vfs/operation/fs_other.c
+++ b/fs/vfs/operation/fs_other.c
@@ -38,15 +38,13 @@
#include "sys/select.h"
#include "sys/stat.h"
#include "sys/prctl.h"
-#include "fs/dirent_fs.h"
#include "fs/fd_table.h"
#include "fs/fs.h"
#include "linux/spinlock.h"
#include "los_process_pri.h"
#include "los_task_pri.h"
-#include "inode/inode.h"
#include "capability_api.h"
-
+#include "fs/vnode.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@@ -54,7 +52,6 @@ extern "C" {
#endif /* __cplusplus */
#define MAX_DIR_ENT 1024
-
int fstat(int fd, struct stat *buf)
{
struct file *filep = NULL;
@@ -84,7 +81,14 @@ int lstat(const char *path, struct stat *buffer)
return stat(path, buffer);
}
-int VfsPermissionCheck(uint fuid, uint fgid, mode_t fileMode, int accMode)
+int VfsVnodePermissionCheck(const struct Vnode *node, int accMode)
+{
+ uint fuid = node->uid;
+ uint fgid = node->gid;
+ uint fileMode = node->mode;
+ return VfsPermissionCheck(fuid, fgid, fileMode, accMode);
+}
+int VfsPermissionCheck(uint fuid, uint fgid, uint fileMode, int accMode)
{
uint uid = OsCurrUserGet()->effUserID;
mode_t tmpMode = fileMode;
@@ -153,6 +157,7 @@ int chdir(const char *path)
char *fullpath_bak = NULL;
struct stat statBuff;
+
if (!path) {
set_errno(EFAULT);
return -1;
@@ -283,23 +288,6 @@ int access(const char *path, int amode)
return OK;
}
-bool IS_MOUNTPT(const char *dev)
-{
- struct inode *node = NULL;
- bool ret = 0;
- struct inode_search_s desc;
-
- SETUP_SEARCH(&desc, dev, false);
- if (inode_find(&desc) < 0) {
- return 0;
- }
- node = desc.node;
-
- ret = INODE_IS_MOUNTPT(node);
- inode_release(node);
- return ret;
-}
-
static struct dirent **scandir_get_file_list(const char *dir, int *num, int(*filter)(const struct dirent *))
{
DIR *od = NULL;
@@ -525,7 +513,6 @@ static void PrintFileInfo(const struct stat *statInfo, const char *name)
PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag,
str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size, statInfo->st_uid, statInfo->st_gid, name);
}
-
void ls(const char *pathname)
{
struct stat64 stat64_info;
@@ -562,7 +549,6 @@ void ls(const char *pathname)
}
/* list all directory and file*/
-
d = opendir(path);
if (d == NULL) {
perror("ls error");
@@ -585,13 +571,13 @@ void ls(const char *pathname)
}
fullpath_bak = fullpath;
-
if (stat64(fullpath, &stat64_info) == 0) {
PrintFileInfo64(&stat64_info, pdirent->d_name);
} else if (stat(fullpath, &stat_info) == 0) {
PrintFileInfo(&stat_info, pdirent->d_name);
- } else
+ } else {
PRINTK("BAD file: %s\n", pdirent->d_name);
+ }
free(fullpath_bak);
}
} while (1);
@@ -644,10 +630,10 @@ char *realpath(const char *path, char *resolved_path)
void lsfd(void)
{
- FAR struct filelist *f_list = NULL;
+ struct filelist *f_list = NULL;
unsigned int i = 3; /* file start fd */
int ret;
- FAR struct inode *node = NULL;
+ struct Vnode *node = NULL;
f_list = &tg_filelist;
diff --git a/fs/vfs/operation/fs_readv.c b/fs/vfs/operation/fs_readv.c
old mode 100755
new mode 100644
index 573fbf92..f3786cdf
--- a/fs/vfs/operation/fs_readv.c
+++ b/fs/vfs/operation/fs_readv.c
@@ -35,8 +35,9 @@
#include "string.h"
#include "stdlib.h"
#include "fs/fs.h"
-#include "inode/inode.h"
#include "user_copy.h"
+#include "stdio.h"
+#include "limits.h"
static char *pread_buf_and_check(int fd, const struct iovec *iov, int iovcnt, ssize_t *totalbytesread, off_t *offset)
{
diff --git a/fs/vfs/operation/fs_utime.c b/fs/vfs/operation/fs_utime.c
old mode 100755
new mode 100644
index e30c982f..fce8c694
--- a/fs/vfs/operation/fs_utime.c
+++ b/fs/vfs/operation/fs_utime.c
@@ -36,138 +36,86 @@
#include "errno.h"
#include "vfs_config.h"
#include "sys/stat.h"
-#include "inode/inode.h"
+#include "fs/vnode.h"
#include "string.h"
#include "stdlib.h"
#include "utime.h"
+#include "fs_other.h"
/****************************************************************************
* Global Functions
****************************************************************************/
-/****************************************************************************
- * Name: utime
- *
- * Returned Value:
- * Zero on success; -1 on failure with errno set:
- *
- ****************************************************************************/
-
-static int utime_pseudo(FAR struct inode *pinode, FAR const struct utimbuf *ptimes)
+int utime(const char *path, const struct utimbuf *ptimes)
{
- return ENOSYS;
-}
-
-int utime(FAR const char *path, FAR const struct utimbuf *ptimes)
-{
- FAR struct inode *pinode = NULL;
- const char *relpath = NULL;
- int ret = OK;
+ int ret;
char *fullpath = NULL;
+ struct Vnode *vnode = NULL;
time_t cur_sec;
- struct tm *set_tm = NULL;
- struct inode_search_s desc;
+ struct IATTR attr = {0};
/* Sanity checks */
+
if (path == NULL) {
- ret = EINVAL;
+ ret = -EINVAL;
goto errout;
}
if (!path[0]) {
- ret = ENOENT;
+ ret = -ENOENT;
goto errout;
}
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
if (ret < 0) {
- ret = -ret;
goto errout;
}
- /* Check for the fake root directory (which has no inode) */
-
- if (strcmp(fullpath, "/") == 0) {
- ret = EACCES;
+ /* Get the vnode for this file */
+ VnodeHold();
+ ret = VnodeLookup(fullpath, &vnode, 0);
+ if (ret != LOS_OK) {
+ VnodeDrop();
goto errout_with_path;
}
- /* Get an inode for this file */
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
- /* This name does not refer to a psudeo-inode and there is no
- * mountpoint that includes in this path.
- */
-
- ret = EACCES;
- goto errout_with_path;
- }
- pinode = desc.node;
-
- /* The way we handle the utime depends on the type of inode that we
- * are dealing with.
- */
-
-#ifndef CONFIG_DISABLE_MOUNTPOINT
- if (INODE_IS_MOUNTPT(pinode)) {
- /* The node is a file system mointpoint. Verify that the mountpoint
- * supports the utime() method.
- */
-
- if (pinode->u.i_mops && pinode->u.i_mops->utime) {
- if (ptimes == NULL) {
- /*get current seconds*/
-
- cur_sec = time(NULL);
- set_tm = localtime(&cur_sec); /* transform seconds to struct tm */
- } else {
- set_tm = gmtime(&ptimes->modtime); /* transform seconds to struct tm */
- }
-
- /* Perform the utime() operation */
-
- if (set_tm == NULL) {
- ret = EINVAL;
- goto errout_with_inode;
- }
- ret = pinode->u.i_mops->utime(pinode, relpath, set_tm);
+ if (vnode->vop && vnode->vop->Chattr) {
+ if (ptimes == NULL) {
+ /* get current seconds */
+ cur_sec = time(NULL);
+ attr.attr_chg_atime = cur_sec;
+ attr.attr_chg_mtime = cur_sec;
} else {
- ret = ENOSYS;
- goto errout_with_inode;
+ attr.attr_chg_atime = ptimes->actime;
+ attr.attr_chg_mtime = ptimes->modtime;
}
- } else
-#endif
- {
- /* The node is part of the root pseudo file system */
-
- ret = utime_pseudo(pinode, ptimes);
- goto errout_with_inode;
- }
-
- /* Check if the stat operation was successful */
-
- if (ret < 0) {
- ret = -ret;
- goto errout_with_inode;
+ attr.attr_chg_valid = CHG_ATIME | CHG_MTIME;
+ ret = vnode->vop->Chattr(vnode, &attr);
+ if (ret != OK) {
+ VnodeDrop();
+ goto errout_with_path;
+ }
+ } else {
+ ret = -ENOSYS;
+ VnodeDrop();
+ goto errout_with_path;
}
+ VnodeDrop();
/* Successfully stat'ed the file */
-
- inode_release(pinode);
free(fullpath);
+
return OK;
/* Failure conditions always set the errno appropriately */
-errout_with_inode:
- inode_release(pinode);
errout_with_path:
free(fullpath);
errout:
+
if (ret != 0) {
- set_errno(ret);
+ set_errno(-ret);
}
return VFS_ERROR;
}
diff --git a/fs/vfs/operation/fs_virstatfs.c b/fs/vfs/operation/fs_virstatfs.c
old mode 100755
new mode 100644
index 8bc41dca..e9363e4d
--- a/fs/vfs/operation/fs_virstatfs.c
+++ b/fs/vfs/operation/fs_virstatfs.c
@@ -40,7 +40,6 @@
#include "string.h"
#include "sched.h"
-#include "inode/inode.h"
#include "errno.h"
#include "stdlib.h"
/****************************************************************************
@@ -52,10 +51,10 @@
****************************************************************************/
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
-int virstatfs(FAR const char *path, FAR struct statfs *buf)
+int virstatfs(const char *path, struct statfs *buf)
{
- FAR struct inode *inode;
- FAR const char *relpath = NULL;
+#ifdef VFS_IMPL_LATER
+ struct inode *inode = NULL;
int ret = OK;
char *fullpath = NULL;
struct inode_search_s desc;
@@ -95,7 +94,6 @@ int virstatfs(FAR const char *path, FAR struct statfs *buf)
goto errout;
}
inode = desc.node;
- relpath = desc.relpath;
/* The way we handle the statfs depends on the type of inode that we
* are dealing with.
@@ -108,11 +106,11 @@ int virstatfs(FAR const char *path, FAR struct statfs *buf)
* supports the statfs() method
*/
- if (inode->u.i_mops && inode->u.i_mops->virstatfs)
+ if (inode->u.i_mops)
{
/* Perform the statfs() operation */
- ret = inode->u.i_mops->virstatfs(inode, relpath, buf);
+ ret = LOS_OK;
}
else
{
@@ -149,5 +147,7 @@ errout_with_inode:
errout:
set_errno(ret);
return VFS_ERROR;
+#endif
+ return 0;
}
#endif
diff --git a/fs/vfs/operation/fs_writev.c b/fs/vfs/operation/fs_writev.c
old mode 100755
new mode 100644
index 49c0b911..cfd70f99
--- a/fs/vfs/operation/fs_writev.c
+++ b/fs/vfs/operation/fs_writev.c
@@ -35,8 +35,8 @@
#include "string.h"
#include "stdlib.h"
#include "fs/fs.h"
-#include "inode/inode.h"
#include "user_copy.h"
+#include "limits.h"
static int iov_trans_to_buf(char *buf, ssize_t totallen, const struct iovec *iov, int iovcnt)
{
diff --git a/fs/vfs/path_cache.c b/fs/vfs/path_cache.c
new file mode 100755
index 00000000..6242f7dc
--- /dev/null
+++ b/fs/vfs/path_cache.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fs/path_cache.h"
+#include "los_config.h"
+#include "stdlib.h"
+#include "limits.h"
+#include "fs/vfs_util.h"
+#include "fs/vnode.h"
+
+#define PATH_CACHE_HASH_MASK (LOSCFG_MAX_PATH_CACHE_SIZE - 1)
+LIST_HEAD g_pathCacheHashEntrys[LOSCFG_MAX_PATH_CACHE_SIZE];
+
+int PathCacheInit(void)
+{
+ for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) {
+ LOS_ListInit(&g_pathCacheHashEntrys[i]);
+ }
+ return LOS_OK;
+}
+
+void PathCacheDump(void)
+{
+ PRINTK("-------->pathCache dump in\n");
+ for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) {
+ struct PathCache *nc = NULL;
+ LIST_HEAD *nhead = &g_pathCacheHashEntrys[i];
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(nc, nhead, struct PathCache, hashEntry) {
+ PRINTK(" pathCache dump hash %d item %s %p %d\n", i, nc->name, nc->parentVnode, nc->nameLen);
+ }
+ }
+ PRINTK("-------->pathCache dump out\n");
+}
+
+void PathCacheMemoryDump(void)
+{
+ int pathCacheNum = 0;
+ for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) {
+ LIST_HEAD *dhead = &g_pathCacheHashEntrys[i];
+ struct PathCache *dent = NULL;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(dent, dhead, struct PathCache, hashEntry) {
+ pathCacheNum++;
+ }
+ }
+ PRINTK("pathCache number = %d\n", pathCacheNum);
+ PRINTK("pathCache memory size = %d(B)\n", pathCacheNum * sizeof(struct PathCache));
+}
+
+static uint32_t NameHash(const char *name, int len, struct Vnode *dvp)
+{
+ uint32_t hash;
+ hash = fnv_32_buf(name, len, FNV1_32_INIT);
+ hash = fnv_32_buf(&dvp, sizeof(dvp), hash);
+ return hash;
+}
+
+static void PathCacheInsert(struct Vnode *parent, struct PathCache *cache, const char* name, int len)
+{
+ int hash = NameHash(name, len, parent) & PATH_CACHE_HASH_MASK;
+ LOS_ListAdd(&g_pathCacheHashEntrys[hash], &cache->hashEntry);
+}
+
+struct PathCache *PathCacheAlloc(struct Vnode *parent, struct Vnode *vnode, const char *name, uint8_t len)
+{
+ struct PathCache *nc = NULL;
+ size_t pathCacheSize;
+
+ if (name == NULL || len > NAME_MAX || parent == NULL || vnode == NULL) {
+ return NULL;
+ }
+ pathCacheSize = sizeof(struct PathCache) + len + 1;
+
+ nc = (struct PathCache*)zalloc(pathCacheSize);
+ if (nc == NULL) {
+ PRINT_ERR("pathCache alloc failed, no memory!\n");
+ return NULL;
+ }
+
+ (void)strncpy_s(nc->name, pathCacheSize, name, len);
+
+ nc->parentVnode = parent;
+ nc->nameLen = len;
+ nc->childVnode = vnode;
+
+ LOS_ListAdd((&(parent->childPathCaches)), (&(nc->childEntry)));
+ LOS_ListAdd((&(vnode->parentPathCaches)), (&(nc->parentEntry)));
+
+ PathCacheInsert(parent, nc, name, len);
+
+ return nc;
+}
+
+int PathCacheFree(struct PathCache *nc)
+{
+ if (nc == NULL) {
+ PRINT_ERR("pathCache free: invalid pathCache\n");
+ return -ENOENT;
+ }
+
+ LOS_ListDelete(&nc->hashEntry);
+ LOS_ListDelete(&nc->parentEntry);
+ LOS_ListDelete(&nc->childEntry);
+ free(nc->name);
+ free(nc);
+
+ return LOS_OK;
+}
+
+/* alloc an empty node and awlays add it to path_cache.cache */
+int PathCacheAllocDummy(struct Vnode *parent, struct Vnode **vnode, const char *name, uint8_t len)
+{
+ int ret;
+ struct PathCache *dt = NULL;
+
+ ret = VnodeAlloc(NULL, vnode);
+ if (ret != LOS_OK) {
+ PRINT_ERR("pathCache alloc vnode %s failed\n", name);
+ return -ENOENT;
+ }
+
+ dt = PathCacheAlloc(parent, *vnode, name, len);
+ if (dt == NULL) {
+ PRINT_ERR("pathCache alloc pathCache %s failed\n", name);
+ VnodeFree(*vnode);
+ *vnode = NULL;
+ return -ENOENT;
+ }
+
+ return LOS_OK;
+}
+
+int PathCacheLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode)
+{
+ struct PathCache *nc = NULL;
+ int hash = NameHash(name, len, parent) & PATH_CACHE_HASH_MASK;
+ LIST_HEAD *dhead = &g_pathCacheHashEntrys[hash];
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(nc, dhead, struct PathCache, hashEntry) {
+ if (nc->parentVnode == parent && nc->nameLen == len && !strncmp(nc->name, name, len)) {
+ *vnode = nc->childVnode;
+ return LOS_OK;
+ }
+ }
+ return -ENOENT;
+}
+
+static void FreeChildPathCache(struct Vnode *vnode)
+{
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(vnode->childPathCaches), struct PathCache, childEntry) {
+ PathCacheFree(item);
+ }
+}
+
+static void FreeParentPathCache(struct Vnode *vnode)
+{
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(vnode->parentPathCaches), struct PathCache, parentEntry) {
+ PathCacheFree(item);
+ }
+}
+
+void VnodePathCacheFree(struct Vnode *vnode)
+{
+ if (vnode == NULL) {
+ return;
+ }
+ FreeParentPathCache(vnode);
+ FreeChildPathCache(vnode);
+}
diff --git a/fs/vfs/vfs_cmd/vfs_shellcmd.c b/fs/vfs/vfs_cmd/vfs_shellcmd.c
old mode 100755
new mode 100644
index d8a4caf8..261913e9
--- a/fs/vfs/vfs_cmd/vfs_shellcmd.c
+++ b/fs/vfs/vfs_cmd/vfs_shellcmd.c
@@ -38,7 +38,6 @@
#include "shell.h"
#include "fs/fs.h"
#include "sys/stat.h"
-#include "inode/inode.h"
#include "stdlib.h"
#include "unistd.h"
#include "fs_other.h"
@@ -54,6 +53,7 @@
#include "los_process_pri.h"
#include
+#include "fs/fs_operation.h"
typedef enum
{
@@ -241,12 +241,9 @@ out:
int osShellCmdCat(int argc, const char **argv)
{
char *fullpath = NULL;
- const char *filename = NULL;
- char *fullpath_bak = NULL;
- FAR const char *relpath = NULL;
int ret;
unsigned int ca_task;
- FAR struct inode *inode = NULL;
+ struct Vnode *vnode = NULL;
TSK_INIT_PARAM_S init_param;
char *shell_working_directory = OsShellGetWorkingDirtectory();
if (shell_working_directory == NULL)
@@ -256,34 +253,32 @@ int osShellCmdCat(int argc, const char **argv)
ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1);
- filename = argv[0];
- ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
+ ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath);
ERROR_OUT_IF(ret < 0, set_err(-ret, "cat error"), return -1);
- inode_semtake();
- fullpath_bak = fullpath;
- inode = inode_search((FAR const char **)&fullpath, (FAR struct inode **)NULL, (FAR struct inode **)NULL, &relpath);
- if (inode == NULL)
- {
- set_errno(ENOENT);
- perror("cat error");
- inode_semgive();
- free(fullpath_bak);
- return -1;
- }
- if (INODE_IS_BLOCK(inode) || INODE_IS_DRIVER(inode))
- {
- set_errno(EPERM);
- perror("cat error");
- inode_semgive();
- free(fullpath_bak);
- return -1;
- }
- inode_semgive();
+ VnodeHold();
+ ret = VnodeLookup(fullpath, &vnode, O_RDONLY);
+ if (ret != LOS_OK)
+ {
+ set_errno(-ret);
+ perror("cat error");
+ VnodeDrop();
+ free(fullpath);
+ return -1;
+ }
+ if (vnode->type != VNODE_TYPE_REG)
+ {
+ set_errno(EINVAL);
+ perror("cat error");
+ VnodeDrop();
+ free(fullpath);
+ return -1;
+ }
+ VnodeDrop();
(void)memset_s(&init_param, sizeof(init_param), 0, sizeof(TSK_INIT_PARAM_S));
init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)osShellCmdDoCatShow;
init_param.usTaskPrio = CAT_TASK_PRIORITY;
- init_param.auwArgs[0] = (UINTPTR)fullpath_bak;
+ init_param.auwArgs[0] = (UINTPTR)fullpath;
init_param.uwStackSize = CAT_TASK_STACK_SIZE;
init_param.pcName = "shellcmd_cat";
init_param.uwResved = LOS_TASK_STATUS_DETACHED | OS_TASK_FLAG_SPECIFIES_PROCESS;
@@ -291,6 +286,11 @@ int osShellCmdCat(int argc, const char **argv)
ret = (int)LOS_TaskCreate(&ca_task, &init_param);
+ if (ret != LOS_OK)
+ {
+ free(fullpath);
+ }
+
return ret;
}
@@ -479,7 +479,6 @@ int osShellCmdUmount(int argc, const char **argv)
target_path = fullpath;
cmp_num = strlen(fullpath);
ret = strncmp(work_path, target_path, cmp_num);
-
if (ret == 0)
{
work_path += cmp_num;
@@ -1338,12 +1337,11 @@ int osShellCmdRmdir(int argc, const char **argv)
{
ret = rmdir(fullpath);
}
- free(fullpath);
-
if (ret == -1)
{
- perror("rmdir error");
+ PRINTK("rmdir %s failed. Error: %s.\n", fullpath, strerror(errno));
}
+ free(fullpath);
return 0;
}
diff --git a/fs/vfs/vnode.c b/fs/vfs/vnode.c
new file mode 100755
index 00000000..a2cf6575
--- /dev/null
+++ b/fs/vfs/vnode.c
@@ -0,0 +1,655 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "los_mux.h"
+#include "fs/vfs_util.h"
+#include "fs/vnode.h"
+#include "fs/dirent_fs.h"
+#include "fs_other.h"
+
+LIST_HEAD g_vnodeFreeList; /* free vnodes list */
+LIST_HEAD g_vnodeVirtualList; /* dev vnodes list */
+LIST_HEAD g_vnodeCurrList; /* inuse vnodes list */
+static int g_freeVnodeSize = 0; /* system free vnodes size */
+static int g_totalVnodeSize = 0; /* total vnode size */
+
+static LosMux g_vnodeMux;
+static struct Vnode *g_rootVnode = NULL;
+static struct VnodeOps g_devfsOps;
+
+#define ENTRY_TO_VNODE(ptr) LOS_DL_LIST_ENTRY(ptr, struct Vnode, actFreeEntry)
+#define VNODE_LRU_COUNT 10
+#define DEV_VNODE_MODE 0755
+
+int VnodesInit(void)
+{
+ int retval = LOS_MuxInit(&g_vnodeMux, NULL);
+ if (retval != LOS_OK) {
+ PRINT_ERR("Create mutex for vnode fail, status: %d", retval);
+ return retval;
+ }
+
+ LOS_ListInit(&g_vnodeFreeList);
+ LOS_ListInit(&g_vnodeVirtualList);
+ LOS_ListInit(&g_vnodeCurrList);
+ retval = VnodeAlloc(NULL, &g_rootVnode);
+ if (retval != LOS_OK) {
+ PRINT_ERR("VnodeInit failed error %d\n", retval);
+ return retval;
+ }
+ g_rootVnode->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
+ g_rootVnode->type = VNODE_TYPE_DIR;
+
+ return LOS_OK;
+}
+
+static struct Vnode *GetFromFreeList(void)
+{
+ if (g_freeVnodeSize <= 0) {
+ return NULL;
+ }
+ struct Vnode *vnode = NULL;
+
+ if (LOS_ListEmpty(&g_vnodeFreeList)) {
+ PRINT_ERR("get vnode from free list failed, list empty but g_freeVnodeSize = %d!\n", g_freeVnodeSize);
+ g_freeVnodeSize = 0;
+ return NULL;
+ }
+
+ vnode = ENTRY_TO_VNODE(LOS_DL_LIST_FIRST(&g_vnodeFreeList));
+ LOS_ListDelete(&vnode->actFreeEntry);
+ g_freeVnodeSize--;
+ return vnode;
+}
+
+struct Vnode *VnodeReclaimLru(void)
+{
+ struct Vnode *item = NULL;
+ struct Vnode *nextItem = NULL;
+ int releaseCount = 0;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeCurrList, struct Vnode, actFreeEntry) {
+ if ((item->useCount > 0) ||
+ (item->flag & VNODE_FLAG_MOUNT_NEW) ||
+ (item->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
+ continue;
+ }
+
+ if (VnodeFree(item) == LOS_OK) {
+ releaseCount++;
+ }
+ if (releaseCount >= VNODE_LRU_COUNT) {
+ break;
+ }
+ }
+
+ if (releaseCount == 0) {
+ PRINT_ERR("VnodeAlloc failed, vnode size hit max but can't reclaim anymore!\n");
+ return NULL;
+ }
+
+ item = GetFromFreeList();
+ if (item == NULL) {
+ PRINT_ERR("VnodeAlloc failed, reclaim and get from free list failed!\n");
+ }
+ return item;
+}
+
+int VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode)
+{
+ struct Vnode* vnode = NULL;
+
+ VnodeHold();
+ vnode = GetFromFreeList();
+ if ((vnode == NULL) && g_totalVnodeSize < LOSCFG_MAX_VNODE_SIZE) {
+ vnode = (struct Vnode*)zalloc(sizeof(struct Vnode));
+ g_totalVnodeSize++;
+ }
+
+ if (vnode == NULL) {
+ vnode = VnodeReclaimLru();
+ }
+
+ if (vnode == NULL) {
+ *newVnode = NULL;
+ VnodeDrop();
+ return -ENOMEM;
+ }
+
+ vnode->type = VNODE_TYPE_UNKNOWN;
+ LOS_ListInit((&(vnode->parentPathCaches)));
+ LOS_ListInit((&(vnode->childPathCaches)));
+ LOS_ListInit((&(vnode->hashEntry)));
+ LOS_ListInit((&(vnode->actFreeEntry)));
+
+ if (vop == NULL) {
+ LOS_ListAdd(&g_vnodeVirtualList, &(vnode->actFreeEntry));
+ vnode->vop = &g_devfsOps;
+ } else {
+ LOS_ListTailInsert(&g_vnodeCurrList, &(vnode->actFreeEntry));
+ vnode->vop = vop;
+ }
+ VnodeDrop();
+
+ *newVnode = vnode;
+
+ return LOS_OK;
+}
+
+int VnodeFree(struct Vnode *vnode)
+{
+ if (vnode == NULL) {
+ return LOS_OK;
+ }
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+
+ VnodeHold();
+ if (vnode->useCount > 0) {
+ VnodeDrop();
+ return -EBUSY;
+ }
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vnode->childPathCaches, struct PathCache, childEntry) {
+ PathCacheFree(item);
+ }
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vnode->parentPathCaches, struct PathCache, parentEntry) {
+ PathCacheFree(item);
+ }
+
+ LOS_ListDelete(&(vnode->hashEntry));
+
+ if (vnode->vop->Reclaim) {
+ vnode->vop->Reclaim(vnode);
+ }
+
+ LOS_ListDelete(&vnode->actFreeEntry);
+ memset_s(vnode, sizeof(struct Vnode), 0, sizeof(struct Vnode));
+ LOS_ListAdd(&g_vnodeFreeList, &vnode->actFreeEntry);
+
+ g_freeVnodeSize++;
+ VnodeDrop();
+
+ return LOS_OK;
+}
+
+int VnodeFreeIter(struct Vnode *vnode)
+{
+ struct Vnode *vp = NULL;
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+ int ret;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vnode->childPathCaches, struct PathCache, childEntry) {
+ vp = item->childVnode;
+ if (vp == NULL) {
+ continue;
+ }
+ ret = VnodeFreeIter(vp);
+ if (ret != LOS_OK) {
+ return ret;
+ }
+ }
+ return VnodeFree(vnode);
+}
+
+int VnodeFreeAll(struct Mount *mnt)
+{
+ struct Vnode *vp = NULL;
+ struct Vnode *mountptVnode = mnt->vnodeCovered;
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+ int ret;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &mountptVnode->childPathCaches, struct PathCache, childEntry) {
+ vp = item->childVnode;
+ if (vp == NULL) {
+ continue;
+ }
+ ret = VnodeFreeIter(vp);
+ if (ret != LOS_OK) {
+ return ret;
+ }
+ }
+ return 0;
+}
+
+BOOL VnodeInUseIter(struct Vnode *vnode)
+{
+ struct Vnode *vp = NULL;
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+ if (vnode->useCount > 0) {
+ return TRUE;
+ }
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vnode->childPathCaches, struct PathCache, childEntry) {
+ vp = item->childVnode;
+ if (vp == NULL) {
+ continue;
+ }
+ if (VnodeInUseIter(vp) == TRUE) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+int VnodeHold()
+{
+ int ret = LOS_MuxLock(&g_vnodeMux, LOS_WAIT_FOREVER);
+ if (ret != LOS_OK) {
+ PRINT_ERR("VnodeHold lock failed !\n");
+ }
+ return ret;
+}
+
+int VnodeDrop()
+{
+ int ret = LOS_MuxUnlock(&g_vnodeMux);
+ if (ret != LOS_OK) {
+ PRINT_ERR("VnodeDrop unlock failed !\n");
+ }
+ return ret;
+}
+
+static char *NextName(char *pos, uint8_t *len)
+{
+ char *name = NULL;
+ if (*pos == '\0') {
+ return NULL;
+ }
+ while (*pos != 0 && *pos == '/') {
+ pos++;
+ }
+ if (*pos == '\0') {
+ return NULL;
+ }
+ name = (char *)pos;
+ while (*pos != '\0' && *pos != '/') {
+ pos++;
+ }
+ *len = pos - name;
+ return name;
+}
+
+static int PreProcess(const char *originPath, struct Vnode **startVnode, char **path)
+{
+ int ret;
+ char *absolutePath = NULL;
+
+ ret = vfs_normalize_path(NULL, originPath, &absolutePath);
+ if (ret == LOS_OK) {
+ *startVnode = g_rootVnode;
+ *path = absolutePath;
+ }
+
+ return ret;
+}
+
+static struct Vnode *ConvertVnodeIfMounted(struct Vnode *vnode)
+{
+ if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_NEW)) {
+ return vnode;
+ }
+ return vnode->newMount->vnodeCovered;
+}
+
+static void RefreshLRU(struct Vnode *vnode)
+{
+ if (vnode == NULL || (vnode->type != VNODE_TYPE_REG && vnode->type != VNODE_TYPE_DIR) ||
+ vnode->vop == &g_devfsOps || vnode->vop == NULL) {
+ return;
+ }
+ LOS_ListDelete(&(vnode->actFreeEntry));
+ LOS_ListTailInsert(&g_vnodeCurrList, &(vnode->actFreeEntry));
+}
+
+static int ProcessVirtualVnode(struct Vnode *parent, uint32_t flags, struct Vnode **vnode)
+{
+ int ret = -ENOENT;
+ if (flags & V_CREATE) {
+ // only create /dev/ vnode
+ ret = VnodeAlloc(NULL, vnode);
+ }
+ if (ret == LOS_OK) {
+ (*vnode)->parent = parent;
+ }
+ return ret;
+}
+
+static int Step(char **currentDir, struct Vnode **currentVnode, uint32_t flags)
+{
+ int ret;
+ uint8_t len = 0;
+ struct Vnode *nextVnode = NULL;
+ char *nextDir = NULL;
+
+ if ((*currentVnode)->type != VNODE_TYPE_DIR) {
+ return -ENOTDIR;
+ }
+ nextDir = NextName(*currentDir, &len);
+ if (nextDir == NULL) {
+ *currentDir = NULL;
+ return LOS_OK;
+ }
+
+ ret = PathCacheLookup(*currentVnode, nextDir, len, &nextVnode);
+ if (ret == LOS_OK) {
+ goto STEP_FINISH;
+ }
+
+ if (flags & V_DUMMY) {
+ ret = ProcessVirtualVnode(*currentVnode, flags, &nextVnode);
+ } else {
+ if ((*currentVnode)->vop != NULL && (*currentVnode)->vop->Lookup != NULL) {
+ ret = (*currentVnode)->vop->Lookup(*currentVnode, nextDir, len, &nextVnode);
+ } else {
+ ret = -ENOSYS;
+ }
+ }
+
+ if (ret == LOS_OK) {
+ (void)PathCacheAlloc((*currentVnode), nextVnode, nextDir, len);
+ }
+
+STEP_FINISH:
+ nextVnode = ConvertVnodeIfMounted(nextVnode);
+ RefreshLRU(nextVnode);
+
+ *currentDir = nextDir + len;
+ if (ret == LOS_OK) {
+ *currentVnode = nextVnode;
+ }
+
+ return ret;
+}
+
+int VnodeLookup(const char *path, struct Vnode **result, uint32_t flags)
+{
+ struct Vnode *startVnode = NULL;
+ char *normalizedPath = NULL;
+
+
+ int ret = PreProcess(path, &startVnode, &normalizedPath);
+ if (ret != LOS_OK) {
+ PRINT_ERR("[VFS]lookup failed, invalid path=%s err = %d\n", path, ret);
+ goto OUT_FREE_PATH;
+ }
+
+ if (normalizedPath[0] == '/' && normalizedPath[1] == '\0') {
+ *result = g_rootVnode;
+ free(normalizedPath);
+ return LOS_OK;
+ }
+
+ char *currentDir = normalizedPath;
+ struct Vnode *currentVnode = startVnode;
+
+ while (currentDir && *currentDir != '\0') {
+ ret = Step(¤tDir, ¤tVnode, flags);
+ if (*currentDir == '\0') {
+ // return target or parent vnode as result
+ *result = currentVnode;
+ } else if (VfsVnodePermissionCheck(currentVnode, EXEC_OP)) {
+ ret = -EACCES;
+ goto OUT_FREE_PATH;
+ }
+
+ if (ret != LOS_OK) {
+ // no such file, lookup failed
+ goto OUT_FREE_PATH;
+ }
+ }
+
+OUT_FREE_PATH:
+ if (normalizedPath) {
+ free(normalizedPath);
+ }
+
+ return ret;
+}
+
+static void ChangeRootInternal(struct Vnode *rootOld, char *dirname)
+{
+ int ret;
+ struct Mount *mnt = NULL;
+ char *name = NULL;
+ struct Vnode *node = NULL;
+ struct Vnode *nodeInFs = NULL;
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &rootOld->childPathCaches, struct PathCache, childEntry) {
+ name = item->name;
+ node = item->childVnode;
+
+ if (strcmp(name, dirname)) {
+ continue;
+ }
+ PathCacheFree(item);
+
+ ret = VnodeLookup(dirname, &nodeInFs, 0);
+ if (ret) {
+ PRINTK("%s-%d %s NOT exist in rootfs\n", __FUNCTION__, __LINE__, dirname);
+ break;
+ }
+
+ mnt = node->newMount;
+ mnt->vnodeBeCovered = nodeInFs;
+
+ nodeInFs->newMount = mnt;
+ nodeInFs->flag |= VNODE_FLAG_MOUNT_NEW;
+
+ break;
+ }
+}
+
+void ChangeRoot(struct Vnode *rootNew)
+{
+ struct Vnode *rootOld = g_rootVnode;
+ g_rootVnode = rootNew;
+ ChangeRootInternal(rootOld, "proc");
+ ChangeRootInternal(rootOld, "dev");
+}
+
+static int VnodeReaddir(struct Vnode *vp, struct fs_dirent_s *dir)
+{
+ int result;
+ int cnt = 0;
+ off_t i = 0;
+ off_t idx;
+ unsigned int dstNameSize;
+
+ struct PathCache *item = NULL;
+ struct PathCache *nextItem = NULL;
+
+ if (dir == NULL) {
+ return -EINVAL;
+ }
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vp->childPathCaches, struct PathCache, childEntry) {
+ if (i < dir->fd_position) {
+ i++;
+ continue;
+ }
+
+ idx = i - dir->fd_position;
+
+ dstNameSize = sizeof(dir->fd_dir[idx].d_name);
+ result = strncpy_s(dir->fd_dir[idx].d_name, dstNameSize, item->name, item->nameLen);
+ if (result != EOK) {
+ return -ENAMETOOLONG;
+ }
+ dir->fd_dir[idx].d_off = i;
+ dir->fd_dir[idx].d_reclen = (uint16_t)sizeof(struct dirent);
+
+ i++;
+ if (++cnt >= dir->read_cnt) {
+ break;
+ }
+ }
+
+ dir->fd_position = i;
+
+ return cnt;
+}
+
+int VnodeOpendir(struct Vnode *vnode, struct fs_dirent_s *dir)
+{
+ (void)vnode;
+ (void)dir;
+ return LOS_OK;
+}
+
+int VnodeClosedir(struct Vnode *vnode, struct fs_dirent_s *dir)
+{
+ (void)vnode;
+ (void)dir;
+ return LOS_OK;
+}
+
+int VnodeCreate(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode)
+{
+ int ret;
+ struct Vnode *newVnode = NULL;
+
+ ret = VnodeAlloc(NULL, &newVnode);
+ if (ret != 0) {
+ return -ENOMEM;
+ }
+
+ newVnode->type = VNODE_TYPE_CHR;
+ newVnode->vop = parent->vop;
+ newVnode->fop = parent->fop;
+ newVnode->data = NULL;
+ newVnode->parent = parent;
+ newVnode->originMount = parent->originMount;
+ newVnode->uid = parent->uid;
+ newVnode->gid = parent->gid;
+ newVnode->mode = mode;
+
+ *vnode = newVnode;
+ return 0;
+}
+
+int VnodeDevInit()
+{
+ struct Vnode *devNode = NULL;
+ struct Mount *devMount = NULL;
+
+ int retval = VnodeLookup("/dev", &devNode, V_CREATE | V_CACHE | V_DUMMY);
+ if (retval != LOS_OK) {
+ PRINT_ERR("VnodeDevInit failed error %d\n", retval);
+ return retval;
+ }
+ devNode->mode = DEV_VNODE_MODE | S_IFDIR;
+ devNode->type = VNODE_TYPE_DIR;
+
+ devMount = MountAlloc(devNode, NULL);
+ devMount->vnodeCovered = devNode;
+ devMount->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_NEW;
+ return LOS_OK;
+}
+
+int VnodeGetattr(struct Vnode *vnode, struct stat *buf)
+{
+ (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
+ buf->st_mode = vnode->mode;
+ buf->st_uid = vnode->uid;
+ buf->st_gid = vnode->gid;
+
+ return LOS_OK;
+}
+
+struct Vnode *VnodeGetRoot()
+{
+ return g_rootVnode;
+}
+
+static int VnodeChattr(struct Vnode *vnode, struct IATTR *attr)
+{
+ mode_t tmpMode;
+ if (vnode == NULL || attr == NULL) {
+ return -EINVAL;
+ }
+ if (attr->attr_chg_valid & CHG_MODE) {
+ tmpMode = attr->attr_chg_mode;
+ tmpMode &= ~S_IFMT;
+ vnode->mode &= S_IFMT;
+ vnode->mode = tmpMode | vnode->mode;
+ }
+ if (attr->attr_chg_valid & CHG_UID) {
+ vnode->uid = attr->attr_chg_uid;
+ }
+ if (attr->attr_chg_valid & CHG_GID) {
+ vnode->gid = attr->attr_chg_gid;
+ }
+ return LOS_OK;
+}
+
+int VnodeDevLookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **vnode)
+{
+ (void)parentVnode;
+ (void)path;
+ (void)len;
+ (void)vnode;
+ /* dev node must in pathCache. */
+ return -ENOENT;
+}
+
+static struct VnodeOps g_devfsOps = {
+ .Lookup = VnodeDevLookup,
+ .Getattr = VnodeGetattr,
+ .Readdir = VnodeReaddir,
+ .Opendir = VnodeOpendir,
+ .Closedir = VnodeClosedir,
+ .Create = VnodeCreate,
+ .Chattr = VnodeChattr,
+};
+
+void VnodeMemoryDump(void)
+{
+ struct Vnode *item = NULL;
+ struct Vnode *nextItem = NULL;
+ int vnodeCount = 0;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeCurrList, struct Vnode, actFreeEntry) {
+ if ((item->useCount > 0) ||
+ (item->flag & VNODE_FLAG_MOUNT_NEW) ||
+ (item->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
+ continue;
+ }
+
+ vnodeCount++;
+ }
+
+ PRINTK("Vnode number = %d\n", vnodeCount);
+ PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode));
+}
diff --git a/fs/vfs/vnode_hash.c b/fs/vfs/vnode_hash.c
new file mode 100644
index 00000000..7a98cced
--- /dev/null
+++ b/fs/vfs/vnode_hash.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "los_mux.h"
+#include "fs/vnode.h"
+
+
+#define VNODE_HASH_BUCKETS 128
+
+LIST_HEAD g_vnodeHashEntrys[VNODE_HASH_BUCKETS];
+uint32_t g_vnodeHashMask = VNODE_HASH_BUCKETS - 1;
+uint32_t g_vnodeHashSize = VNODE_HASH_BUCKETS;
+uint32_t g_curVnodeSize = 0;
+
+static LosMux g_vnodeHashMux;
+
+int VnodeHashInit(void)
+{
+ int ret;
+ for (int i = 0; i < g_vnodeHashSize; i++) {
+ LOS_ListInit(&g_vnodeHashEntrys[i]);
+ }
+
+ ret = LOS_MuxInit(&g_vnodeHashMux, NULL);
+ if (ret != LOS_OK) {
+ PRINT_ERR("Create mutex for vnode hash list fail, status: %d", ret);
+ return ret;
+ }
+
+ return LOS_OK;
+}
+
+void VnodeHashDump(void)
+{
+ PRINTK("-------->VnodeHashDump in\n");
+ (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER);
+ for (int i = 0; i < g_vnodeHashSize; i++) {
+ LIST_HEAD *nhead = &g_vnodeHashEntrys[i];
+ struct Vnode *node = NULL;
+
+ LOS_DL_LIST_FOR_EACH_ENTRY(node, nhead, struct Vnode, hashEntry) {
+ PRINTK(" vnode dump: col %d item %p\n", i, node);
+ }
+ }
+ (void)LOS_MuxUnlock(&g_vnodeHashMux);
+ PRINTK("-------->VnodeHashDump out\n");
+}
+
+uint32_t VfsHashIndex(struct Vnode *vnode)
+{
+ if (vnode == NULL) {
+ return -EINVAL;
+ }
+ return (vnode->hash + vnode->originMount->hashseed);
+}
+
+static LOS_DL_LIST *VfsHashBucket(const struct Mount *mp, uint32_t hash)
+{
+ return (&g_vnodeHashEntrys[(hash + mp->hashseed) & g_vnodeHashMask]);
+}
+
+int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fn, void *arg)
+{
+ struct Vnode *curVnode = NULL;
+
+ if (mount == NULL || vnode == NULL) {
+ return -EINVAL;
+ }
+
+ (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER);
+ LOS_DL_LIST *list = VfsHashBucket(mount, hash);
+ LOS_DL_LIST_FOR_EACH_ENTRY(curVnode, list, struct Vnode, hashEntry) {
+ if (curVnode->hash != hash) {
+ continue;
+ }
+ if (curVnode->originMount != mount) {
+ continue;
+ }
+ if (fn != NULL && fn(curVnode, arg)) {
+ continue;
+ }
+ (void)LOS_MuxUnlock(&g_vnodeHashMux);
+ *vnode = curVnode;
+ return LOS_OK;
+ }
+ (void)LOS_MuxUnlock(&g_vnodeHashMux);
+ *vnode = NULL;
+ return LOS_NOK;
+}
+
+void VfsHashRemove(struct Vnode *vnode)
+{
+ if (vnode == NULL) {
+ return;
+ }
+ (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER);
+ LOS_ListDelete(&vnode->hashEntry);
+ (void)LOS_MuxUnlock(&g_vnodeHashMux);
+}
+
+int VfsHashInsert(struct Vnode *vnode, uint32_t hash)
+{
+ if (vnode == NULL) {
+ return -EINVAL;
+ }
+ (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER);
+ vnode->hash = hash;
+ LOS_ListHeadInsert(VfsHashBucket(vnode->originMount, hash), &vnode->hashEntry);
+ (void)LOS_MuxUnlock(&g_vnodeHashMux);
+ return LOS_OK;
+}
diff --git a/fs/zpfs/vfs_zpfs.c b/fs/zpfs/vfs_zpfs.c
index d9ce0930..8d855c6c 100755
--- a/fs/zpfs/vfs_zpfs.c
+++ b/fs/zpfs/vfs_zpfs.c
@@ -161,7 +161,7 @@ static int VfsZpfsClose(struct file *file)
return ret;
}
-static ssize_t VfsZpfsRead(struct file *file, FAR char *buffer, size_t bufLen)
+static ssize_t VfsZpfsRead(struct file *file, char *buffer, size_t bufLen)
{
struct inode *swapInode = NULL;
ssize_t sret;
@@ -370,7 +370,7 @@ static int VfsZpfsRewindDir(struct inode *mountpt, struct fs_dirent_s *dir)
return OK;
}
-static int VfsZpfsBind(struct inode *blkDriver, const void *data, FAR void **handle, const char *relPath)
+static int VfsZpfsBind(struct inode *blkDriver, const void *data, void **handle, const char *relPath)
{
if (data == NULL) {
return -1;
diff --git a/fs/zpfs/zpfs.c b/fs/zpfs/zpfs.c
index 05da2979..d2a21756 100644
--- a/fs/zpfs/zpfs.c
+++ b/fs/zpfs/zpfs.c
@@ -276,8 +276,8 @@ static int IsTargetMounted(const char *target)
return -EINVAL;
}
- inode = inode_search((FAR const char **)&target, (FAR struct inode**)NULL,
- (FAR struct inode**)NULL, (const char **)&path);
+ inode = inode_search((const char **)&target, (struct inode**)NULL,
+ (struct inode**)NULL, (const char **)&path);
if (inode == NULL || !INODE_IS_MOUNTPT(inode)) {
PRINT_ERR("Can't to mount to this inode %s\n", target);
return -EINVAL;
diff --git a/kernel/base/ipc/los_event.c b/kernel/base/ipc/los_event.c
index a17e3280..6fb9f6d4 100755
--- a/kernel/base/ipc/los_event.c
+++ b/kernel/base/ipc/los_event.c
@@ -44,7 +44,6 @@
extern "C" {
#endif
#endif /* __cplusplus */
-
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
{
UINT32 intSave;
@@ -110,7 +109,6 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT3
{
UINT32 ret;
LosTaskCB *runTask = NULL;
-
ret = OsEventParamCheck(eventCB, eventMask, mode);
if (ret != LOS_OK) {
return ret;
diff --git a/kernel/base/misc/vm_shellcmd.c b/kernel/base/misc/vm_shellcmd.c
index c4f08d1f..220890ab 100755
--- a/kernel/base/misc/vm_shellcmd.c
+++ b/kernel/base/misc/vm_shellcmd.c
@@ -42,6 +42,7 @@
#include "los_oom.h"
#include "los_vm_dump.h"
#include "los_process_pri.h"
+#include "fs/path_cache.h"
#ifdef __cplusplus
#if __cplusplus
@@ -186,6 +187,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID)
{
OsVmPhysDump();
+ PathCacheMemoryDump();
+ VnodeMemoryDump();
return OS_ERROR;
}
diff --git a/kernel/base/vm/los_vm_filemap.c b/kernel/base/vm/los_vm_filemap.c
old mode 100755
new mode 100644
index ced2e720..24b2c69e
--- a/kernel/base/vm/los_vm_filemap.c
+++ b/kernel/base/vm/los_vm_filemap.c
@@ -40,7 +40,6 @@
#include "los_vm_common.h"
#include "los_vm_fault.h"
#include "los_process_pri.h"
-#include "inode/inode.h"
#include "los_vm_lock.h"
#ifdef __cplusplus
@@ -129,6 +128,7 @@ VOID OsDeletePageCacheLru(LosFilePage *page)
OsPageCacheDel(page);
}
+#if VFS_IMPL_LATER
STATIC LosFilePage *OsPagecacheGetPageAndFill(struct file *filp, VM_OFFSET_T pgOff, size_t *readSize, VADDR_T *kvaddr)
{
LosFilePage *page = NULL;
@@ -151,7 +151,7 @@ STATIC LosFilePage *OsPagecacheGetPageAndFill(struct file *filp, VM_OFFSET_T pgO
file_seek(filp, pgOff << PAGE_SHIFT, SEEK_SET);
/* "ReadPage" func exists definitely in this procedure */
- *readSize = filp->f_inode->u.i_mops->readpage(filp, (char *)(UINTPTR)*kvaddr, PAGE_SIZE);
+ *readSize = filp->f_vnode->u.i_mops->readpage(filp, (char *)(UINTPTR)*kvaddr, PAGE_SIZE);
if (*readSize == 0) {
VM_ERR("read 0 bytes");
OsCleanPageLocked(page->vmPage);
@@ -162,6 +162,7 @@ STATIC LosFilePage *OsPagecacheGetPageAndFill(struct file *filp, VM_OFFSET_T pgO
return page;
}
+
ssize_t OsMappingRead(struct file *filp, char *buf, size_t size)
{
INT32 ret;
@@ -217,6 +218,7 @@ ssize_t OsMappingRead(struct file *filp, char *buf, size_t size)
return readTotal;
}
+#endif
ssize_t OsMappingWrite(struct file *filp, const char *buf, size_t size)
{
@@ -388,7 +390,7 @@ STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
char *buff = NULL;
VM_OFFSET_T oldPos;
struct file *file = fpage->mapping->host;
- if ((file == NULL) || (file->f_inode == NULL)) {
+ if ((file == NULL) || (file->f_vnode == NULL)) {
VM_ERR("page cache file error");
return LOS_NOK;
}
@@ -404,11 +406,7 @@ STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
return LOS_OK;
}
- if (file->f_inode && file->f_inode->u.i_mops->writepage) {
- ret = file->f_inode->u.i_mops->writepage(file, (buff + fpage->dirtyOff), len);
- } else {
- ret = file_write(file, (VOID *)buff, len);
- }
+ ret = file_write(file, (VOID *)buff, len);
if (ret <= 0) {
VM_ERR("WritePage error ret %d", ret);
}
@@ -536,11 +534,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
if (newCache) {
oldPos = file_seek(file, 0, SEEK_CUR);
file_seek(file, fpage->pgoff << PAGE_SHIFT, SEEK_SET);
- if (file->f_inode && file->f_inode->u.i_mops->readpage) {
- ret = file->f_inode->u.i_mops->readpage(file, (char *)kvaddr, PAGE_SIZE);
- } else {
- ret = file_read(file, kvaddr, PAGE_SIZE);
- }
+ ret = file_read(file, kvaddr, PAGE_SIZE);
file_seek(file, oldPos, SEEK_SET);
if (ret == 0) {
VM_ERR("Failed to read from file!");
@@ -646,34 +640,30 @@ INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
{
- struct inode *inodePtr = NULL;
+ struct Vnode *vnode = NULL;
if (filep == NULL) {
return LOS_ERRNO_VM_MAP_FAILED;
}
- inodePtr = filep->f_inode;
- if (inodePtr == NULL) {
+ vnode = filep->f_vnode;
+ if (vnode == NULL) {
return LOS_ERRNO_VM_MAP_FAILED;
}
- if (INODE_IS_MOUNTPT(inodePtr)) {
- if (inodePtr->u.i_mops->mmap) {
- LOS_SetRegionTypeFile(region);
- return inodePtr->u.i_mops->mmap(filep, region);
- } else {
- VM_ERR("file mmap not support");
- return LOS_ERRNO_VM_MAP_FAILED;
- }
- } else if (INODE_IS_DRIVER(inodePtr)) {
- if (inodePtr->u.i_ops && inodePtr->u.i_ops->mmap) {
+
+ if (filep->ops != NULL && filep->ops->mmap != NULL) {
+ if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) {
LOS_SetRegionTypeDev(region);
- return inodePtr->u.i_ops->mmap(filep, region);
} else {
- VM_ERR("dev mmap not support");
+ LOS_SetRegionTypeFile(region);
+ }
+ int ret = filep->ops->mmap(filep, region);
+ if (ret != LOS_OK) {
return LOS_ERRNO_VM_MAP_FAILED;
}
} else {
VM_ERR("mmap file type unknown");
return LOS_ERRNO_VM_MAP_FAILED;
}
+ return LOS_OK;
}
LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
diff --git a/kernel/common/console.c b/kernel/common/console.c
old mode 100755
new mode 100644
index ce5a7fe3..69b4dbc2
--- a/kernel/common/console.c
+++ b/kernel/common/console.c
@@ -37,7 +37,6 @@
#endif
#include "unistd.h"
#include "securec.h"
-#include "inode/inode.h"
#ifdef LOSCFG_SHELL_DMESG
#include "dmesg_pri.h"
#endif
@@ -48,7 +47,10 @@
#include "los_exc_pri.h"
#include "los_process_pri.h"
#include "los_sched_pri.h"
+#include "fs/path_cache.h"
+#include "fs/vfs_util.h"
#include "user_copy.h"
+#include "fs/vnode.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@@ -84,20 +86,24 @@ INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struc
{
INT32 ret;
- if ((filep == NULL) || (filep->f_inode == NULL) || (filep->f_inode->i_private == NULL)) {
+ if ((filep == NULL) || (filep->f_vnode == NULL) || (filep->f_vnode->data == NULL)) {
ret = EINVAL;
goto ERROUT;
}
/* to find console device's filep(now it is *privFilep) throught i_private */
- *privFilep = (struct file *)filep->f_inode->i_private;
- if (((*privFilep)->f_inode == NULL) || ((*privFilep)->f_inode->u.i_ops == NULL)) {
+ struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
+ *privFilep = (struct file *)drv->priv;
+ if (((*privFilep)->f_vnode == NULL) || ((*privFilep)->f_vnode->data == NULL)) {
ret = EINVAL;
goto ERROUT;
}
/* to find uart driver operation function throutht u.i_opss */
- *filepOps = (*privFilep)->f_inode->u.i_ops;
+
+ drv = (struct drv_data *)(*privFilep)->f_vnode->data;
+
+ *filepOps = (const struct file_operations_vfs *)drv->ops;
return ENOERR;
ERROUT:
@@ -242,33 +248,21 @@ STATIC INT32 ConsoleCtrlRightsRelease(CONSOLE_CB *consoleCB)
STATIC CONSOLE_CB *OsGetConsoleByDevice(const CHAR *deviceName)
{
INT32 ret;
- CHAR *fullpath = NULL;
- struct inode *inode = NULL;
- struct inode_search_s desc;
+ struct Vnode *vnode = NULL;
- ret = vfs_normalize_path(NULL, deviceName, &fullpath);
- if (ret < 0) {
- set_errno(EINVAL);
- return NULL;
- }
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
+ VnodeHold();
+ ret = VnodeLookup(deviceName, &vnode, 0);
+ VnodeDrop();
if (ret < 0) {
set_errno(EACCES);
- free(fullpath);
return NULL;
}
- inode = desc.node;
- free(fullpath);
- if (g_console[CONSOLE_SERIAL - 1]->devInode == inode) {
- inode_release(inode);
+ if (g_console[CONSOLE_SERIAL - 1]->devVnode == vnode) {
return g_console[CONSOLE_SERIAL - 1];
- } else if (g_console[CONSOLE_TELNET - 1]->devInode == inode) {
- inode_release(inode);
+ } else if (g_console[CONSOLE_TELNET - 1]->devVnode == vnode) {
return g_console[CONSOLE_TELNET - 1];
} else {
- inode_release(inode);
set_errno(ENOENT);
return NULL;
}
@@ -937,7 +931,6 @@ STATIC const struct file_operations_vfs g_consoleDevOps = {
#ifndef CONFIG_DISABLE_POLL
.poll = ConsolePoll,
#endif
- .unlink = NULL,
};
STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
@@ -970,40 +963,40 @@ STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
STATIC INT32 OsConsoleFileInit(CONSOLE_CB *consoleCB)
{
INT32 ret;
- struct inode *inode = NULL;
+ struct Vnode *vnode = NULL;
struct file *filep = NULL;
CHAR *fullpath = NULL;
- struct inode_search_s desc;
ret = vfs_normalize_path(NULL, consoleCB->name, &fullpath);
if (ret < 0) {
return EINVAL;
}
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
+
+ VnodeHold();
+ ret = VnodeLookup(fullpath, &vnode, 0);
+ if (ret != LOS_OK) {
ret = EACCES;
goto ERROUT_WITH_FULLPATH;
}
- inode = desc.node;
- consoleCB->fd = files_allocate(inode, O_RDWR, (off_t)0, consoleCB, STDERR_FILENO + 1);
+ consoleCB->fd = files_allocate(vnode, O_RDWR, (off_t)0, consoleCB, STDERR_FILENO + 1);
if (consoleCB->fd < 0) {
ret = EMFILE;
- goto ERROUT_WITH_INODE;
+ goto ERROUT_WITH_FULLPATH;
}
ret = fs_getfilep(consoleCB->fd, &filep);
if (ret < 0) {
ret = EPERM;
- goto ERROUT_WITH_INODE;
+ goto ERROUT_WITH_FULLPATH;
}
filep->f_path = fullpath;
+ filep->ops = (struct file_operations_vfs *)((struct drv_data *)vnode->data)->ops;
+ VnodeDrop();
return LOS_OK;
-ERROUT_WITH_INODE:
- inode_release(inode);
ERROUT_WITH_FULLPATH:
+ VnodeDrop();
free(fullpath);
return ret;
}
@@ -1015,10 +1008,8 @@ ERROUT_WITH_FULLPATH:
STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
{
INT32 ret;
- CHAR *fullpath = NULL;
struct file *filep = NULL;
- struct inode *inode = NULL;
- struct inode_search_s desc;
+ struct Vnode *vnode = NULL;
/* allocate memory for filep,in order to unchange the value of filep */
filep = (struct file *)LOS_MemAlloc(m_aucSysMem0, sizeof(struct file));
@@ -1027,107 +1018,53 @@ STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName)
goto ERROUT;
}
- /* Adopt procedure of open function to allocate 'filep' to /dev/console */
- ret = vfs_normalize_path(NULL, deviceName, &fullpath);
- if (ret < 0) {
- ret = EINVAL;
- goto ERROUT_WITH_FILEP;
- }
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
+ VnodeHold();
+ ret = VnodeLookup(deviceName, &vnode, V_DUMMY);
+ VnodeDrop(); // not correct, but can't fix perfectly here
+ if (ret != LOS_OK) {
ret = EACCES;
- goto ERROUT_WITH_FULLPATH;
+ PRINTK("!! can not find %s\n", consoleCB->name);
+ goto ERROUT;
}
- inode = desc.node;
- consoleCB->devInode = inode;
+ consoleCB->devVnode = vnode;
/*
* initialize the console filep which is associated with /dev/console,
- * assign the uart0 inode of /dev/ttyS0 to console inod of /dev/console,
+ * assign the uart0 vnode of /dev/ttyS0 to console inod of /dev/console,
* then we can operate console's filep as if we operate uart0 filep of
* /dev/ttyS0.
*/
(VOID)memset_s(filep, sizeof(struct file), 0, sizeof(struct file));
filep->f_oflags = O_RDWR;
filep->f_pos = 0;
- filep->f_inode = inode;
+ filep->f_vnode = vnode;
filep->f_path = NULL;
filep->f_priv = NULL;
-
- if (inode->u.i_ops->open != NULL) {
- (VOID)inode->u.i_ops->open(filep);
- } else {
- ret = EFAULT;
- goto ERROUT_WITH_INODE;
- }
-
/*
* Use filep to connect console and uart, we can find uart driver function throught filep.
* now we can operate /dev/console to operate /dev/ttyS0 through filep.
*/
+
ret = register_driver(consoleCB->name, &g_consoleDevOps, DEFFILEMODE, filep);
if (ret != LOS_OK) {
- goto ERROUT_WITH_INODE;
+ goto ERROUT;
}
- inode_release(inode);
- free(fullpath);
return LOS_OK;
-ERROUT_WITH_INODE:
- inode_release(inode);
-ERROUT_WITH_FULLPATH:
- free(fullpath);
-ERROUT_WITH_FILEP:
- (VOID)LOS_MemFree(m_aucSysMem0, filep);
ERROUT:
+ if (filep) {
+ (VOID)LOS_MemFree(m_aucSysMem0, filep);
+ }
+
set_errno(ret);
return LOS_NOK;
}
STATIC UINT32 OsConsoleDevDeinit(const CONSOLE_CB *consoleCB)
{
- INT32 ret;
- struct file *filep = NULL;
- struct inode *inode = NULL;
- CHAR *fullpath = NULL;
- struct inode_search_s desc;
-
- ret = vfs_normalize_path(NULL, consoleCB->name, &fullpath);
- if (ret < 0) {
- ret = EINVAL;
- goto ERROUT;
- }
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
- ret = EACCES;
- goto ERROUT_WITH_FULLPATH;
- }
- inode = desc.node;
-
- filep = inode->i_private;
- if (filep != NULL) {
- (VOID)LOS_MemFree(m_aucSysMem0, filep); /* free filep what you malloc from console_init */
- inode->i_private = NULL;
- } else {
- ret = EBADF;
- goto ERROUT_WITH_INODE;
- }
- inode_release(inode);
- free(fullpath);
- (VOID)unregister_driver(consoleCB->name);
- return LOS_OK;
-
-ERROUT_WITH_INODE:
- inode_release(inode);
-ERROUT_WITH_FULLPATH:
- free(fullpath);
-ERROUT:
- set_errno(ret);
- return LOS_NOK;
+ return unregister_driver(consoleCB->name);
}
STATIC CirBufSendCB *ConsoleCirBufCreate(VOID)
@@ -1260,6 +1197,7 @@ STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName)
ret = (INT32)OsConsoleBufInit(consoleCB);
if (ret != LOS_OK) {
+ PRINT_ERR("console OsConsoleBufInit error. %d\n", ret);
goto ERR_WITH_NAME;
}
@@ -1271,11 +1209,13 @@ STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName)
ret = OsConsoleDevInit(consoleCB, deviceName);
if (ret != LOS_OK) {
+ PRINT_ERR("console OsConsoleDevInitlloc error. %d\n", ret);
goto ERR_WITH_SEM;
}
ret = OsConsoleFileInit(consoleCB);
if (ret != LOS_OK) {
+ PRINT_ERR("console OsConsoleFileInit error. %d\n", ret);
goto ERR_WITH_DEV;
}
@@ -1344,6 +1284,7 @@ INT32 system_console_init(const CHAR *deviceName)
LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
#ifdef LOSCFG_SHELL
+
ret = OsShellInit(consoleID);
if (ret != LOS_OK) {
PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
diff --git a/kernel/common/console.h b/kernel/common/console.h
index 7b2a7ef4..20a0c2d3 100755
--- a/kernel/common/console.h
+++ b/kernel/common/console.h
@@ -82,7 +82,7 @@ typedef struct {
UINT32 consoleSem;
UINT32 shellEntryId;
UINT32 consoleMask;
- struct inode *devInode;
+ struct Vnode *devVnode;
CHAR *name;
INT32 fd;
UINT32 refCount;
diff --git a/kernel/common/los_hilog.c b/kernel/common/los_hilog.c
old mode 100755
new mode 100644
index e1a798dc..1da79321
--- a/kernel/common/los_hilog.c
+++ b/kernel/common/los_hilog.c
@@ -56,11 +56,11 @@ struct HiLogEntry {
ssize_t HilogRead(struct file *filep, char __user *buf, size_t count);
ssize_t HilogWrite(struct file *filep, const char __user *buf, size_t count);
-int HiLogOpen(FAR struct file *filep);
-int HiLogClose(FAR struct file *filep);
+int HiLogOpen(struct file *filep);
+int HiLogClose(struct file *filep);
-static ssize_t HiLogWrite(FAR struct file *filep, const char *buffer, size_t bufLen);
-static ssize_t HiLogRead(FAR struct file *filep, char *buffer, size_t bufLen);
+static ssize_t HiLogWrite(struct file *filep, const char *buffer, size_t bufLen);
+static ssize_t HiLogRead(struct file *filep, char *buffer, size_t bufLen);
STATIC struct file_operations_vfs g_hilogFops = {
HiLogOpen, /* open */
@@ -76,7 +76,7 @@ STATIC struct file_operations_vfs g_hilogFops = {
NULL, /* unlink */
};
-FAR struct HiLogCharDevice {
+struct HiLogCharDevice {
int flag;
LosMux mtx;
unsigned char *buffer;
@@ -92,13 +92,13 @@ static inline unsigned char *HiLogBufferHead(void)
return g_hiLogDev.buffer + g_hiLogDev.headOffset;
}
-int HiLogOpen(FAR struct file *filep)
+int HiLogOpen(struct file *filep)
{
(void)filep;
return 0;
}
-int HiLogClose(FAR struct file *filep)
+int HiLogClose(struct file *filep)
{
(void)filep;
return 0;
@@ -161,7 +161,7 @@ static int HiLogReadRingBuffer(unsigned char *buffer, size_t bufLen)
return retval;
}
-static ssize_t HiLogRead(FAR struct file *filep, char *buffer, size_t bufLen)
+static ssize_t HiLogRead(struct file *filep, char *buffer, size_t bufLen)
{
size_t retval;
struct HiLogEntry header;
@@ -301,7 +301,7 @@ out:
return retval;
}
-static ssize_t HiLogWrite(FAR struct file *filep, const char *buffer, size_t bufLen)
+static ssize_t HiLogWrite(struct file *filep, const char *buffer, size_t bufLen)
{
(void)filep;
if (bufLen + sizeof(struct HiLogEntry) > HILOG_BUFFER) {
diff --git a/kernel/common/los_rootfs.c b/kernel/common/los_rootfs.c
old mode 100755
new mode 100644
index 11a2de93..dd50cb06
--- a/kernel/common/los_rootfs.c
+++ b/kernel/common/los_rootfs.c
@@ -40,11 +40,11 @@
#include "ff.h"
#endif
#include "sys/mount.h"
-#include "inode/inode.h"
#ifdef LOSCFG_PLATFORM_ROOTFS
#include "los_rootfs.h"
#endif
#include "mtd_list.h"
+#include "fs/path_cache.h"
#ifdef LOSCFG_STORAGE_SPINOR
#define DEV_STORAGE_PATH "/dev/spinorblk2"
@@ -73,20 +73,8 @@ STATIC los_disk *g_emmcDisk = NULL;
STATIC INT32 g_alignSize = 0;
#endif
-#define VFAT_STORAGE_MOUNT_DIR_MODE 777
-#define DEFAULT_STORAGE_MOUNT_DIR_MODE 755
-
-STATIC UINT64 g_cmdLineAddr = COMMAND_LINE_ADDR;
-
-VOID OsSetCmdLineAddr(UINT64 addr)
-{
- g_cmdLineAddr = addr;
-}
-
-UINT64 OsGetCmdLineAddr(VOID)
-{
- return g_cmdLineAddr;
-}
+#define VFAT_STORAGE_MOUNT_DIR_MODE 0777
+#define DEFAULT_STORAGE_MOUNT_DIR_MODE 0755
#ifdef LOSCFG_DRIVERS_MMC
los_disk *GetMmcDisk(UINT8 type)
@@ -117,7 +105,7 @@ STATIC const CHAR *AddEmmcRootfsPart(INT32 rootAddr, INT32 rootSize)
{
INT32 ret;
- struct mmc_block *block = g_emmcDisk->dev->i_private;
+ struct mmc_block *block = (struct mmc_block *)((struct drv_data *)g_emmcDisk->dev->data)->priv;
const char *node_name = mmc_block_get_node_name(block);
if (los_disk_deinit(g_emmcDisk->disk_id) != ENOERR) {
PRINT_ERR("Failed to deinit emmc disk!\n");
@@ -434,7 +422,7 @@ STATIC VOID OsMountUserdata(const CHAR *fsType)
ret = mkdir(userdataDir, VFAT_STORAGE_MOUNT_DIR_MODE);
if (ret != LOS_OK) {
err = get_errno();
- PRINT_ERR("Failed to reserve inode /userdata, errno %d: %s\n", err, strerror(err));
+ PRINT_ERR("Failed to reserve vnode /userdata, errno %d: %s\n", err, strerror(err));
return;
}
CHAR emmcUserdataDev[DISK_NAME] = {0};
@@ -477,12 +465,10 @@ STATIC INT32 OsMountRootfsAndUserfs(const CHAR *rootDev, const CHAR *fsType)
PRINT_ERR("Failed to mount vfat rootfs, errno %d: %s\n", err, strerror(err));
return ret;
}
- g_root_inode->i_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
#ifdef LOSCFG_STORAGE_EMMC
ret = mkdir("/storage", VFAT_STORAGE_MOUNT_DIR_MODE);
- if (ret != LOS_OK) {
- err = get_errno();
- PRINT_ERR("Failed to reserve inode /storage, errno %d: %s\n", err, strerror(err));
+ if ((ret != LOS_OK) && ((err = get_errno()) != EEXIST)) {
+ PRINT_ERR("Failed to reserve vnode /storage, errno %d: %s\n", err, strerror(err));
} else {
CHAR emmcStorageDev[DISK_NAME] = {0};
if (snprintf_s(emmcStorageDev, sizeof(emmcStorageDev), sizeof(emmcStorageDev) - 1,
@@ -507,9 +493,8 @@ STATIC INT32 OsMountRootfsAndUserfs(const CHAR *rootDev, const CHAR *fsType)
}
#if defined(LOSCFG_STORAGE_SPINOR) || defined(LOSCFG_STORAGE_SPINAND)
ret = mkdir("/storage", DEFAULT_STORAGE_MOUNT_DIR_MODE);
- if (ret != LOS_OK) {
- err = get_errno();
- PRINT_ERR("Failed to reserve inode /storage, errno %d: %s\n", err, strerror(err));
+ if ((ret != LOS_OK) && ((err = get_errno()) != EEXIST)) {
+ PRINT_ERR("Failed to reserve vnode /storage, errno %d: %s\n", err, strerror(err));
} else {
ret = mount(DEV_STORAGE_PATH, "/storage", fsType, 0, NULL);
if (ret != LOS_OK) {
diff --git a/kernel/common/patchfs/los_patchfs.c b/kernel/common/patchfs/los_patchfs.c
index fa1012c4..d2ece3b9 100755
--- a/kernel/common/patchfs/los_patchfs.c
+++ b/kernel/common/patchfs/los_patchfs.c
@@ -32,7 +32,7 @@
#include "los_partition_utils.h"
#include "sys/mount.h"
-#include "inode/inode.h"
+#include "fs/vnode.h"
#ifdef LOSCFG_PLATFORM_PATCHFS
diff --git a/kernel/common/virtual_serial.c b/kernel/common/virtual_serial.c
old mode 100755
new mode 100644
index d8def05d..fda82408
--- a/kernel/common/virtual_serial.c
+++ b/kernel/common/virtual_serial.c
@@ -35,10 +35,11 @@
#include "stdarg.h"
#endif
#ifdef LOSCFG_FS_VFS
-#include "inode/inode.h"
#include "console.h"
#endif
+#include "fs/path_cache.h"
+
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@@ -48,6 +49,7 @@ extern "C" {
STATIC volatile UINT32 g_serialType = 0;
STATIC struct file g_serialFilep;
+
UINT32 SerialTypeGet(VOID)
{
return g_serialType;
@@ -130,7 +132,7 @@ ERROUT:
}
/* Note: do not add print function in this module! */
-STATIC ssize_t SerialWrite(FAR struct file *filep, FAR const CHAR *buffer, size_t bufLen)
+STATIC ssize_t SerialWrite(struct file *filep, const CHAR *buffer, size_t bufLen)
{
INT32 ret;
struct file *privFilep = NULL;
@@ -215,9 +217,7 @@ STATIC const struct file_operations_vfs g_serialDevOps = {
INT32 virtual_serial_init(const CHAR *deviceName)
{
INT32 ret;
- CHAR *fullpath = NULL;
- struct inode *inode = NULL;
- struct inode_search_s desc;
+ struct Vnode *vnode = NULL;
if (deviceName == NULL) {
ret = EINVAL;
@@ -226,86 +226,39 @@ INT32 virtual_serial_init(const CHAR *deviceName)
SerialTypeSet(deviceName);
- ret = vfs_normalize_path(NULL, deviceName, &fullpath);
- if (ret < 0) {
- ret = EINVAL;
+ VnodeHold();
+ ret = VnodeLookup(deviceName, &vnode, V_DUMMY);
+ if (ret != LOS_OK) {
+ ret = EACCES;
goto ERROUT;
}
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
- ret = EACCES;
- goto ERROUT_WITH_FULLPATH;
- }
- inode = desc.node;
(VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file));
g_serialFilep.f_oflags = O_RDWR;
- g_serialFilep.f_inode = inode;
+ g_serialFilep.f_vnode = vnode;
+ g_serialFilep.ops = ((struct drv_data *)vnode->data)->ops;
- if (inode->u.i_ops->open != NULL) {
- (VOID)inode->u.i_ops->open(&g_serialFilep);
+ if (g_serialFilep.ops->open != NULL) {
+ (VOID)g_serialFilep.ops->open(&g_serialFilep);
} else {
ret = EFAULT;
- inode_release(inode);
- goto ERROUT_WITH_FULLPATH;
+ PRINTK("virtual_serial_init %s open is NULL\n", deviceName);
+ goto ERROUT;
}
-
(VOID)register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep);
- inode_release(inode);
- free(fullpath);
+
+ VnodeDrop();
return ENOERR;
-ERROUT_WITH_FULLPATH:
- free(fullpath);
ERROUT:
+ VnodeDrop();
set_errno(ret);
return VFS_ERROR;
}
INT32 virtual_serial_deinit(VOID)
{
- INT32 ret;
- struct file *filep = NULL;
- struct inode *inode = NULL;
- CHAR *fullpath = NULL;
- struct inode_search_s desc;
-
- /* It's a process opposite virtual_serial_init */
- ret = vfs_normalize_path(NULL, SERIAL, &fullpath);
- if (ret < 0) {
- ret = EINVAL;
- goto ERROUT;
- }
- SETUP_SEARCH(&desc, fullpath, false);
- ret = inode_find(&desc);
- if (ret < 0) {
- ret = EACCES;
- goto ERROUT_WITH_FULLPATH;
- }
- inode = desc.node;
-
- filep = inode->i_private;
- if ((filep != NULL) && (inode->u.i_ops != NULL)) {
- (VOID)inode->u.i_ops->close(filep); /* close filep */
- inode->i_private = NULL;
- } else {
- ret = EBADF;
- goto ERROUT_WITH_INODE;
- }
- inode_release(inode);
- free(fullpath);
- (VOID)unregister_driver(SERIAL);
-
- return ENOERR;
-
-ERROUT_WITH_INODE:
- inode_release(inode);
-ERROUT_WITH_FULLPATH:
- free(fullpath);
-ERROUT:
- set_errno(ret);
- return VFS_ERROR;
+ return unregister_driver(SERIAL);
}
#ifdef __cplusplus
diff --git a/kernel/extended/liteipc/hm_liteipc.c b/kernel/extended/liteipc/hm_liteipc.c
old mode 100755
new mode 100644
index c35b4bca..4d745828
--- a/kernel/extended/liteipc/hm_liteipc.c
+++ b/kernel/extended/liteipc/hm_liteipc.c
@@ -82,27 +82,20 @@ SPIN_LOCK_INIT(g_ipcSpin);
#define IPC_LOCK(state) LOS_SpinLockSave(&g_ipcSpin, &(state))
#define IPC_UNLOCK(state) LOS_SpinUnlockRestore(&g_ipcSpin, state)
-STATIC int LiteIpcOpen(FAR struct file *filep);
-STATIC int LiteIpcClose(FAR struct file *filep);
-STATIC int LiteIpcIoctl(FAR struct file *filep, int cmd, unsigned long arg);
-STATIC int LiteIpcMmap(FAR struct file* filep, LosVmMapRegion *region);
+STATIC int LiteIpcOpen(struct file *filep);
+STATIC int LiteIpcClose(struct file *filep);
+STATIC int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg);
+STATIC int LiteIpcMmap(struct file* filep, LosVmMapRegion *region);
STATIC UINT32 LiteIpcWrite(IpcContent *content);
STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID);
STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback);
STATIC const struct file_operations_vfs g_liteIpcFops = {
- LiteIpcOpen, /* open */
- LiteIpcClose, /* close */
- NULL, /* read */
- NULL, /* write */
- NULL, /* seek */
- LiteIpcIoctl, /* ioctl */
- LiteIpcMmap, /* mmap */
-#ifndef CONFIG_DISABLE_POLL
- NULL, /* poll */
-#endif
- NULL, /* unlink */
+ .open = LiteIpcOpen, /* open */
+ .close = LiteIpcClose, /* close */
+ .ioctl = LiteIpcIoctl, /* ioctl */
+ .mmap = LiteIpcMmap, /* mmap */
};
#if (LOSCFG_KERNEL_TRACE == YES)
@@ -174,12 +167,12 @@ LITE_OS_SEC_TEXT_INIT UINT32 LiteIpcInit(VOID)
return ret;
}
-LITE_OS_SEC_TEXT STATIC int LiteIpcOpen(FAR struct file *filep)
+LITE_OS_SEC_TEXT STATIC int LiteIpcOpen(struct file *filep)
{
return 0;
}
-LITE_OS_SEC_TEXT STATIC int LiteIpcClose(FAR struct file *filep)
+LITE_OS_SEC_TEXT STATIC int LiteIpcClose(struct file *filep)
{
return 0;
}
@@ -237,13 +230,13 @@ LITE_OS_SEC_TEXT STATIC INT32 DoIpcMmap(LosProcessCB *pcb, LosVmMapRegion *regio
return ret;
}
-LITE_OS_SEC_TEXT STATIC int LiteIpcMmap(FAR struct file* filep, LosVmMapRegion *region)
+LITE_OS_SEC_TEXT STATIC int LiteIpcMmap(struct file *filep, LosVmMapRegion *region)
{
int ret = 0;
LosVmMapRegion *regionTemp = NULL;
LosProcessCB *pcb = OsCurrProcessGet();
if ((region == NULL) || (region->range.size > LITE_IPC_POOL_MAX_SIZE) ||
- (!LOS_IsRegionPermUserReadOnly(region)) || (!LOS_IsRegionFlagPrivateOnly(region))) {
+ (!LOS_IsRegionPermUserReadOnly(region)) || (!LOS_IsRegionFlagPrivateOnly(region))) {
ret = -EINVAL;
goto ERROR_REGION_OUT;
}
@@ -343,7 +336,7 @@ LITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(UINT32 processID, VOID *buf
}
}
-LITE_OS_SEC_TEXT STATIC VOID* LiteIpcNodeAlloc(UINT32 processID, UINT32 size)
+LITE_OS_SEC_TEXT STATIC VOID *LiteIpcNodeAlloc(UINT32 processID, UINT32 size)
{
VOID *ptr = LOS_MemAlloc(OS_PCB_FROM_PID(processID)->ipcInfo.pool.kvaddr, size);
PRINT_INFO("LiteIpcNodeAlloc pid:%d, pool:%x buf:%x size:%d\n",
@@ -1210,7 +1203,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleCmsCmd(CmsCmdContent *content)
return ret;
}
-LITE_OS_SEC_TEXT int LiteIpcIoctl(FAR struct file *filep, int cmd, unsigned long arg)
+LITE_OS_SEC_TEXT int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg)
{
UINT32 ret = LOS_OK;
if (IsPoolMapped() == FALSE) {
diff --git a/kernel/extended/trace/los_trace.c b/kernel/extended/trace/los_trace.c
old mode 100755
new mode 100644
index ad63323a..74c2f663
--- a/kernel/extended/trace/los_trace.c
+++ b/kernel/extended/trace/los_trace.c
@@ -40,7 +40,6 @@
#include "shell.h"
#include "unistd.h"
#include "stdlib.h"
-#include "inode/inode.h"
#endif
#ifdef __cplusplus
diff --git a/kernel/include/los_base.h b/kernel/include/los_base.h
index 7c5fe36d..436e9419 100755
--- a/kernel/include/los_base.h
+++ b/kernel/include/los_base.h
@@ -60,6 +60,8 @@ extern "C" {
#define LOS_ASSERT_COND(expression) LOS_ASSERT(expression)
+extern VOID PrintExcInfo(const CHAR *fmt, ...);
+
/**
* @ingroup los_base
* Define the timeout interval as LOS_NO_WAIT.
diff --git a/net/telnet/src/telnet_dev.c b/net/telnet/src/telnet_dev.c
old mode 100755
new mode 100644
index 77fbca07..baaf4c5c
--- a/net/telnet/src/telnet_dev.c
+++ b/net/telnet/src/telnet_dev.c
@@ -47,6 +47,7 @@
#include "lwip/sockets.h"
#include "telnet_pri.h"
+#include "fs/vnode.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@@ -59,31 +60,31 @@ extern "C" {
STATIC TELNET_DEV_S g_telnetDev;
STATIC EVENT_CB_S *g_event;
-STATIC struct inode *g_currentInode;
+STATIC struct Vnode *g_currentVnode;
STATIC INLINE TELNET_DEV_S *GetTelnetDevByFile(const struct file *file, BOOL isOpenOp)
{
- struct inode *telnetInode = NULL;
+ struct Vnode *telnetInode = NULL;
TELNET_DEV_S *telnetDev = NULL;
if (file == NULL) {
return NULL;
}
- telnetInode = file->f_inode;
+ telnetInode = file->f_vnode;
if (telnetInode == NULL) {
return NULL;
}
/*
- * Check if the f_inode is valid here for non-open ops (open is supposed to get invalid f_inode):
+ * Check if the f_vnode is valid here for non-open ops (open is supposed to get invalid f_vnode):
* when telnet is disconnected, there still may be 'TelentShellTask' tasks trying to write
- * to the file, but the file has illegal f_inode because the file is used by others.
+ * to the file, but the file has illegal f_vnode because the file is used by others.
*/
if (!isOpenOp) {
- if (telnetInode != g_currentInode) {
+ if (telnetInode != g_currentVnode) {
return NULL;
}
}
- telnetDev = (TELNET_DEV_S *)telnetInode->i_private;
+ telnetDev = (TELNET_DEV_S *)((struct drv_data*)telnetInode->data)->priv;
return telnetDev;
}
@@ -165,7 +166,7 @@ STATIC INT32 TelnetOpen(struct file *file)
telnetDev->cmdFifo->fifoNum = FIFO_MAX;
LOS_ListInit(&wait->poll_queue);
}
- g_currentInode = file->f_inode;
+ g_currentVnode = file->f_vnode;
TelnetUnlock();
return 0;
}
@@ -189,7 +190,7 @@ STATIC INT32 TelnetClose(struct file *file)
(VOID)LOS_EventDestroy(&telnetDev->eventTelnet);
g_event = NULL;
}
- g_currentInode = NULL;
+ g_currentVnode = NULL;
TelnetUnlock();
return 0;
}
diff --git a/platform/bsp.mk b/platform/bsp.mk
index b2dc9216..7f6640df 100755
--- a/platform/bsp.mk
+++ b/platform/bsp.mk
@@ -80,6 +80,7 @@ LITEOS_PLATFORM := $(subst $\",,$(LOSCFG_PLATFORM))
PLATFORM_BSP_BASE := $(LITEOSTOPDIR)/platform
PLATFORM_INCLUDE := -I $(LITEOSTOPDIR)/../../$(LOSCFG_BOARD_CONFIG_PATH) \
+ -I $(LITEOSTOPDIR)/../../$(LOSCFG_BOARD_CONFIG_PATH)/include \
-I $(PLATFORM_BSP_BASE)/../kernel/common \
-I $(PLATFORM_BSP_BASE)/../../../drivers/liteos/platform/pm \
-I $(PLATFORM_BSP_BASE)/hw/include \
diff --git a/shell/full/src/base/shcmd.c b/shell/full/src/base/shcmd.c
index 34e11ce5..39b7ad14 100755
--- a/shell/full/src/base/shcmd.c
+++ b/shell/full/src/base/shcmd.c
@@ -38,6 +38,7 @@
#include "securec.h"
#include "los_mux.h"
#include "los_memory.h"
+#include "los_typedef.h"
#ifdef __cplusplus
#if __cplusplus
@@ -274,7 +275,6 @@ STATIC VOID strncmp_cut(const CHAR *s1, CHAR *s2, size_t n)
}
return;
}
-
STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR *strObj, UINT32 *maxLen)
{
INT32 count = 0;
diff --git a/shell/full/src/cmds/date_shell.c b/shell/full/src/cmds/date_shell.c
old mode 100755
new mode 100644
index 2c594b3a..b16bc3b5
--- a/shell/full/src/cmds/date_shell.c
+++ b/shell/full/src/cmds/date_shell.c
@@ -36,7 +36,6 @@
#include "los_typedef.h"
#include "sys/stat.h"
#include "securec.h"
-#include "inode/inode.h"
#if defined(__LP64__)
#define timeval64 timeval
diff --git a/shell/full/src/cmds/dmesg.c b/shell/full/src/cmds/dmesg.c
old mode 100755
new mode 100644
index 961d39d7..fa195c16
--- a/shell/full/src/cmds/dmesg.c
+++ b/shell/full/src/cmds/dmesg.c
@@ -59,7 +59,6 @@ Case B:
#include "unistd.h"
#include "stdlib.h"
#include "los_task.h"
-#include "inode/inode.h"
#ifdef __cplusplus
#if __cplusplus
diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c
old mode 100755
new mode 100644
index 72ad0653..1b4034a8
--- a/syscall/fs_syscall.c
+++ b/syscall/fs_syscall.c
@@ -270,49 +270,52 @@ ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
int SysOpen(const char *path, int oflags, ...)
{
int ret;
- mode_t mode;
+ int procFd;
+ mode_t mode = DEFAULT_FILE_MODE; /* 0666: File read-write properties. */
char *pathRet = NULL;
- int procFd = -1;
- if (path != NULL) {
- ret = UserPathCopy(path, &pathRet);
- if (ret != 0) {
- goto OUT;
- }
+ if (path == NULL && *path == 0) {
+ return -EINVAL;
+ }
+
+ ret = UserPathCopy(path, &pathRet);
+ if (ret != 0) {
+ return ret;
}
procFd = AllocProcessFd();
- if (procFd < 0) {
+ if (procFd < 0) {
ret = -EMFILE;
- goto OUT;
+ goto ERROUT;
}
if ((unsigned int)oflags & O_DIRECTORY) {
ret = do_opendir(pathRet, oflags);
- if (ret < 0) {
- ret = -get_errno();
- }
- goto OUT;
- }
-
+ } else {
#ifdef LOSCFG_FILE_MODE
- va_list ap;
-
- va_start(ap, oflags);
- mode = va_arg(ap, int);
- va_end(ap);
-#else
- mode = 0666; /* 0666: File read-write properties. */
+ va_list ap;
+ va_start(ap, oflags);
+ mode = va_arg(ap, int);
+ va_end(ap);
#endif
- ret = do_open(AT_FDCWD, (path ? pathRet : NULL), oflags, mode);
- if (ret < 0) {
- ret = -get_errno();
+ ret = do_open(AT_FDCWD, pathRet, oflags, mode);
}
-OUT:
+ if (ret < 0) {
+ ret = -get_errno();
+ goto ERROUT;
+ }
+
+ AssociateSystemFd(procFd, ret);
if (pathRet != NULL) {
- (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
+ LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
+ }
+ return procFd;
+
+ERROUT:
+ if (pathRet != NULL) {
+ LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
}
if (ret >= 0) {
AssociateSystemFd(procFd, ret);
@@ -628,7 +631,12 @@ int SysAccess(const char *path, int amode)
ret = statfs((path ? pathRet : NULL), &fsBuf);
if (ret != 0) {
ret = -get_errno();
- goto OUT;
+ if (ret != -ENOSYS) {
+ goto OUT;
+ } else {
+ /* dev has no statfs ops, need devfs to handle this in feature */
+ ret = LOS_OK;
+ }
}
if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
diff --git a/syscall/los_syscall.h b/syscall/los_syscall.h
old mode 100755
new mode 100644
index a4e04f43..afd74df2
--- a/syscall/los_syscall.h
+++ b/syscall/los_syscall.h
@@ -55,6 +55,8 @@
#include "dirent.h"
#include "fs/fs.h"
#endif
+#include
+#include "sys/resource.h"
/* process */
extern unsigned int SysGetGroupId(void);
@@ -187,7 +189,8 @@ extern int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec
/* filesystem */
#ifdef LOSCFG_FS_VFS
typedef int (*PollFun)(struct pollfd *fds, nfds_t nfds, int timeout);
-extern int do_open(int dirfd, const char *path, int oflags, ...);
+extern int fp_open(char *fullpath, int oflags, mode_t mode);
+extern int do_open(int dirfd, const char *path, int oflags, mode_t mode);
extern int do_unlink(int dirfd, const char *pathname);
extern int do_mkdir(int dirfd, const char *pathname, mode_t mode);
extern int do_rmdir(int dirfd, const char *pathname);
diff --git a/tools/scripts/make_rootfs/rootfsdir.sh b/tools/scripts/make_rootfs/rootfsdir.sh
index fe46c91f..ff7266cb 100755
--- a/tools/scripts/make_rootfs/rootfsdir.sh
+++ b/tools/scripts/make_rootfs/rootfsdir.sh
@@ -34,7 +34,7 @@ BIN_DIR=$1
LIB_DIR=$2
ROOTFS_DIR=$3
mkdir -p ${ROOTFS_DIR}/bin ${ROOTFS_DIR}/lib ${ROOTFS_DIR}/usr/bin ${ROOTFS_DIR}/usr/lib ${ROOTFS_DIR}/etc \
-${ROOTFS_DIR}/app ${ROOTFS_DIR}/data ${ROOTFS_DIR}/data/system ${ROOTFS_DIR}/data/system/param \
+${ROOTFS_DIR}/app ${ROOTFS_DIR}/data ${ROOTFS_DIR}/proc ${ROOTFS_DIR}/dev ${ROOTFS_DIR}/data/system ${ROOTFS_DIR}/data/system/param \
${ROOTFS_DIR}/system ${ROOTFS_DIR}/system/internal ${ROOTFS_DIR}/system/external
if [ -d "${BIN_DIR}" ] && [ "$(ls -A "${BIN_DIR}")" != "" ]; then
cp -f ${BIN_DIR}/* ${ROOTFS_DIR}/bin