!82 轻内核VFS层重构,添加路径缓存

Merge pull request !82 from 野生毛霉君/noEmployeeNum_ChangeID_13306388_wangchenyang
This commit is contained in:
openharmony_ci 2021-03-23 14:45:14 +08:00 committed by Gitee
commit 996047a7e2
78 changed files with 5341 additions and 4165 deletions

17
Kconfig
View File

@ -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 ############################

View File

@ -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;

View File

@ -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)

View File

@ -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 */

View File

@ -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 */

4
fs/fat/os_adapt/fat_shellcmd.c Normal file → Executable file
View File

@ -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

View File

@ -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

View File

@ -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 */

11
fs/fat/virpart/src/virpart.c Normal file → Executable file
View File

@ -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

33
fs/fat/virpart/src/virpartff.c Normal file → Executable file
View File

@ -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

16
fs/include/disk.h Executable file → Normal file
View File

@ -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

36
fs/include/fs/fs_operation.h Executable file → Normal file
View File

@ -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

63
fs/include/fs/mount.h Normal file
View File

@ -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

View File

@ -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 */

64
fs/include/fs/vfs_util.h Normal file
View File

@ -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_ */

126
fs/include/fs/vnode.h Normal file
View File

@ -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_ */

View File

@ -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)

59
fs/jffs2/include/jffs2_hash.h Executable file
View File

@ -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

View File

@ -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

123
fs/jffs2/src/jffs2_hash.c Executable file
View File

@ -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

805
fs/jffs2/src/vfs_jffs2.c Executable file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

279
fs/proc/os_adapt/proc_vfs.c Executable file
View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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"

18
fs/vfs/Makefile Executable file → Normal file
View File

@ -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

15
fs/vfs/bcache/src/bcache.c Executable file → Normal file
View File

@ -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;

View File

@ -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);
}

View File

@ -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;

9
fs/vfs/include/bcache/bcache.h Executable file → Normal file
View File

@ -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,

2
fs/vfs/include/driver/driver.h Executable file → Normal file
View File

@ -54,8 +54,6 @@ extern "C" {
* Global Variables
****************************************************************************/
extern FAR struct inode *g_root_inode;
/**
* @ingroup disk
* @brief Set usb mode.

4
fs/vfs/include/operation/fs_other.h Executable file → Normal file
View File

@ -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

78
fs/vfs/mount.c Normal file
View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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"

154
fs/vfs/operation/fs_chattr.c Executable file → Normal file
View File

@ -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;
}

87
fs/vfs/operation/fs_check.c Executable file → Normal file
View File

@ -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;
}

29
fs/vfs/operation/fs_fallocate.c Executable file → Normal file
View File

@ -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? */

19
fs/vfs/operation/fs_fallocate64.c Executable file → Normal file
View File

@ -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? */

322
fs/vfs/operation/fs_file_mapping.c Executable file → Normal file
View File

@ -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;
}

10
fs/vfs/operation/fs_getlabel.c Executable file → Normal file
View File

@ -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;
}

50
fs/vfs/operation/fs_init.c Executable file → Normal file
View File

@ -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) {

View File

@ -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;

3
fs/vfs/operation/fs_readv.c Executable file → Normal file
View File

@ -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)
{

124
fs/vfs/operation/fs_utime.c Executable file → Normal file
View File

@ -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;
}

14
fs/vfs/operation/fs_virstatfs.c Executable file → Normal file
View File

@ -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

2
fs/vfs/operation/fs_writev.c Executable file → Normal file
View File

@ -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)
{

203
fs/vfs/path_cache.c Executable file
View File

@ -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);
}

62
fs/vfs/vfs_cmd/vfs_shellcmd.c Executable file → Normal file
View File

@ -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;
}

655
fs/vfs/vnode.c Executable file
View File

@ -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(&currentDir, &currentVnode, 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));
}

138
fs/vfs/vnode_hash.c Normal file
View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

46
kernel/base/vm/los_vm_filemap.c Executable file → Normal file
View File

@ -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)

157
kernel/common/console.c Executable file → Normal file
View File

@ -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__);

View File

@ -82,7 +82,7 @@ typedef struct {
UINT32 consoleSem;
UINT32 shellEntryId;
UINT32 consoleMask;
struct inode *devInode;
struct Vnode *devVnode;
CHAR *name;
INT32 fd;
UINT32 refCount;

18
kernel/common/los_hilog.c Executable file → Normal file
View File

@ -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) {

33
kernel/common/los_rootfs.c Executable file → Normal file
View File

@ -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) {

View File

@ -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

85
kernel/common/virtual_serial.c Executable file → Normal file
View File

@ -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

35
kernel/extended/liteipc/hm_liteipc.c Executable file → Normal file
View File

@ -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) {

1
kernel/extended/trace/los_trace.c Executable file → Normal file
View File

@ -40,7 +40,6 @@
#include "shell.h"
#include "unistd.h"
#include "stdlib.h"
#include "inode/inode.h"
#endif
#ifdef __cplusplus

View File

@ -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.

19
net/telnet/src/telnet_dev.c Executable file → Normal file
View File

@ -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;
}

View File

@ -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 \

View File

@ -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;

1
shell/full/src/cmds/date_shell.c Executable file → Normal file
View File

@ -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

1
shell/full/src/cmds/dmesg.c Executable file → Normal file
View File

@ -59,7 +59,6 @@ Case B:
#include "unistd.h"
#include "stdlib.h"
#include "los_task.h"
#include "inode/inode.h"
#ifdef __cplusplus
#if __cplusplus

64
syscall/fs_syscall.c Executable file → Normal file
View File

@ -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)) {

5
syscall/los_syscall.h Executable file → Normal file
View File

@ -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);

View File

@ -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