From 54c75c3b6f6f751fdb1a6d12071e307c9a5208fc Mon Sep 17 00:00:00 2001 From: mamingshuai Date: Thu, 11 Mar 2021 18:44:56 +0800 Subject: [PATCH] update openharmony 1.0.1 --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 13 --- .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 15 --- .gitignore | 0 README.OpenSource | 11 ++ drivers/pipes/pipe_common.c | 62 +++++++---- fs/dirent/fs_readdir.c | 144 ++++++++++++++++++------ fs/dirent/fs_seekdir.c | 7 +- fs/inode/fs_files.c | 94 ++++++---------- fs/inode/fs_foreachinode.c | 3 +- fs/inode/fs_inodereserve.c | 46 +++++++- fs/inode/inode.h | 3 + fs/mount/fs_foreachmountpoint.c | 6 +- fs/mount/fs_mount.c | 30 ++++- fs/mount/fs_umount.c | 26 +++++ fs/nfs/nfs_vfsops.c | 109 ++++++++++++------ fs/tmpfs/fs_tmpfs.c | 22 ++-- fs/vfs/fs_close.c | 9 ++ fs/vfs/fs_stat.c | 5 + fs/vfs/fs_statfs.c | 28 ++++- include/nuttx/fs/dirent_fs.h | 14 ++- include/nuttx/fs/fs.h | 1 + include/sys/statfs.h | 155 ++++++++++++++++++++++++++ 22 files changed, 596 insertions(+), 207 deletions(-) delete mode 100755 .gitee/ISSUE_TEMPLATE.zh-CN.md delete mode 100755 .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md mode change 100755 => 100644 .gitignore create mode 100755 README.OpenSource mode change 100755 => 100644 fs/inode/fs_inodereserve.c mode change 100755 => 100644 fs/mount/fs_umount.c create mode 100755 include/sys/statfs.h diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md deleted file mode 100755 index f09d98d..0000000 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,13 +0,0 @@ -### 该问题是怎么引起的? - - - -### 重现步骤 - - - -### 报错信息 - - - - diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md deleted file mode 100755 index 33948fd..0000000 --- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,15 +0,0 @@ -### 相关的Issue - - -### 原因(目的、解决的问题等) - - -### 描述(做了什么,变更了什么) - - -### 测试用例(新增、改动、可能影响的功能) - - - - - diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/README.OpenSource b/README.OpenSource new file mode 100755 index 0000000..9d96b93 --- /dev/null +++ b/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name" : "NuttX", + "License" : "BSD 3-Clause License", + "License File" : "COPYING", + "Version Number" : "8.2", + "Owner" : "tonghaoyang1@huawei.com", + "Upstream URL" : "http://www.nuttx.org", + "Description" : "Apache NuttX is a mature, real-time embedded operating system (RTOS)." + } +] diff --git a/drivers/pipes/pipe_common.c b/drivers/pipes/pipe_common.c index e7ade69..0b3a53c 100755 --- a/drivers/pipes/pipe_common.c +++ b/drivers/pipes/pipe_common.c @@ -395,6 +395,7 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len) ssize_t nread = 0; int sval; int ret; + volatile int num; if (dev == NULL) { @@ -472,24 +473,48 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len) nread++; } - /* If O_NONBLOCK was set, then break */ - - if (filep->f_oflags & O_NONBLOCK) - { - break; - } - - /* Is the read complete? */ - + /* Is the read complete? */ if ((size_t)nread >= len) { break; } - /* wait for something to be written to the pipe */ + /* Notify all waiting writers that bytes have been read from the buffer */ - sem_post(&dev->d_wrsem); + num = 0; + while (sem_getvalue(&dev->d_wrsem, &sval) == 0 && sval == 0) + { + sem_post(&dev->d_wrsem); + num++; + } + + /* If there are no writers be awakened, then return */ + + if (num == 0 || num == 1) + { + pipecommon_pollnotify(dev, POLLOUT); + sem_post(&dev->d_bfsem); + return nread; + } + + /* If there are no writers on the pipe, then return the number of read bytes */ + + if (dev->d_nwriters <= 0) + { + sem_post(&dev->d_wrsem); + pipecommon_pollnotify(dev, POLLOUT); + sem_post(&dev->d_bfsem); + return nread; + } + + /* wait for something to be written to the pipe */ pipecommon_pollnotify(dev, POLLOUT); + + while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval != 0) + { + sem_wait(&dev->d_rdsem); + } + sem_post(&dev->d_bfsem); ret = sem_wait(&dev->d_rdsem); @@ -503,16 +528,6 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len) { return ret; } - - /* If there are no writers on the pipe, then return end of file */ - - if (dev->d_nwriters <= 0) - { - sem_post(&dev->d_wrsem); - pipecommon_pollnotify(dev, POLLOUT); - sem_post(&dev->d_bfsem); - return nread; - } } /* Notify all waiting writers that bytes have been removed from the buffer */ @@ -679,7 +694,12 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, /* There is more to be written.. wait for data to be removed from the pipe */ + while (sem_getvalue(&dev->d_wrsem, &sval) == 0 && sval != 0) + { + pipecommon_semtake(&dev->d_wrsem); + } sem_post(&dev->d_bfsem); + pipecommon_semtake(&dev->d_wrsem); pipecommon_semtake(&dev->d_bfsem); } diff --git a/fs/dirent/fs_readdir.c b/fs/dirent/fs_readdir.c index 6260e0e..3f0fd37 100755 --- a/fs/dirent/fs_readdir.c +++ b/fs/dirent/fs_readdir.c @@ -49,6 +49,7 @@ #include "fs/dirent_fs.h" #include "inode/inode.h" +#include "sys/statfs.h" #include "user_copy.h" /**************************************************************************** @@ -77,8 +78,7 @@ static inline int readpseudodir(struct fs_dirent_s *idir) } /* Copy the inode name into the dirent structure */ - - ret = strncpy_s(idir->fd_dir.d_name, NAME_MAX + 1, idir->u.pseudo.fd_next->i_name, NAME_MAX); + ret = strncpy_s(idir->fd_dir[0].d_name, NAME_MAX + 1, idir->u.pseudo.fd_next->i_name, NAME_MAX); if (ret != EOK) { return -ENAMETOOLONG; @@ -86,24 +86,22 @@ static inline int readpseudodir(struct fs_dirent_s *idir) /* If the node has file operations, we will say that it is a file. */ - idir->fd_dir.d_type = 0; - idir->fd_dir.d_off = idir->fd_position; - idir->fd_dir.d_reclen = sizeof(struct dirent); + idir->fd_dir[0].d_type = 0; if (idir->u.pseudo.fd_next->u.i_ops) { #ifndef CONFIG_DISABLE_MOUNTPOINT if (INODE_IS_BLOCK(idir->u.pseudo.fd_next)) { - idir->fd_dir.d_type |= DT_BLK; + idir->fd_dir[0].d_type |= DT_BLK; } if (INODE_IS_MOUNTPT(idir->u.pseudo.fd_next)) { - idir->fd_dir.d_type |= DT_DIR; + idir->fd_dir[0].d_type |= DT_DIR; } else #endif { - idir->fd_dir.d_type |= DT_CHR; + idir->fd_dir[0].d_type |= DT_CHR; } } @@ -114,7 +112,7 @@ static inline int readpseudodir(struct fs_dirent_s *idir) if (idir->u.pseudo.fd_next->i_child || !idir->u.pseudo.fd_next->u.i_ops) { - idir->fd_dir.d_type |= DT_DIR; + idir->fd_dir[0].d_type |= DT_DIR; } /* Now get the inode to vist next time that readdir() is called */ @@ -141,6 +139,47 @@ static inline int readpseudodir(struct fs_dirent_s *idir) return OK; } +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: handlezpfsdir + * Description: + * The handlezpfsdir() function handle with the inode with zpfs magic + * + * Input Parameters: + * idir -- the pointer of one dir + * + * Returned Value: + * none + ****************************************************************************/ +#ifdef LOSCFG_FS_ZPFS +static inline void handlezpfsdir(struct fs_dirent_s *idir) +{ + struct statfs buf; + int ret; + /* Maybe there are two or more zpfs nodes together, so we need one loop */ + do + { + if (!idir->u.pseudo.fd_next || !INODE_IS_MOUNTPT(idir->u.pseudo.fd_next) || + !idir->u.pseudo.fd_next->u.i_mops || !idir->u.pseudo.fd_next->u.i_mops->statfs) + { + return; + } + ret = idir->u.pseudo.fd_next->u.i_mops->statfs(idir->u.pseudo.fd_next, &buf); + if (ret != OK || buf.f_type != ZPFS_MAGIC) + { + return; + } + if (readpseudodir(idir) == OK) + { + idir->fd_position++; + } + } while (1); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -165,12 +204,12 @@ static inline int readpseudodir(struct fs_dirent_s *idir) * EBADF - Invalid directory stream descriptor dir * ****************************************************************************/ -static struct dirent *__readdir(DIR *dirp) +static struct dirent *__readdir(DIR *dirp, int *lencnt) { FAR struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp; struct inode *inode_ptr = NULL; int ret = 0; - + int file_cnt = 0; /* Verify that we were provided with a valid directory structure */ if (!idir || idir->fd_status != DIRENT_MAGIC) @@ -200,13 +239,20 @@ static struct dirent *__readdir(DIR *dirp) */ if (DIRENT_ISPSEUDONODE(idir->fd_flags)) { +#ifdef LOSCFG_FS_ZPFS + /* if the current node has the zpfs magic, we continue to skip the node */ + handlezpfsdir(idir); +#endif /* The node is part of the root pseudo file system */ ret = readpseudodir(idir); - if (!ret) + if (ret == OK) { - idir->fd_position++; - return &idir->fd_dir; + idir->fd_position++; + idir->fd_dir[0].d_off = idir->fd_position; + idir->fd_dir[0].d_reclen = (uint16_t)sizeof(struct dirent); + *lencnt = sizeof(struct dirent); + return &(idir->fd_dir[0]); } } @@ -223,23 +269,33 @@ static struct dirent *__readdir(DIR *dirp) } /* Perform the readdir() operation */ - - ret = inode_ptr->u.i_mops->readdir(inode_ptr, idir); - if (!ret) +#ifdef LOSCFG_ENABLE_READ_BUFFER + idir->read_cnt = MAX_DIRENT_NUM; +#else + idir->read_cnt = 1; +#endif + file_cnt = inode_ptr->u.i_mops->readdir(inode_ptr, idir); + if (file_cnt > 0) { - idir->fd_position++; - return &idir->fd_dir; + *lencnt = file_cnt * sizeof(struct dirent); + return &(idir->fd_dir[0]); } } #endif - ret = -ret; - errout: if (ret != OK) { + if (ret < 0) + { + ret = -ret; + } set_errno(ret); } + else if (file_cnt <= 0) + { + set_errno(ENOENT); + } return (struct dirent *)NULL; } @@ -272,16 +328,40 @@ FAR struct dirent *readdir(DIR *dirp) { int ret; int old_err = get_errno(); - struct dirent *de = __readdir(dirp); + int lencnt = 0; + struct dirent *de = NULL; + FAR struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp; + int dirlen; - if (de == NULL) +#ifdef LOSCFG_ENABLE_READ_BUFFER + dirlen = MAX_DIRENT_NUM; +#else + dirlen = 1; +#endif + if (idir->cur_pos != 0 && idir->cur_pos < dirlen && idir->cur_pos < idir->end_pos) { - ret = get_errno(); - /* Special case: ret = -ENOENT is end of file */ - - if (ret == ENOENT) + de = &(idir->fd_dir[idir->cur_pos]); + if (idir->cur_pos == dirlen) { - set_errno(old_err); + idir->cur_pos = 0; + } + idir->cur_pos++; + return de; + } else { + de = __readdir(dirp, &lencnt); + idir->end_pos = lencnt / sizeof(struct dirent); + idir->cur_pos = 1; + + if (de == NULL) + { + idir->cur_pos = 0; + ret = get_errno(); + /* Special case: ret = -ENOENT is end of file */ + + if (ret == ENOENT) + { + set_errno(old_err); + } } } return de; @@ -292,7 +372,7 @@ FAR struct dirent *readdir(DIR *dirp) int do_readdir(int fd, struct dirent **de, unsigned int count) { struct dirent *de_src = NULL; - + int lencnt = 0; /* Did we get a valid file descriptor? */ #if CONFIG_NFILE_DESCRIPTORS > 0 @@ -321,8 +401,7 @@ int do_readdir(int fd, struct dirent **de, unsigned int count) } /* Then let do_readdir do all of the work */ - - de_src = __readdir(filep->f_dir); + de_src = __readdir(filep->f_dir, &lencnt); if (de_src == NULL) { /* Special case: ret = -ENOENT is end of file */ @@ -330,7 +409,8 @@ int do_readdir(int fd, struct dirent **de, unsigned int count) } *de = de_src; - return sizeof(*de_src); + lencnt = (lencnt != 0) ? lencnt : sizeof(*de_src); + return lencnt; } #endif diff --git a/fs/dirent/fs_seekdir.c b/fs/dirent/fs_seekdir.c index 568189a..f9621d7 100755 --- a/fs/dirent/fs_seekdir.c +++ b/fs/dirent/fs_seekdir.c @@ -71,7 +71,7 @@ static inline void seekpseudodir(struct fs_dirent_s *idir, off_t offset) if (offset < idir->fd_position) { pos = 0; - curr = idir->fd_root; + curr = idir->fd_root->i_child; } else { @@ -153,10 +153,12 @@ static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset) * directory entries until we are at the desired position. */ + idir->read_cnt = 1; + while (pos < offset) { if (!inode->u.i_mops || !inode->u.i_mops->readdir || - inode->u.i_mops->readdir(inode, idir) < 0) + inode->u.i_mops->readdir(inode, idir) <= 0) { /* We can't read the next entry and there is no way to return * an error indication. @@ -171,7 +173,6 @@ static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset) } /* If we get here the directory position has been successfully set */ - idir->fd_position = pos; } #endif diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index b8bd5ab..6133962 100755 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -59,6 +59,7 @@ #endif #include "los_process_pri.h" #include "los_vm_filemap.h" +#include "mqueue.h" #define ferr PRINTK #if CONFIG_NFILE_DESCRIPTORS > 0 @@ -176,6 +177,10 @@ static int _files_close(FAR struct file *filep) } } + /* Drop file caches */ + + (void)remove_mapping_nolock(filep->f_path, filep); + /* And release the inode */ inode_release(inode); @@ -483,11 +488,7 @@ int files_allocate(FAR struct inode *inode_ptr, int oflags, off_t pos,void* priv list->fl_files[i].f_dir = NULL; list->fl_files[i].f_magicnum = files_magic_generate(); process_files = OsCurrProcessGet()->files; - if (process_files) - { - FD_SET(i, process_files->fdt->open_fds); - } - else + if (process_files == NULL) { PRINT_ERR("process files is NULL, %s %d\n", __FUNCTION__ ,__LINE__); _files_semgive(list); @@ -535,11 +536,7 @@ static int files_close_internal(int fd, LosProcessCB *processCB) _files_semtake(list); process_files = processCB->files; - if (process_files) - { - FD_CLR(fd, process_files->fdt->open_fds); - } - else + if (process_files == NULL) { PRINT_ERR("process files is NULL, %s %d\n", __FUNCTION__ ,__LINE__); _files_semgive(list); @@ -598,7 +595,6 @@ int files_close(int fd) void files_release(int fd) { FAR struct filelist *list = NULL; - struct files_struct *process_files = NULL; list = sched_getfiles(); DEBUGASSERT(list); @@ -618,11 +614,6 @@ void files_release(int fd) list->fl_files[fd].f_mapping = NULL; list->fl_files[fd].f_dir = NULL; - process_files = OsCurrProcessGet()->files; - if (process_files) - { - FD_CLR(fd, process_files->fdt->open_fds); - } clear_bit(fd, bitmap); _files_semgive(list); } @@ -722,6 +713,16 @@ void files_refer(int fd) _files_semgive(list); } +void alloc_std_fd(struct fd_table_s *fdt) +{ + fdt->ft_fds[STDIN_FILENO].sysFd = STDIN_FILENO; + fdt->ft_fds[STDOUT_FILENO].sysFd = STDOUT_FILENO; + fdt->ft_fds[STDERR_FILENO].sysFd = STDERR_FILENO; + FD_SET(STDIN_FILENO, fdt->proc_fds); + FD_SET(STDOUT_FILENO, fdt->proc_fds); + FD_SET(STDERR_FILENO, fdt->proc_fds); +} + static void copy_fds(const struct fd_table_s *new_fdt, const struct fd_table_s *old_fdt) { unsigned int sz; @@ -731,7 +732,6 @@ static void copy_fds(const struct fd_table_s *new_fdt, const struct fd_table_s * { (void)memcpy_s(new_fdt->ft_fds, sz, old_fdt->ft_fds, sz); } - (void)memcpy_s(new_fdt->open_fds, sizeof(fd_set), old_fdt->open_fds, sizeof(fd_set)); (void)memcpy_s(new_fdt->proc_fds, sizeof(fd_set), old_fdt->proc_fds, sizeof(fd_set)); } @@ -740,20 +740,27 @@ static void copy_fd_table(struct fd_table_s *new_fdt, struct fd_table_s *old_fdt copy_fds((const struct fd_table_s *)new_fdt, (const struct fd_table_s *)old_fdt); for (int i = 0; i < new_fdt->max_fds; i++) { - if (FD_ISSET(i, new_fdt->open_fds)) - { - files_refer(i); - } -#if defined(LOSCFG_NET_LWIP_SACK) if (FD_ISSET(i, new_fdt->proc_fds)) { int sysFd = GetAssociatedSystemFd(i); - if (sysFd >= CONFIG_NFILE_DESCRIPTORS && sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) + if ((sysFd >= 0) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) + { + files_refer(sysFd); + } +#if defined(LOSCFG_NET_LWIP_SACK) + if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) { socks_refer(sysFd); } - } #endif +#if defined(LOSCFG_COMPAT_POSIX) + if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) + { + mqueue_refer(sysFd); + } +#endif + + } } } @@ -771,7 +778,6 @@ static struct fd_table_s * alloc_fd_table(unsigned int numbers) if (!numbers) { fdt->ft_fds = NULL; - fdt->open_fds = NULL; fdt->proc_fds = NULL; return fdt; } @@ -782,10 +788,6 @@ static struct fd_table_s * alloc_fd_table(unsigned int numbers) } fdt->ft_fds = data; - /* 0,1,2 be distributed to stdin,stdout,stderr default */ - fdt->ft_fds[STDIN_FILENO].sysFd = STDIN_FILENO; - fdt->ft_fds[STDOUT_FILENO].sysFd = STDOUT_FILENO; - fdt->ft_fds[STDERR_FILENO].sysFd = STDERR_FILENO; for (int i = STDERR_FILENO + 1; i < numbers; i++) { fdt->ft_fds[i].sysFd = -1; @@ -797,28 +799,14 @@ static struct fd_table_s * alloc_fd_table(unsigned int numbers) goto out_arr; } (VOID)memset_s(data, sizeof(fd_set), 0, sizeof(fd_set)); - fdt->open_fds = data; - FD_SET(STDIN_FILENO, fdt->open_fds); - FD_SET(STDOUT_FILENO, fdt->open_fds); - FD_SET(STDERR_FILENO, fdt->open_fds); - - data = LOS_MemAlloc(m_aucSysMem0, sizeof(fd_set)); - if (!data) - { - goto out_all; - } - (VOID)memset_s(data, sizeof(fd_set), 0, sizeof(fd_set)); fdt->proc_fds = data; - FD_SET(STDIN_FILENO, fdt->proc_fds); - FD_SET(STDOUT_FILENO, fdt->proc_fds); - FD_SET(STDERR_FILENO, fdt->proc_fds); + + alloc_std_fd(fdt); (void)sem_init(&fdt->ft_sem, 0, 1); return fdt; -out_all: - (VOID)LOS_MemFree(m_aucSysMem0, fdt->open_fds); out_arr: (VOID)LOS_MemFree(m_aucSysMem0, fdt->ft_fds); out_fdt: @@ -915,25 +903,16 @@ void delete_files(LosProcessCB *processCB, struct files_struct *files) for (int i = 0; i < files->fdt->max_fds; i++) { - if (FD_ISSET(i, files->fdt->open_fds)) - { - files_close_internal(i, processCB); - } -#if defined(LOSCFG_NET_LWIP_SACK) if (FD_ISSET(i, files->fdt->proc_fds)) { - int sysFd = GetAssociatedSystemFd(i); - if (sysFd >= CONFIG_NFILE_DESCRIPTORS && sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) - { - close(sysFd); - } + int sysFd = DisassociateProcessFd(i); + close(sysFd); + FreeProcessFd(i); } -#endif } (VOID)sem_destroy(&files->fdt->ft_sem); (VOID)LOS_MemFree(m_aucSysMem0, files->fdt->ft_fds); - (VOID)LOS_MemFree(m_aucSysMem0, files->fdt->open_fds); (VOID)LOS_MemFree(m_aucSysMem0, files->fdt->proc_fds); (VOID)LOS_MemFree(m_aucSysMem0, files->fdt); out_file: @@ -992,7 +971,6 @@ void delete_files_snapshot(struct files_struct *files) (VOID)sem_destroy(&files->fdt->ft_sem); (VOID)LOS_MemFree(m_aucSysMem0, files->fdt->ft_fds); - (VOID)LOS_MemFree(m_aucSysMem0, files->fdt->open_fds); (VOID)LOS_MemFree(m_aucSysMem0, files->fdt->proc_fds); (VOID)LOS_MemFree(m_aucSysMem0, files->fdt); out_file: diff --git a/fs/inode/fs_foreachinode.c b/fs/inode/fs_foreachinode.c index 70d6be5..592cae9 100755 --- a/fs/inode/fs_foreachinode.c +++ b/fs/inode/fs_foreachinode.c @@ -95,7 +95,6 @@ static int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info) for (; node; node = node->i_peer) { /* Give the next inode to the callback */ - ret = info->handler(node, info->path, info->arg); /* Break out of the loop early if the handler returns a non-zero @@ -129,7 +128,7 @@ static int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info) /* Append the path segment to this inode and recurse */ ret = snprintf_s(&info->path[pathlen], CONFIG_PATH_MAX - pathlen, - CONFIG_PATH_MAX - pathlen - 1, "/%s", node->i_name); + CONFIG_PATH_MAX - pathlen - 1, "%s/", node->i_name); if (ret < 0) { ret = -ENAMETOOLONG; diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c old mode 100755 new mode 100644 index d905bf7..76f5a27 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -190,7 +190,7 @@ static void inode_insert(FAR struct inode *node, ****************************************************************************/ /**************************************************************************** - * Name: inode_reserve + * Name: inode_reserve_rootdir * * Description: * Reserve an (initialized) inode the pseudo file system. The initial @@ -199,6 +199,7 @@ static void inode_insert(FAR struct inode *node, * Input Parameters: * path - The path to the inode to create * inode - The location to return the inode pointer + * force - force to reserve the inode if the value is true * * Returned Value: * Zero on success (with the inode point in 'inode'); A negated errno @@ -213,7 +214,10 @@ static void inode_insert(FAR struct inode *node, * ****************************************************************************/ -int inode_reserve(FAR const char *path, FAR struct inode **inode_ptr) +#ifndef LOSCFG_FS_ZPFS +static inline +#endif +int inode_reserve_rootdir(FAR const char *path, FAR struct inode **inode_ptr, bool force) { FAR const char *name = path; FAR const char *relpath; @@ -247,7 +251,8 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode_ptr) #ifndef CONFIG_DISABLE_MOUNTPOINT else if (INODE_IS_MOUNTPT(pathnode)) { - if ((pathnode != g_root_inode) || IsInRootfs(relpath)) + if ((pathnode != g_root_inode) || + (force ? false : IsInRootfs(relpath))) { /* The node cannot be a child of a mounted point, except the root node. */ @@ -266,10 +271,9 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode_ptr) } } - if (check_name(name) == false) + if ((force == false) && (check_name(name) == false)) { /* check the path has no '/' symbol, prevent to create multilevel directory */ - return -EINVAL; } @@ -317,4 +321,34 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode_ptr) return -ENOMEM; } -} \ No newline at end of file +} + +/**************************************************************************** + * Name: inode_reserve + * + * Description: + * Reserve an (initialized) inode the pseudo file system. The initial + * reference count on the new inode is zero. + * + * Input Parameters: + * path - The path to the inode to create + * inode - The location to return the inode pointer + * + * Returned Value: + * Zero on success (with the inode point in 'inode'); A negated errno + * value is returned on failure: + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + * Assumptions: + * Caller must hold the inode semaphore + * + ****************************************************************************/ + +int inode_reserve(FAR const char *path, FAR struct inode **inode_ptr) +{ + return inode_reserve_rootdir(path, inode_ptr, false); +} + diff --git a/fs/inode/inode.h b/fs/inode/inode.h index 671d56f..72c82e5 100755 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -355,6 +355,9 @@ bool IsInRootfs(const char *relpath); ****************************************************************************/ int inode_reserve(FAR const char *path, FAR struct inode **inode); +#ifdef LOSCFG_FS_ZPFS +int inode_reserve_rootdir(FAR const char *path, FAR struct inode **inode, bool force); +#endif /**************************************************************************** * Name: inode_unlink diff --git a/fs/mount/fs_foreachmountpoint.c b/fs/mount/fs_foreachmountpoint.c index b219b27..156bfe0 100755 --- a/fs/mount/fs_foreachmountpoint.c +++ b/fs/mount/fs_foreachmountpoint.c @@ -110,7 +110,7 @@ static int mountpoint_filter(FAR struct inode *node, /* Append the inode name to the directory path */ - ret = snprintf_s(&dirpath[pathlen], PATH_MAX - pathlen, PATH_MAX - pathlen - 1, "/%s", node->i_name); + ret = snprintf_s(&dirpath[pathlen], PATH_MAX - pathlen, PATH_MAX - pathlen - 1, "%s/", node->i_name); if (ret < 0) { return -ENAMETOOLONG; @@ -123,6 +123,10 @@ static int mountpoint_filter(FAR struct inode *node, { /* And pass the full path and file system status to the handler */ + if (strlen(dirpath) > 1) { + dirpath[strlen(dirpath) - 1] = '\0'; + } + ret = info->handler(dirpath, &statbuf, info->arg); } diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index 605916d..63f0f23 100755 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -51,7 +51,7 @@ #include "inode/inode.h" #include "stdlib.h" #include "driver/driver.h" -#if defined(LOSCFG_FS_JFFS) +#ifdef LOSCFG_DRIVERS_MTD #include "mtd_partition.h" #endif #ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION @@ -59,6 +59,10 @@ #endif #include "los_tables.h" +#ifdef LOSCFG_FS_ZPFS +#include "vfs_zpfs.h" +#endif + /* At least one filesystem must be defined, or this file will not compile. * It may be desire-able to make filesystems dynamically registered at * some time in the future, but at present, this file needs to know about @@ -161,7 +165,7 @@ int mount(const char *source, const char *target, const struct fsmap_t *fsmap = NULL; const struct mountpt_operations *mops = NULL; -#if defined(LOSCFG_FS_JFFS) +#ifdef LOSCFG_DRIVERS_MTD mtd_partition *partition = NULL; #endif @@ -220,7 +224,20 @@ int mount(const char *source, const char *target, */ inode_semtake(); - +#ifdef LOSCFG_FS_ZPFS + if (strcmp(filesystemtype, ZPFS_NAME) == 0) + { + ret = ZpfsPrepare(source, fullpath, &mountpt_inode, true); + if (ret < 0) + { + errcode = -ret; + goto errout_with_semaphore; + } + data = (const void *)mountpt_inode->i_private; + } + else + { +#endif mountpt_inode = inode_search((const char **)&fullpath, (struct inode **)NULL, (struct inode **)NULL, \ (const char **)NULL); @@ -244,6 +261,9 @@ int mount(const char *source, const char *target, errcode = EINVAL; goto errout_with_semaphore; } +#ifdef LOSCFG_FS_ZPFS + } +#endif mountpt_inode ->mountflags = mountflags; @@ -277,7 +297,7 @@ int mount(const char *source, const char *target, goto errout_with_mountpt; } } -#if defined(LOSCFG_FS_JFFS) +#ifdef LOSCFG_DRIVERS_MTD if (fsmap->is_mtd_support && (blkdrvr_inode != NULL)) { partition = (mtd_partition *)blkdrvr_inode->i_private; @@ -316,7 +336,7 @@ int mount(const char *source, const char *target, } errcode = -ret; -#if defined(LOSCFG_FS_JFFS) +#ifdef LOSCFG_DRIVERS_MTD if (fsmap->is_mtd_support && (blkdrvr_inode != NULL) && (partition != NULL)) { free(partition->mountpoint_name); diff --git a/fs/mount/fs_umount.c b/fs/mount/fs_umount.c old mode 100755 new mode 100644 index cdfaf9b..5be2824 --- a/fs/mount/fs_umount.c +++ b/fs/mount/fs_umount.c @@ -49,6 +49,9 @@ #include "string.h" #include "disk.h" +#ifdef LOSCFG_FS_ZPFS +#include "vfs_zpfs.h" +#endif /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -101,6 +104,11 @@ int umount(const char *target) const char *relpath = NULL; struct inode_search_s desc; int ret; +#ifdef LOSCFG_FS_ZPFS + bool isZpfs = false; + struct inode zpfsInode; +#endif + /* Verify required pointer arguments */ if (target == NULL) @@ -159,6 +167,17 @@ int umount(const char *target) } inode_semtake(); /* Hold the semaphore through the unbind logic */ + +#ifdef LOSCFG_FS_ZPFS + if (IsZpfsFileSystem(mountpt_inode)) + { + isZpfs = true; + zpfsInode.i_private = mountpt_inode->i_private; + zpfsInode.u.i_ops = mountpt_inode->u.i_ops; + zpfsInode.i_flags = mountpt_inode->i_flags; + } +#endif + if (mountpt_inode->i_crefs == 1) { status = mountpt_inode->u.i_mops->unbind(mountpt_inode->i_private, &blkdrvr_inode); @@ -207,6 +226,13 @@ int umount(const char *target) inode_release(blkdrvr_inode); } +#ifdef LOSCFG_FS_ZPFS + if (isZpfs) + { + ZpfsCleanUp((void*)&zpfsInode, fullpath); + } +#endif + free(fullpath); return OK; diff --git a/fs/nfs/nfs_vfsops.c b/fs/nfs/nfs_vfsops.c index d1f2c73..10a98a3 100755 --- a/fs/nfs/nfs_vfsops.c +++ b/fs/nfs/nfs_vfsops.c @@ -253,6 +253,30 @@ const struct mountpt_operations nfs_operations = FSMAP_ENTRY(nfs_fsmap, "nfs", nfs_operations, FALSE, FALSE); +static int nfs_2_vfs(int result) +{ + int status; + + if ((result < NFS_OK) || (result > NFSERR_NOTEMPTY)) { + return result; + } + + /* Nfs errno to Libc errno */ + switch (result) { + case NFSERR_NAMETOL: + status = ENAMETOOLONG; + break; + case NFSERR_NOTEMPTY: + status = ENOTEMPTY; + break; + default: + status = result; + break; + } + + return status; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -875,14 +899,6 @@ static int nfs_close(FAR struct file *filep) nfs_mux_release(nmp); - /* Drop the NFS file page cache if no one, except me, is working on it, to ensure - * the close-to-open cache consistency for NFS files. - * And because the outer "files_close" has locked the global file list already, - * we use the nolock version here. - */ - - (void)remove_mapping_nolock(filep->f_path, filep); - return ret; } @@ -1072,6 +1088,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, uint32_t tmp; int committed = NFSV3WRITE_UNSTABLE; int error; + char *temp_buffer; /* Sanity checks */ @@ -1121,6 +1138,16 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, fvdbg("Write %d bytes to offset %d\n", buflen, np->n_fpos); + /* Allocate memory for data */ + + bufsize = (buflen < nmp->nm_wsize) ? buflen : nmp->nm_wsize; + temp_buffer = malloc(bufsize); + if (temp_buffer == NULL) + { + error = ENOMEM; + goto errout_with_mutex; + } + /* Now loop until we send the entire user buffer */ writesize = 0; @@ -1146,6 +1173,14 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, writesize -= (bufsize - nmp->nm_buflen); } + /* Copy a chunk of the user data into the temporary buffer */ + + if (LOS_CopyToKernel(temp_buffer, writesize, buffer, writesize) != 0) + { + error = EINVAL; + goto errout_with_memfree; + } + /* Initialize the request. Here we need an offset pointer to the write * arguments, skipping over the RPC header. Write is unique among the * RPC calls in that the entry RPC calls messasge lies in the I/O buffer @@ -1176,16 +1211,16 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, *ptr++ = txdr_unsigned((uint32_t)committed); reqlen += 2*sizeof(uint32_t); - /* Copy a chunk of the user data into the I/O buffer */ + /* Copy a chunk of the user data into the I/O buffer from temporary buffer */ *ptr++ = txdr_unsigned(writesize); reqlen += sizeof(uint32_t); - if (LOS_CopyToKernel(ptr, writesize, buffer, writesize) != 0) + error = memcpy_s(ptr, writesize, temp_buffer, writesize); + if (error != EOK) { - error = EINVAL; - goto errout_with_mutex; + error = ENOBUFS; + goto errout_with_memfree; } - reqlen += uint32_alignup(writesize); /* Perform the write */ @@ -1198,7 +1233,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, if (error) { ferr("ERROR: nfs_request failed: %d\n", error); - goto errout_with_mutex; + goto errout_with_memfree; } /* Get a pointer to the WRITE reply data */ @@ -1234,7 +1269,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, if (tmp < 1 || tmp > writesize) { error = EIO; - goto errout_with_mutex; + goto errout_with_memfree; } writesize = tmp; @@ -1252,9 +1287,11 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, buffer += writesize; } + free(temp_buffer); nfs_mux_release(nmp); return byteswritten; - +errout_with_memfree: + free(temp_buffer); errout_with_mutex: nfs_mux_release(nmp); return -error; @@ -1668,7 +1705,6 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) size_t d_name_size; int reqlen; int error = 0; - finfo("Entry\n"); /* Sanity checks */ @@ -1824,7 +1860,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) /* Get the length and point to the name */ - tmp = *ptr++; /*lint !e662 !e661*/ + tmp = *ptr++; /*lint !e662 !e661*/ entry->name_len = fxdr_unsigned(uint32_t, tmp); entry->contents = (uint8_t *)malloc(entry->name_len + 1); if (!entry->contents) @@ -1919,8 +1955,8 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) goto errout_with_mutex; } - d_name_size = sizeof(dir->fd_dir.d_name); - error = memcpy_s(dir->fd_dir.d_name, d_name_size, (const char *)entry_pos->contents, (size_t)entry_pos->name_len); + d_name_size = sizeof(dir->fd_dir[0].d_name); + error = memcpy_s(dir->fd_dir[0].d_name, d_name_size, (const char *)entry_pos->contents, (size_t)entry_pos->name_len); if (error != EOK) { error = ENOBUFS; @@ -1928,21 +1964,21 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) } if (entry_pos->name_len >= d_name_size) { - dir->fd_dir.d_name[d_name_size - 1] = '\0'; + dir->fd_dir[0].d_name[d_name_size - 1] = '\0'; } else { - dir->fd_dir.d_name[entry_pos->name_len] = '\0'; + dir->fd_dir[0].d_name[entry_pos->name_len] = '\0'; } nfs_dir->nfs_entries = entry_pos->next; NFS_DIR_ENTRY_FREE(entry_pos); - fvdbg("name: \"%s\"\n", dir->fd_dir.d_name); + fvdbg("name: \"%s\"\n", dir->fd_dir[0].d_name); fhandle.length = (uint32_t)nfs_dir->nfs_fhsize; (void)memcpy_s(&fhandle.handle, DIRENT_NFS_MAXHANDLE, nfs_dir->nfs_fhandle, DIRENT_NFS_MAXHANDLE); - error = nfs_lookup(nmp, dir->fd_dir.d_name, &fhandle, &obj_attributes, NULL); + error = nfs_lookup(nmp, dir->fd_dir[0].d_name, &fhandle, &obj_attributes, NULL); if (error != OK) { ferr("ERROR: nfs_lookup failed: %d\n", error); @@ -1961,28 +1997,29 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) break; case NFREG: /* Regular file */ - dir->fd_dir.d_type = DT_REG; + dir->fd_dir[0].d_type = DT_REG; break; case NFDIR: /* Directory */ - dir->fd_dir.d_type = DT_DIR; + dir->fd_dir[0].d_type = DT_DIR; break; case NFBLK: /* Block special device file */ - dir->fd_dir.d_type = DT_BLK; + dir->fd_dir[0].d_type = DT_BLK; break; case NFFIFO: /* Named FIFO */ case NFCHR: /* Character special device file */ - dir->fd_dir.d_type = DT_CHR; + dir->fd_dir[0].d_type = DT_CHR; break; } - dir->fd_dir.d_off = dir->fd_position; - dir->fd_dir.d_reclen = (uint16_t)sizeof(struct dirent); - finfo("type: %d->%d\n", (int)tmp, dir->fd_dir.d_type); + finfo("type: %d->%d\n", (int)tmp, dir->fd_dir[0].d_type); + dir->fd_position++; + dir->fd_dir[0].d_off = dir->fd_position; + dir->fd_dir[0].d_reclen = (uint16_t)sizeof(struct dirent); nfs_mux_release(nmp); - return OK; + return 1; errout_with_memory: for (entry_pos = nfs_dir->nfs_entries; entry_pos != NULL; entry_pos = nfs_dir->nfs_entries) @@ -2970,7 +3007,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) errout_with_mutex: nfs_mux_release(nmp); - return -error; + return -nfs_2_vfs(error); } static int nfs_getfilename(char *dstpath, unsigned int dstpathLen, const char *srcpath, unsigned int maxlen) @@ -3119,7 +3156,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, for (nd = nmp->nm_dir; nd; nd = nd->nfs_next) { char filename[FILENAME_MAX_LEN] = {}; - error = nfs_getfilename(filename, sizeof(filename), nd->nfs_dir->fd_dir.d_name, NAME_MAX); + error = nfs_getfilename(filename, sizeof(filename), nd->nfs_dir->fd_dir[0].d_name, NAME_MAX); if (error != OK) { goto errout_with_mutex; @@ -3257,7 +3294,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, } else if (nd) { - error = memcpy_s(nd->nfs_dir->fd_dir.d_name, strlen(to_name) + 1, to_name, strlen(to_name) + 1); + error = memcpy_s(nd->nfs_dir->fd_dir[0].d_name, strlen(to_name) + 1, to_name, strlen(to_name) + 1); if (error != EOK) { error = ENOBUFS; @@ -3427,7 +3464,7 @@ static int nfs_stat(struct inode *mountpt, const char *relpath, errout_with_mutex: nfs_mux_release(nmp); - return -error; + return -nfs_2_vfs(error); } int nfs_mount(const char *server_ip_and_path, const char *mount_path, diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c index f57c788..170b0a3 100755 --- a/fs/tmpfs/fs_tmpfs.c +++ b/fs/tmpfs/fs_tmpfs.c @@ -1366,8 +1366,7 @@ static ssize_t tmpfs_write(FAR struct file *filep, FAR const char *buffer, ret = -ENOSPC; goto errout_with_lock; } - (void)memset_s(data, startpos + alloc, 0, startpos + alloc); - if (tfo->tfo_data) + if (tfo->tfo_size) { ret = memcpy_s(data, startpos + alloc, tfo->tfo_data, tfo->tfo_size); if (ret != EOK) @@ -1378,6 +1377,10 @@ static ssize_t tmpfs_write(FAR struct file *filep, FAR const char *buffer, } free(tfo->tfo_data); } + if (startpos > tfo->tfo_size) + { + (void)memset_s(data + tfo->tfo_size, startpos + alloc - tfo->tfo_size, 0, startpos - tfo->tfo_size); + } tfo->tfo_data = data; tfo->tfo_size = startpos + alloc; @@ -1675,25 +1678,24 @@ static int tmpfs_readdir(FAR struct inode *mountpt, { /* A directory */ - dir->fd_dir.d_type = DT_DIR; + dir->fd_dir[0].d_type = DT_DIR; } else /* to->to_type == TMPFS_REGULAR) */ { /* A regular file */ - dir->fd_dir.d_type = DT_REG; + dir->fd_dir[0].d_type = DT_REG; } /* Copy the entry name */ - (void)strncpy_s(dir->fd_dir.d_name, NAME_MAX + 1, tde->tde_name, NAME_MAX); + (void)strncpy_s(dir->fd_dir[0].d_name, NAME_MAX + 1, tde->tde_name, NAME_MAX); - /* Increment the index for next time */ + dir->fd_position++; + dir->fd_dir[0].d_off = dir->fd_position; + dir->fd_dir[0].d_reclen = (uint16_t)sizeof(struct dirent); - dir->fd_dir.d_off = dir->fd_position; - dir->fd_dir.d_reclen = (uint16_t)sizeof(struct dirent); - - ret = OK; + ret = 1; // 1 means current file num is 1 } tmpfs_unlock_directory(tdo); diff --git a/fs/vfs/fs_close.c b/fs/vfs/fs_close.c index a96b211..8b7fc53 100755 --- a/fs/vfs/fs_close.c +++ b/fs/vfs/fs_close.c @@ -49,6 +49,7 @@ #endif #include "inode/inode.h" +#include "mqueue.h" /**************************************************************************** * Public Functions @@ -97,6 +98,14 @@ int close(int fd) } else #endif +#if defined(LOSCFG_COMPAT_POSIX) + if ((unsigned int)fd >= MQUEUE_FD_OFFSET && \ + (unsigned int)fd < (unsigned int)(MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS)) + { + return mq_close((mqd_t)fd); + } +#endif + else { err = EBADF; goto errout; diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index ced32a7..7932c5d 100755 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -229,6 +229,11 @@ int stat(FAR const char *path, FAR struct stat *buf) else #endif { + if (strlen(relpath) > 0) + { + ret = ENOENT; + goto errout_with_inode; + } /* The node is part of the root pseudo file system */ if (VfsPermissionCheck(desc.parent->i_uid, desc.parent->i_gid, desc.parent->i_mode, EXEC_OP)) diff --git a/fs/vfs/fs_statfs.c b/fs/vfs/fs_statfs.c index f521af3..1bd7c20 100755 --- a/fs/vfs/fs_statfs.c +++ b/fs/vfs/fs_statfs.c @@ -131,11 +131,27 @@ int statfs(FAR const char *path, FAR struct statfs *buf) * supports the statfs() method */ - if (inode->u.i_mops && inode->u.i_mops->statfs) + if (inode->u.i_mops && inode->u.i_mops->stat && inode->u.i_mops->statfs) { - /* Perform the statfs() operation */ + struct stat *statbuf = LOS_MemAlloc(m_aucSysMem0, sizeof(struct stat)); + if (statbuf == NULL) + { + ret = ENOMEM; + } + else + { + /* Check whether the path is available or not */ - ret = inode->u.i_mops->statfs(inode, buf); + ret = inode->u.i_mops->stat(inode, desc.relpath, statbuf); + if (ret == 0) + { + /* Perform the statfs() operation */ + + (void)memset_s((void *)buf, sizeof(struct statfs), 0, sizeof(struct statfs)); + ret = inode->u.i_mops->statfs(inode, buf); + } + (VOID)LOS_MemFree(m_aucSysMem0, statbuf); + } } } else @@ -143,6 +159,12 @@ int statfs(FAR const char *path, FAR struct statfs *buf) { /* The node is part of the root pseudo file system */ + if (strlen(desc.relpath) > 0) + { + ret = ENOENT; + goto errout_with_inode; + } + ret = statpseudofs(inode, buf); } diff --git a/include/nuttx/fs/dirent_fs.h b/include/nuttx/fs/dirent_fs.h index 101f753..9498eac 100755 --- a/include/nuttx/fs/dirent_fs.h +++ b/include/nuttx/fs/dirent_fs.h @@ -308,11 +308,21 @@ struct fs_dirent_s #ifdef CONFIG_FS_HOSTFS struct fs_hostfsdir_s hostfs; #endif + +#ifdef LOSCFG_FS_ZPFS + void *zpfs; +#endif } u; /* In any event, this the actual struct dirent that is returned by readdir */ - - struct dirent fd_dir; /* Populated when readdir is called */ +#ifdef LOSCFG_ENABLE_READ_BUFFER + struct dirent fd_dir[MAX_DIRENT_NUM]; /* Populated when readdir is called */ +#else + struct dirent fd_dir[1]; /* Populated when readdir is called */ +#endif + int16_t cur_pos; + int16_t end_pos; + int32_t read_cnt; int fd_status; /* Express the dirent is been opened or no */ }; diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 210e8b3..93905b4 100755 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -78,6 +78,7 @@ extern "C" { #undef OK #define OK 0 +#define MAX_DIRENT_NUM 14 // 14 means 4096 length buffer can store 14 dirent, see struct DIR #define MS_RDONLY 1 #define MS_NOSYNC 2 #define PROCFS_MOUNT_POINT "/proc" diff --git a/include/sys/statfs.h b/include/sys/statfs.h new file mode 100755 index 0000000..451f63f --- /dev/null +++ b/include/sys/statfs.h @@ -0,0 +1,155 @@ +/**************************************************************************** + * include/sys/statfs.h + * + * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 NuttX 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 OWNER 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 __INCLUDE_SYS_STATFS_H +#define __INCLUDE_SYS_STATFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* struct statfs file system types. */ + +#define ADFS_SUPER_MAGIC 0xadf5 +#define AFFS_SUPER_MAGIC 0xadff +#define BEFS_SUPER_MAGIC 0x42465331 +#define BFS_MAGIC 0x1badface +#define CIFS_MAGIC_NUMBER 0xff534d42 +#define CODA_SUPER_MAGIC 0x73757245 +#define COH_SUPER_MAGIC 0x012ff7b7 +#define CRAMFS_MAGIC 0x28cd3d45 +#define DEVFS_SUPER_MAGIC 0x1373 +#define EFS_SUPER_MAGIC 0x00414a53 +#define EXT_SUPER_MAGIC 0x137d +#define EXT2_OLD_SUPER_MAGIC 0xef51 +#define EXT2_SUPER_MAGIC 0xef53 +#define EXT3_SUPER_MAGIC 0xef53 +#define HFS_SUPER_MAGIC 0x4244 +#define HPFS_SUPER_MAGIC 0xf995e849 +#define HUGETLBFS_MAGIC 0x958458f6 +#define ISOFS_SUPER_MAGIC 0x9660 +#define JFFS2_SUPER_MAGIC 0x72b6 +#define JFS_SUPER_MAGIC 0x3153464a +#define MINIX_SUPER_MAGIC 0x137f /* orig. minix */ +#define MINIX_SUPER_MAGIC2 0x138f /* 30 char minix */ +#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 */ +#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2, 30 char names */ +#define MSDOS_SUPER_MAGIC 0x4d44 +#define NCP_SUPER_MAGIC 0x564c +#define NFS_SUPER_MAGIC 0x6969 +#define NTFS_SB_MAGIC 0x5346544e +#define OPENPROM_SUPER_MAGIC 0x9fa1 +#define PROC_SUPER_MAGIC 0x9fa0 +#define QNX4_SUPER_MAGIC 0x002f +#define REISERFS_SUPER_MAGIC 0x52654973 +#define ROMFS_MAGIC 0x7275 +#define SMB_SUPER_MAGIC 0x517B +#define SYSV2_SUPER_MAGIC 0x012ff7b6 +#define SYSV4_SUPER_MAGIC 0x012FF7B5 +#define TMPFS_MAGIC 0x01021994 +#define UDF_SUPER_MAGIC 0x15013346 +#define UFS_MAGIC 0x00011954 +#define USBDEVICE_SUPER_MAGIC 0x9fa2 +#define VXFS_SUPER_MAGIC 0xa501fcf5 +#define XENIX_SUPER_MAGIC 0x012ff7b4 +#define XFS_SUPER_MAGIC 0x58465342 +#define _XIAFS_SUPER_MAGIC 0x012fd16d +#define SPIFFS_SUPER_MAGIC 0x20090315 +#define LITTLEFS_SUPER_MAGIC 0x0a732923 +#define ZPFS_MAGIC 0xa000e93 + +/* NuttX specific file-systems */ + +#define BINFS_MAGIC 0x4242 +#define PROCFS_MAGIC 0x434f5250 +#define NXFFS_MAGIC 0x4747 +#define SMARTFS_MAGIC 0x54524D53 +#define UNIONFS_MAGIC 0x53464e55 +#define HOSTFS_MAGIC 0x54534f48 +#define USERFS_MAGIC 0x52455355 +#define CROMFS_MAGIC 0x4d4f5243 + +/**************************************************************************** + * Type Definitions + ****************************************************************************/ + +struct statfs +{ + uint32_t f_type; /* Type of filesystem (see definitions above) */ + size_t f_namelen; /* Maximum length of filenames */ + size_t f_bsize; /* Optimal block size for transfers */ + off_t f_blocks; /* Total data blocks in the file system of this size */ + off_t f_bfree; /* Free blocks in the file system */ + off_t f_bavail; /* Free blocks avail to non-superuser */ + off_t f_files; /* Total file nodes in the file system */ + off_t f_ffree; /* Free file nodes in the file system */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Inspired by Linux statfs() which was, in turn, inspired by + * the BSD statfs(). None of these implementations agree in the + * form of the struct statfs. + */ + +int statfs(FAR const char *path, FAR struct statfs *buf); +int fstatfs(int fd, FAR struct statfs *buf); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_SYS_STATFS_H */