!82 轻内核VFS层重构,添加路径缓存
Merge pull request !82 from 野生毛霉君/noEmployeeNum_ChangeID_13306388_wangchenyang
This commit is contained in:
commit
996047a7e2
17
Kconfig
17
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 ############################
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
* <ul>
|
||||
* <li>The parameter name should be a valid string.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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:
|
||||
* <ul><li>dirop_fat.h: the header file that contains the API declaration.</li></ul>
|
||||
* @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
|
||||
* <ul>
|
||||
* <li>The parameter dir_fat should be a valid pointer which opendir_fat returns.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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:
|
||||
* <ul><li>dirop_fat.h: the header file that contains the API declaration.</li></ul>
|
||||
* @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
|
||||
* <ul>
|
||||
* <li>The parameter dir_fat should be a valid pointer which opendir_fat returns.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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:
|
||||
* <ul><li>dirop_fat.h: the header file that contains the API declaration.</li></ul>
|
||||
* @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
|
||||
* <ul>
|
||||
* <li></li>
|
||||
* </ul>
|
||||
*
|
||||
* @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:
|
||||
* <ul><li>dirop_fat.h: the header file that contains the API declaration.</li></ul>
|
||||
* @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 */
|
|
@ -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 <dev_inodename> <sectors> <option> <label>\n");
|
||||
PRINTK(" dev_inodename : the name of dev\n");
|
||||
PRINTK(" format <dev_vnodename> <sectors> <option> <label>\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, ");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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 <dev_inodename> <sectors> <option> <label>\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 <dev_vnodename> <sectors> <option> <label>\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 */
|
||||
|
|
|
@ -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
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
* <ul>
|
||||
* None
|
||||
* </ul>
|
||||
*
|
||||
* @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
|
||||
|
|
|
@ -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
|
||||
#endif
|
||||
|
|
|
@ -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 <sys/stat.h>
|
||||
|
||||
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
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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 <sys/stat.h>
|
||||
#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_ */
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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 <dirent.h>
|
||||
#include <time.h>
|
||||
#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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
* <ul>
|
||||
|
@ -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
|
||||
* <ul>
|
||||
|
@ -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
|
||||
* <ul>
|
||||
|
@ -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
|
||||
|
|
|
@ -29,13 +29,16 @@
|
|||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "proc_fs.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statfs.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <sys/statfs.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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
|
|
@ -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 <sys/statfs.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#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
|
|
@ -29,7 +29,7 @@
|
|||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "proc_fs.h"
|
||||
#include "proc_file.h"
|
||||
#include <stdio.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 <dev_inodename>\n");
|
||||
PRINTK(" dev_inodename : the name of dev\n");
|
||||
PRINTK(" partinfo <dev_vnodename>\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;
|
||||
|
|
|
@ -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);
|
|||
* <ul><li>bcache.h</li></ul>
|
||||
*
|
||||
*/
|
||||
OsBcache *BlockCacheInit(struct inode *devNode,
|
||||
OsBcache *BlockCacheInit(struct Vnode *devNode,
|
||||
UINT32 sectorSize,
|
||||
UINT32 sectorPerBlock,
|
||||
UINT32 blockNum,
|
||||
|
|
|
@ -54,8 +54,6 @@ extern "C" {
|
|||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
extern FAR struct inode *g_root_inode;
|
||||
|
||||
/**
|
||||
* @ingroup disk
|
||||
* @brief Set usb mode.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 <ctype.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -82,7 +82,7 @@ typedef struct {
|
|||
UINT32 consoleSem;
|
||||
UINT32 shellEntryId;
|
||||
UINT32 consoleMask;
|
||||
struct inode *devInode;
|
||||
struct Vnode *devVnode;
|
||||
CHAR *name;
|
||||
INT32 fd;
|
||||
UINT32 refCount;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "shell.h"
|
||||
#include "unistd.h"
|
||||
#include "stdlib.h"
|
||||
#include "inode/inode.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -59,7 +59,6 @@ Case B:
|
|||
#include "unistd.h"
|
||||
#include "stdlib.h"
|
||||
#include "los_task.h"
|
||||
#include "inode/inode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include "dirent.h"
|
||||
#include "fs/fs.h"
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
#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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue