mirror of
https://github.com/apache/nuttx.git
synced 2026-05-23 06:39:01 +08:00
fs/directory: move private directory information to filesystem
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -97,7 +96,7 @@ static ssize_t cxd56_powermgr_procfs_read(struct file *filep,
|
||||
static int cxd56_powermgr_procfs_dup(const struct file *oldp,
|
||||
struct file *newp);
|
||||
static int cxd56_powermgr_procfs_opendir(const char *relpath,
|
||||
struct fs_dirent_s *dir);
|
||||
struct fs_dirent_s **dir);
|
||||
static int cxd56_powermgr_procfs_closedir(struct fs_dirent_s *dir);
|
||||
static int cxd56_powermgr_procfs_readdir(struct fs_dirent_s *dir,
|
||||
struct dirent *entry);
|
||||
@@ -678,7 +677,7 @@ static int cxd56_powermgr_procfs_stat(const char *relpath,
|
||||
****************************************************************************/
|
||||
|
||||
static int cxd56_powermgr_procfs_opendir(const char *relpath,
|
||||
struct fs_dirent_s *dir)
|
||||
struct fs_dirent_s **dir)
|
||||
{
|
||||
struct cxd56_powermgr_procfs_dir_s *procfs;
|
||||
int ret;
|
||||
@@ -711,7 +710,7 @@ static int cxd56_powermgr_procfs_opendir(const char *relpath,
|
||||
}
|
||||
|
||||
procfs->index = 0;
|
||||
dir->u.procfs = (void *)procfs;
|
||||
*dir = (struct fs_dirent_s *)procfs;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -726,19 +725,10 @@ static int cxd56_powermgr_procfs_opendir(const char *relpath,
|
||||
|
||||
static int cxd56_powermgr_procfs_closedir(struct fs_dirent_s *dir)
|
||||
{
|
||||
struct smartfs_level1_s *priv;
|
||||
|
||||
pminfo("Closedir\n");
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -755,9 +745,9 @@ static int cxd56_powermgr_procfs_readdir(struct fs_dirent_s *dir,
|
||||
{
|
||||
struct cxd56_powermgr_procfs_dir_s *procfs;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
DEBUGASSERT(dir);
|
||||
|
||||
procfs = (struct cxd56_powermgr_procfs_dir_s *)dir->u.procfs;
|
||||
procfs = (struct cxd56_powermgr_procfs_dir_s *)dir;
|
||||
|
||||
pminfo("Readdir %d\n", procfs->index);
|
||||
|
||||
@@ -787,9 +777,9 @@ static int cxd56_powermgr_procfs_rewinddir(struct fs_dirent_s *dir)
|
||||
{
|
||||
struct cxd56_powermgr_procfs_dir_s *procfs;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
DEBUGASSERT(dir);
|
||||
|
||||
procfs = (struct cxd56_powermgr_procfs_dir_s *)dir->u.procfs;
|
||||
procfs = (struct cxd56_powermgr_procfs_dir_s *)dir;
|
||||
pminfo("Rewind %d\n", procfs->index);
|
||||
procfs->index = 0;
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <nuttx/nuttx.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
@@ -104,7 +102,7 @@ static int pm_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
|
||||
static int pm_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int pm_closedir(FAR struct fs_dirent_s *dir);
|
||||
static int pm_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -437,12 +435,12 @@ static int pm_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pm_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
static int pm_opendir(FAR const char *relpath, FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct procfs_dir_priv_s *level1;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath && dir && !dir->u.procfs);
|
||||
DEBUGASSERT(relpath);
|
||||
|
||||
/* Assume that path refers to the 1st level subdirectory. Allocate the
|
||||
* level1 the dirent structure before checking.
|
||||
@@ -460,7 +458,7 @@ static int pm_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
level1->level = 1;
|
||||
level1->nentries = CONFIG_PM_NDOMAINS * ARRAY_SIZE(g_pm_files);
|
||||
|
||||
dir->u.procfs = (FAR void *)level1;
|
||||
*dir = (FAR struct fs_dirent_s *)level1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -473,14 +471,8 @@ static int pm_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
|
||||
static int pm_closedir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct procfs_dir_priv_s *level1;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
|
||||
kmm_free(level1);
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -499,8 +491,8 @@ static int pm_readdir(FAR struct fs_dirent_s *dir,
|
||||
int domain;
|
||||
int fpos;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
level1 = (FAR struct procfs_dir_priv_s *)dir;
|
||||
|
||||
index = level1->index;
|
||||
if (index >= level1->nentries)
|
||||
@@ -535,8 +527,8 @@ static int pm_rewinddir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct procfs_dir_priv_s *level1;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
level1 = (FAR struct procfs_dir_priv_s *)dir;
|
||||
|
||||
level1->index = 0;
|
||||
return OK;
|
||||
|
||||
+50
-11
@@ -38,7 +38,6 @@
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/binfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/lib/builtin.h>
|
||||
|
||||
@@ -46,6 +45,16 @@
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_BINFS)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
struct binfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base; /* VFS directory structure */
|
||||
unsigned int index; /* Index to the next named entry point */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -62,8 +71,11 @@ static int binfs_dup(FAR const struct file *oldp, FAR struct file *newp);
|
||||
static int binfs_fstat(FAR const struct file *filep,
|
||||
FAR struct stat *buf);
|
||||
|
||||
static int binfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
struct fs_dirent_s *dir);
|
||||
static int binfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int binfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int binfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -105,7 +117,7 @@ const struct mountpt_operations binfs_operations =
|
||||
NULL, /* truncate */
|
||||
|
||||
binfs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
binfs_closedir, /* closedir */
|
||||
binfs_readdir, /* readdir */
|
||||
binfs_rewinddir, /* rewinddir */
|
||||
|
||||
@@ -277,9 +289,11 @@ static int binfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int binfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
struct fs_dirent_s *dir)
|
||||
static int binfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct binfs_dir_s *bdir;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
|
||||
/* The requested directory must be the volume-relative "root" directory */
|
||||
@@ -289,12 +303,35 @@ static int binfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
bdir = kmm_zalloc(sizeof(*bdir));
|
||||
if (bdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Set the index to the first entry */
|
||||
|
||||
dir->u.binfs.fb_index = 0;
|
||||
bdir->index = 0;
|
||||
*dir = (FAR struct fs_dirent_s *)bdir;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: binfs_closedir
|
||||
*
|
||||
* Description:
|
||||
* Close a directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int binfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: binfs_readdir
|
||||
*
|
||||
@@ -306,13 +343,15 @@ static int binfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct binfs_dir_s *bdir;
|
||||
FAR const char *name;
|
||||
unsigned int index;
|
||||
int ret;
|
||||
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
index = dir->u.binfs.fb_index;
|
||||
bdir = (FAR struct binfs_dir_s *)dir;
|
||||
index = bdir->index;
|
||||
name = builtin_getname(index);
|
||||
if (name == NULL)
|
||||
{
|
||||
@@ -338,10 +377,10 @@ static int binfs_readdir(FAR struct inode *mountpt,
|
||||
index++;
|
||||
|
||||
/* Set up the next directory entry offset. NOTE that we could use the
|
||||
* standard f_pos instead of our own private fb_index.
|
||||
* standard f_pos instead of our own private index.
|
||||
*/
|
||||
|
||||
dir->u.binfs.fb_index = index;
|
||||
bdir->index = index;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
@@ -359,7 +398,7 @@ static int binfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
{
|
||||
finfo("Entry\n");
|
||||
|
||||
dir->u.binfs.fb_index = 0;
|
||||
((FAR struct binfs_dir_s *)dir)->index = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+47
-10
@@ -40,7 +40,6 @@
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
#include "cromfs.h"
|
||||
@@ -57,6 +56,13 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct cromfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s cr_base; /* VFS directory structure */
|
||||
uint32_t cr_firstoffset; /* Offset to the first entry in the directory */
|
||||
uint32_t cr_curroffset; /* Current offset into the directory contents */
|
||||
};
|
||||
|
||||
/* This structure represents an open, regular file */
|
||||
|
||||
struct cromfs_file_s
|
||||
@@ -142,7 +148,9 @@ static int cromfs_fstat(FAR const struct file *filep,
|
||||
FAR struct stat *buf);
|
||||
|
||||
static int cromfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath, FAR struct fs_dirent_s *dir);
|
||||
FAR const char *relpath, FAR struct fs_dirent_s **dir);
|
||||
static int cromfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int cromfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -184,7 +192,7 @@ const struct mountpt_operations cromfs_operations =
|
||||
NULL, /* truncate */
|
||||
|
||||
cromfs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
cromfs_closedir, /* closedir */
|
||||
cromfs_readdir, /* readdir */
|
||||
cromfs_rewinddir, /* rewinddir */
|
||||
|
||||
@@ -1181,9 +1189,10 @@ static int cromfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
||||
****************************************************************************/
|
||||
|
||||
static int cromfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR const struct cromfs_volume_s *fs;
|
||||
FAR struct cromfs_dir_s *cdir;
|
||||
FAR struct cromfs_nodeinfo_s info;
|
||||
uint32_t offset;
|
||||
int ret;
|
||||
@@ -1217,13 +1226,35 @@ static int cromfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
return -ENOTDIR;
|
||||
}
|
||||
|
||||
cdir = kmm_zalloc(sizeof(*cdir));
|
||||
if (cdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Set the start node and next node to the first entry in the directory */
|
||||
|
||||
dir->u.cromfs.cr_firstoffset = info.ci_child;
|
||||
dir->u.cromfs.cr_curroffset = info.ci_child;
|
||||
cdir->cr_firstoffset = info.ci_child;
|
||||
cdir->cr_curroffset = info.ci_child;
|
||||
*dir = &cdir->cr_base;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cromfs_closedir
|
||||
*
|
||||
* Description: close directory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int cromfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(mountpt != NULL);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cromfs_readdir
|
||||
*
|
||||
@@ -1237,6 +1268,7 @@ static int cromfs_readdir(FAR struct inode *mountpt,
|
||||
{
|
||||
FAR const struct cromfs_volume_s *fs;
|
||||
FAR const struct cromfs_node_s *node;
|
||||
FAR struct cromfs_dir_s *cdir;
|
||||
struct cromfs_node_s newnode;
|
||||
FAR char *name;
|
||||
uint32_t offset;
|
||||
@@ -1251,10 +1283,11 @@ static int cromfs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
cdir = (FAR struct cromfs_dir_s *)dir;
|
||||
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
offset = dir->u.cromfs.cr_curroffset;
|
||||
offset = cdir->cr_curroffset;
|
||||
if (offset == 0)
|
||||
{
|
||||
/* We signal the end of the directory by returning the
|
||||
@@ -1346,7 +1379,7 @@ static int cromfs_readdir(FAR struct inode *mountpt,
|
||||
* standard f_pos instead of our own private fb_index.
|
||||
*/
|
||||
|
||||
dir->u.cromfs.cr_curroffset = node->cn_peer;
|
||||
cdir->cr_curroffset = node->cn_peer;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1357,11 +1390,15 @@ static int cromfs_readdir(FAR struct inode *mountpt,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int cromfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
static int cromfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct cromfs_dir_s *cdir;
|
||||
|
||||
finfo("mountpt: %p dir: %p\n", mountpt, dir);
|
||||
|
||||
dir->u.cromfs.cr_curroffset = dir->u.cromfs.cr_firstoffset;
|
||||
cdir = (FAR struct cromfs_dir_s *)dir;
|
||||
cdir->cr_curroffset = cdir->cr_firstoffset;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+65
-33
@@ -40,7 +40,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/fat.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
#include "fs_fat32.h"
|
||||
@@ -67,7 +66,9 @@ static int fat_fstat(FAR const struct file *filep,
|
||||
static int fat_truncate(FAR struct file *filep, off_t length);
|
||||
|
||||
static int fat_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath, FAR struct fs_dirent_s *dir);
|
||||
FAR const char *relpath, FAR struct fs_dirent_s **dir);
|
||||
static int fat_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int fat_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -122,7 +123,7 @@ const struct mountpt_operations fat_operations =
|
||||
fat_truncate, /* truncate */
|
||||
|
||||
fat_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
fat_closedir, /* closedir */
|
||||
fat_readdir, /* readdir */
|
||||
fat_rewinddir, /* rewinddir */
|
||||
|
||||
@@ -1569,8 +1570,9 @@ errout_with_semaphore:
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct fat_dirent_s *fdir;
|
||||
FAR struct fat_mountpt_s *fs;
|
||||
FAR struct fat_dirinfo_s dirinfo;
|
||||
uint8_t *direntry;
|
||||
@@ -1584,12 +1586,18 @@ static int fat_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
||||
fdir = kmm_zalloc(sizeof(struct fat_dirent_s));
|
||||
if (fdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
ret = fat_semtake(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_fdir;
|
||||
}
|
||||
|
||||
ret = fat_checkmount(fs);
|
||||
@@ -1614,10 +1622,10 @@ static int fat_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
* fat_finddirentry() above.
|
||||
*/
|
||||
|
||||
dir->u.fat.fd_startcluster = dirinfo.dir.fd_startcluster;
|
||||
dir->u.fat.fd_currcluster = dirinfo.dir.fd_currcluster;
|
||||
dir->u.fat.fd_currsector = dirinfo.dir.fd_currsector;
|
||||
dir->u.fat.fd_index = dirinfo.dir.fd_index;
|
||||
fdir->dir.fd_startcluster = dirinfo.dir.fd_startcluster;
|
||||
fdir->dir.fd_currcluster = dirinfo.dir.fd_currcluster;
|
||||
fdir->dir.fd_currsector = dirinfo.dir.fd_currsector;
|
||||
fdir->dir.fd_index = dirinfo.dir.fd_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1638,23 +1646,43 @@ static int fat_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
{
|
||||
/* The entry is a directory (but not the root directory) */
|
||||
|
||||
dir->u.fat.fd_startcluster =
|
||||
fdir->dir.fd_startcluster =
|
||||
((uint32_t)DIR_GETFSTCLUSTHI(direntry) << 16) |
|
||||
DIR_GETFSTCLUSTLO(direntry);
|
||||
dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
|
||||
dir->u.fat.fd_currsector = fat_cluster2sector(fs,
|
||||
dir->u.fat.fd_currcluster);
|
||||
dir->u.fat.fd_index = 2;
|
||||
fdir->dir.fd_currcluster = fdir->dir.fd_startcluster;
|
||||
fdir->dir.fd_currsector = fat_cluster2sector(fs,
|
||||
fdir->dir.fd_currcluster);
|
||||
fdir->dir.fd_index = 2;
|
||||
}
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
*dir = (FAR struct fs_dirent_s *)fdir;
|
||||
fat_semgive(fs);
|
||||
return OK;
|
||||
|
||||
errout_with_semaphore:
|
||||
fat_semgive(fs);
|
||||
|
||||
errout_with_fdir:
|
||||
kmm_free(fdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_closedir
|
||||
*
|
||||
* Description: Close directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_fstat
|
||||
*
|
||||
@@ -1882,6 +1910,7 @@ static int fat_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct fat_dirent_s *fdir;
|
||||
FAR struct fat_mountpt_s *fs;
|
||||
unsigned int dirindex;
|
||||
FAR uint8_t *direntry;
|
||||
@@ -1897,6 +1926,7 @@ static int fat_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
fdir = (FAR struct fat_dirent_s *)dir;
|
||||
|
||||
/* Make sure that the mount is still healthy.
|
||||
* REVISIT: What if a forced unmount was done since opendir() was called?
|
||||
@@ -1919,9 +1949,9 @@ static int fat_readdir(FAR struct inode *mountpt,
|
||||
entry->d_name[0] = '\0';
|
||||
found = false;
|
||||
|
||||
while (dir->u.fat.fd_currsector && !found)
|
||||
while (fdir->dir.fd_currsector && !found)
|
||||
{
|
||||
ret = fat_fscacheread(fs, dir->u.fat.fd_currsector);
|
||||
ret = fat_fscacheread(fs, fdir->dir.fd_currsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
@@ -1929,7 +1959,7 @@ static int fat_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Get a reference to the current directory entry */
|
||||
|
||||
dirindex = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
dirindex = (fdir->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
direntry = &fs->fs_buffer[dirindex];
|
||||
|
||||
/* Has it reached to end of the directory */
|
||||
@@ -1981,8 +2011,8 @@ static int fat_readdir(FAR struct inode *mountpt,
|
||||
* entry.
|
||||
*/
|
||||
|
||||
dirindex = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) *
|
||||
DIR_SIZE;
|
||||
dirindex = (fdir->dir.fd_index & DIRSEC_NDXMASK(fs)) *
|
||||
DIR_SIZE;
|
||||
direntry = &fs->fs_buffer[dirindex];
|
||||
|
||||
/* Then re-read the attributes from the short file name entry */
|
||||
@@ -2010,7 +2040,7 @@ static int fat_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Set up the next directory index */
|
||||
|
||||
if (fat_nextdirentry(fs, &dir->u.fat) != OK)
|
||||
if (fat_nextdirentry(fs, &fdir->dir) != OK)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto errout_with_semaphore;
|
||||
@@ -2035,6 +2065,7 @@ errout_with_semaphore:
|
||||
static int fat_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct fat_dirent_s *fdir;
|
||||
FAR struct fat_mountpt_s *fs;
|
||||
int ret;
|
||||
|
||||
@@ -2045,6 +2076,7 @@ static int fat_rewinddir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
fdir = (FAR struct fat_dirent_s *)dir;
|
||||
|
||||
/* Make sure that the mount is still healthy
|
||||
* REVISIT: What if a forced unmount was done since opendir() was called?
|
||||
@@ -2067,22 +2099,22 @@ static int fat_rewinddir(FAR struct inode *mountpt,
|
||||
*/
|
||||
|
||||
if (fs->fs_type != FSTYPE_FAT32 &&
|
||||
dir->u.fat.fd_startcluster == 0)
|
||||
fdir->dir.fd_startcluster == 0)
|
||||
{
|
||||
/* Handle the FAT12/16 root directory */
|
||||
|
||||
dir->u.fat.fd_currcluster = 0;
|
||||
dir->u.fat.fd_currsector = fs->fs_rootbase;
|
||||
dir->u.fat.fd_index = 0;
|
||||
fdir->dir.fd_currcluster = 0;
|
||||
fdir->dir.fd_currsector = fs->fs_rootbase;
|
||||
fdir->dir.fd_index = 0;
|
||||
}
|
||||
else if (fs->fs_type == FSTYPE_FAT32 &&
|
||||
dir->u.fat.fd_startcluster == fs->fs_rootbase)
|
||||
fdir->dir.fd_startcluster == fs->fs_rootbase)
|
||||
{
|
||||
/* Handle the FAT32 root directory */
|
||||
|
||||
dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
|
||||
dir->u.fat.fd_currsector = fat_cluster2sector(fs, fs->fs_rootbase);
|
||||
dir->u.fat.fd_index = 0;
|
||||
fdir->dir.fd_currcluster = fdir->dir.fd_startcluster;
|
||||
fdir->dir.fd_currsector = fat_cluster2sector(fs, fs->fs_rootbase);
|
||||
fdir->dir.fd_index = 0;
|
||||
}
|
||||
|
||||
/* This is not the root directory. Here the fd_index is set to 2, skipping
|
||||
@@ -2091,10 +2123,10 @@ static int fat_rewinddir(FAR struct inode *mountpt,
|
||||
|
||||
else
|
||||
{
|
||||
dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
|
||||
dir->u.fat.fd_currsector = fat_cluster2sector(fs,
|
||||
dir->u.fat.fd_currcluster);
|
||||
dir->u.fat.fd_index = 2;
|
||||
fdir->dir.fd_currcluster = fdir->dir.fd_startcluster;
|
||||
fdir->dir.fd_currsector = fat_cluster2sector(fs,
|
||||
fdir->dir.fd_currcluster);
|
||||
fdir->dir.fd_index = 2;
|
||||
}
|
||||
|
||||
fat_semgive(fs);
|
||||
|
||||
+14
-1
@@ -33,7 +33,6 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
@@ -953,6 +952,20 @@ typedef uint8_t lfnchar;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
struct fs_fatdir_s
|
||||
{
|
||||
off_t fd_startcluster; /* Start cluster number of the directory */
|
||||
off_t fd_currcluster; /* Current cluster number being read */
|
||||
off_t fd_currsector; /* Current sector being read */
|
||||
unsigned int fd_index; /* Current index of the directory entry to read */
|
||||
};
|
||||
|
||||
struct fat_dirent_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
struct fs_fatdir_s dir;
|
||||
};
|
||||
|
||||
/* This structure is used internally for describing directory entries */
|
||||
|
||||
struct fat_dirinfo_s
|
||||
|
||||
@@ -1964,6 +1964,7 @@ static inline int fat_getlfname(FAR struct fat_mountpt_s *fs,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct fat_dirent_s *fdir;
|
||||
FAR uint8_t *direntry;
|
||||
lfnchar lfname[LDIR_MAXLFNCHARS];
|
||||
uint16_t diroffset;
|
||||
@@ -1977,7 +1978,8 @@ static inline int fat_getlfname(FAR struct fat_mountpt_s *fs,
|
||||
|
||||
/* Get a reference to the current directory entry */
|
||||
|
||||
diroffset = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
fdir = (FAR struct fat_dirent_s *)dir;
|
||||
diroffset = (fdir->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
direntry = &fs->fs_buffer[diroffset];
|
||||
|
||||
/* Get the starting sequence number */
|
||||
@@ -2103,14 +2105,14 @@ static inline int fat_getlfname(FAR struct fat_mountpt_s *fs,
|
||||
|
||||
/* Read next directory entry */
|
||||
|
||||
if (fat_nextdirentry(fs, &dir->u.fat) != OK)
|
||||
if (fat_nextdirentry(fs, &fdir->dir) != OK)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Make sure that the directory sector into the sector cache */
|
||||
|
||||
ret = fat_fscacheread(fs, dir->u.fat.fd_currsector);
|
||||
ret = fat_fscacheread(fs, fdir->dir.fd_currsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
@@ -2118,7 +2120,7 @@ static inline int fat_getlfname(FAR struct fat_mountpt_s *fs,
|
||||
|
||||
/* Get a reference to the current directory entry */
|
||||
|
||||
diroffset = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
diroffset = (fdir->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
direntry = &fs->fs_buffer[diroffset];
|
||||
|
||||
/* Get the next expected sequence number. */
|
||||
@@ -2943,6 +2945,7 @@ int fat_dirname2path(FAR struct fat_mountpt_s *fs,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct fat_dirent_s *fdir;
|
||||
uint16_t diroffset;
|
||||
FAR uint8_t *direntry;
|
||||
#ifdef CONFIG_FAT_LFN
|
||||
@@ -2951,7 +2954,8 @@ int fat_dirname2path(FAR struct fat_mountpt_s *fs,
|
||||
|
||||
/* Get a reference to the current directory entry */
|
||||
|
||||
diroffset = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
fdir = (FAR struct fat_dirent_s *)dir;
|
||||
diroffset = (fdir->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
|
||||
direntry = &fs->fs_buffer[diroffset];
|
||||
|
||||
/* Does this entry refer to the last entry of a long file name? */
|
||||
|
||||
+38
-12
@@ -39,7 +39,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/fat.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/fs/hostfs.h>
|
||||
|
||||
@@ -51,6 +50,16 @@
|
||||
|
||||
#define HOSTFS_RETRY_DELAY_MS 10
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct hostfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
FAR void *dir;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -79,7 +88,7 @@ static int hostfs_ftruncate(FAR struct file *filep,
|
||||
|
||||
static int hostfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int hostfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int hostfs_readdir(FAR struct inode *mountpt,
|
||||
@@ -830,9 +839,10 @@ static int hostfs_ftruncate(FAR struct file *filep, off_t length)
|
||||
****************************************************************************/
|
||||
|
||||
static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_dir_s *hdir;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
int ret;
|
||||
|
||||
@@ -843,13 +853,18 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
hdir = kmm_zalloc(sizeof(struct hostfs_dir_s));
|
||||
if (hdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
ret = hostfs_semtake(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_hdir;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
@@ -858,18 +873,22 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
|
||||
/* Call the host's opendir function */
|
||||
|
||||
dir->u.hostfs.fs_dir = host_opendir(path);
|
||||
if (dir->u.hostfs.fs_dir == NULL)
|
||||
hdir->dir = host_opendir(path);
|
||||
if (hdir->dir == NULL)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
*dir = (FAR struct fs_dirent_s *)hdir;
|
||||
hostfs_semgive(fs);
|
||||
return OK;
|
||||
|
||||
errout_with_semaphore:
|
||||
|
||||
hostfs_semgive(fs);
|
||||
|
||||
errout_with_hdir:
|
||||
kmm_free(hdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -883,7 +902,8 @@ errout_with_semaphore:
|
||||
static int hostfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_dir_s *hdir;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -893,6 +913,7 @@ static int hostfs_closedir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
hdir = (FAR struct hostfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -904,9 +925,10 @@ static int hostfs_closedir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host's closedir function */
|
||||
|
||||
host_closedir(dir->u.hostfs.fs_dir);
|
||||
host_closedir(hdir->dir);
|
||||
|
||||
hostfs_semgive(fs);
|
||||
kmm_free(hdir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -922,6 +944,7 @@ static int hostfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_dir_s *hdir;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -931,6 +954,7 @@ static int hostfs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
hdir = (FAR struct hostfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -942,7 +966,7 @@ static int hostfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host OS's readdir function */
|
||||
|
||||
ret = host_readdir(dir->u.hostfs.fs_dir, entry);
|
||||
ret = host_readdir(hdir->dir, entry);
|
||||
|
||||
hostfs_semgive(fs);
|
||||
return ret;
|
||||
@@ -959,6 +983,7 @@ static int hostfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_dir_s *hdir;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -968,6 +993,7 @@ static int hostfs_rewinddir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
hdir = (FAR struct hostfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -979,7 +1005,7 @@ static int hostfs_rewinddir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host and let it do all the work */
|
||||
|
||||
host_rewinddir(dir->u.hostfs.fs_dir);
|
||||
host_rewinddir(hdir->dir);
|
||||
|
||||
hostfs_semgive(fs);
|
||||
return OK;
|
||||
|
||||
+26
-21
@@ -28,7 +28,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
@@ -44,6 +43,12 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct littlefs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
struct lfs_dir dir;
|
||||
};
|
||||
|
||||
struct littlefs_file_s
|
||||
{
|
||||
struct lfs_file file;
|
||||
@@ -93,7 +98,7 @@ static int littlefs_truncate(FAR struct file *filep,
|
||||
|
||||
static int littlefs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int littlefs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int littlefs_readdir(FAR struct inode *mountpt,
|
||||
@@ -734,10 +739,10 @@ static int littlefs_truncate(FAR struct file *filep, off_t length)
|
||||
|
||||
static int littlefs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct littlefs_mountpt_s *fs;
|
||||
FAR struct lfs_dir *priv;
|
||||
FAR struct littlefs_dir_s *ldir;
|
||||
int ret;
|
||||
|
||||
/* Recover our private data from the inode instance */
|
||||
@@ -746,8 +751,8 @@ static int littlefs_opendir(FAR struct inode *mountpt,
|
||||
|
||||
/* Allocate memory for the open directory */
|
||||
|
||||
priv = kmm_malloc(sizeof(*priv));
|
||||
if (priv == NULL)
|
||||
ldir = kmm_malloc(sizeof(*ldir));
|
||||
if (ldir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -762,20 +767,20 @@ static int littlefs_opendir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the LFS's opendir function */
|
||||
|
||||
ret = littlefs_convert_result(lfs_dir_open(&fs->lfs, priv, relpath));
|
||||
ret = littlefs_convert_result(lfs_dir_open(&fs->lfs, &ldir->dir, relpath));
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
littlefs_semgive(fs);
|
||||
dir->u.littlefs = priv;
|
||||
*dir = &ldir->base;
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
littlefs_semgive(fs);
|
||||
errsem:
|
||||
kmm_free(priv);
|
||||
kmm_free(ldir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -789,13 +794,13 @@ errsem:
|
||||
static int littlefs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
struct littlefs_mountpt_s *fs;
|
||||
FAR struct lfs_dir *priv;
|
||||
FAR struct littlefs_mountpt_s *fs;
|
||||
FAR struct littlefs_dir_s *ldir;
|
||||
int ret;
|
||||
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
priv = dir->u.littlefs;
|
||||
ldir = (FAR struct littlefs_dir_s *)dir;
|
||||
fs = mountpt->i_private;
|
||||
|
||||
/* Call the LFS's closedir function */
|
||||
@@ -806,10 +811,10 @@ static int littlefs_closedir(FAR struct inode *mountpt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
lfs_dir_close(&fs->lfs, priv);
|
||||
lfs_dir_close(&fs->lfs, &ldir->dir);
|
||||
littlefs_semgive(fs);
|
||||
|
||||
kmm_free(priv);
|
||||
kmm_free(ldir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -825,13 +830,13 @@ static int littlefs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct littlefs_mountpt_s *fs;
|
||||
FAR struct lfs_dir *priv;
|
||||
FAR struct littlefs_dir_s *ldir;
|
||||
struct lfs_info info;
|
||||
int ret;
|
||||
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
priv = dir->u.littlefs;
|
||||
ldir = (FAR struct littlefs_dir_s *)dir;
|
||||
fs = mountpt->i_private;
|
||||
|
||||
/* Call the LFS's readdir function */
|
||||
@@ -842,7 +847,7 @@ static int littlefs_readdir(FAR struct inode *mountpt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = littlefs_convert_result(lfs_dir_read(&fs->lfs, priv, &info));
|
||||
ret = littlefs_convert_result(lfs_dir_read(&fs->lfs, &ldir->dir, &info));
|
||||
if (ret > 0)
|
||||
{
|
||||
if (info.type == LFS_TYPE_REG)
|
||||
@@ -875,13 +880,13 @@ static int littlefs_readdir(FAR struct inode *mountpt,
|
||||
static int littlefs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
struct littlefs_mountpt_s *fs;
|
||||
FAR struct lfs_dir *priv;
|
||||
FAR struct littlefs_mountpt_s *fs;
|
||||
FAR struct littlefs_dir_s *ldir;
|
||||
int ret;
|
||||
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
priv = dir->u.littlefs;
|
||||
ldir = (FAR struct littlefs_dir_s *)dir;
|
||||
fs = mountpt->i_private;
|
||||
|
||||
/* Call the LFS's rewinddir function */
|
||||
@@ -892,7 +897,7 @@ static int littlefs_rewinddir(FAR struct inode *mountpt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = littlefs_convert_result(lfs_dir_rewind(&fs->lfs, priv));
|
||||
ret = littlefs_convert_result(lfs_dir_rewind(&fs->lfs, &ldir->dir));
|
||||
|
||||
littlefs_semgive(fs);
|
||||
return ret;
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "mount/mount.h"
|
||||
|
||||
|
||||
+76
-27
@@ -65,7 +65,6 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/nfs.h>
|
||||
#include <nuttx/net/netconfig.h>
|
||||
@@ -85,6 +84,9 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DIRENT_NFS_MAXHANDLE 64 /* Maximum length of an NFSv3 file handle */
|
||||
#define DIRENT_NFS_VERFLEN 8 /* Length of the copy verifier */
|
||||
|
||||
/* include/nuttx/fs/dirent.h has its own version of these lengths. They must
|
||||
* match the NFS versions.
|
||||
*/
|
||||
@@ -99,6 +101,19 @@
|
||||
|
||||
#define CH_STAT_SIZE (1 << 7)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
struct nfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s nfs_base; /* VFS diretory structure */
|
||||
uint8_t nfs_fhsize; /* Length of the file handle */
|
||||
uint8_t nfs_fhandle[DIRENT_NFS_MAXHANDLE]; /* File handle (max size allocated) */
|
||||
uint8_t nfs_verifier[DIRENT_NFS_VERFLEN]; /* Cookie verifier */
|
||||
uint32_t nfs_cookie[2]; /* Cookie */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@@ -138,7 +153,9 @@ static int nfs_fchstat(FAR const struct file *filep,
|
||||
FAR const struct stat *buf, int flags);
|
||||
static int nfs_truncate(FAR struct file *filep, off_t length);
|
||||
static int nfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath, FAR struct fs_dirent_s *dir);
|
||||
FAR const char *relpath, FAR struct fs_dirent_s **dir);
|
||||
static int nfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int nfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -192,7 +209,7 @@ const struct mountpt_operations nfs_operations =
|
||||
nfs_truncate, /* truncate */
|
||||
|
||||
nfs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
nfs_closedir, /* closedir */
|
||||
nfs_readdir, /* readdir */
|
||||
nfs_rewinddir, /* rewinddir */
|
||||
|
||||
@@ -1407,10 +1424,11 @@ static int nfs_truncate(FAR struct file *filep, off_t length)
|
||||
****************************************************************************/
|
||||
|
||||
static int nfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct nfsmount *nmp;
|
||||
FAR struct file_handle fhandle;
|
||||
FAR struct nfs_dir_s *ndir;
|
||||
struct file_handle fhandle;
|
||||
struct nfs_fattr obj_attributes;
|
||||
uint32_t objtype;
|
||||
int ret;
|
||||
@@ -1424,15 +1442,16 @@ static int nfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
nmp = mountpt->i_private;
|
||||
|
||||
/* Initialize the NFS-specific portions of dirent structure to zero */
|
||||
|
||||
memset(&dir->u.nfs, 0, sizeof(struct nfsdir_s));
|
||||
ndir = kmm_zalloc(sizeof(*ndir));
|
||||
if (ndir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = nfs_semtake(nmp);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_ndir;
|
||||
}
|
||||
|
||||
/* Find the NFS node associate with the path */
|
||||
@@ -1458,16 +1477,40 @@ static int nfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
* used later when readdir() is called.
|
||||
*/
|
||||
|
||||
dir->u.nfs.nfs_fhsize = (uint8_t)fhandle.length;
|
||||
ndir->nfs_fhsize = (uint8_t)fhandle.length;
|
||||
DEBUGASSERT(fhandle.length <= DIRENT_NFS_MAXHANDLE);
|
||||
|
||||
memcpy(dir->u.nfs.nfs_fhandle, &fhandle.handle, fhandle.length);
|
||||
memcpy(ndir->nfs_fhandle, &fhandle.handle, fhandle.length);
|
||||
*dir = &ndir->nfs_base;
|
||||
nfs_semgive(nmp);
|
||||
return 0;
|
||||
|
||||
errout_with_semaphore:
|
||||
nfs_semgive(nmp);
|
||||
errout_with_ndir:
|
||||
kmm_free(ndir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nfs_closedir
|
||||
*
|
||||
* Description:
|
||||
* Close directory
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nfs_readdir
|
||||
*
|
||||
@@ -1483,6 +1526,7 @@ static int nfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct nfsmount *nmp;
|
||||
FAR struct nfs_dir_s *ndir;
|
||||
struct file_handle fhandle;
|
||||
struct nfs_fattr obj_attributes;
|
||||
uint32_t readsize;
|
||||
@@ -1502,6 +1546,7 @@ static int nfs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
nmp = mountpt->i_private;
|
||||
ndir = (FAR struct nfs_dir_s *)dir;
|
||||
|
||||
ret = nfs_semtake(nmp);
|
||||
if (ret < 0)
|
||||
@@ -1519,21 +1564,21 @@ read_dir:
|
||||
|
||||
/* Copy the variable length, directory file handle */
|
||||
|
||||
*ptr++ = txdr_unsigned((uint32_t)dir->u.nfs.nfs_fhsize);
|
||||
*ptr++ = txdr_unsigned((uint32_t)ndir->nfs_fhsize);
|
||||
reqlen += sizeof(uint32_t);
|
||||
|
||||
memcpy(ptr, dir->u.nfs.nfs_fhandle, dir->u.nfs.nfs_fhsize);
|
||||
reqlen += uint32_alignup(dir->u.nfs.nfs_fhsize);
|
||||
ptr += uint32_increment(dir->u.nfs.nfs_fhsize);
|
||||
memcpy(ptr, ndir->nfs_fhandle, ndir->nfs_fhsize);
|
||||
reqlen += uint32_alignup(ndir->nfs_fhsize);
|
||||
ptr += uint32_increment(ndir->nfs_fhsize);
|
||||
|
||||
/* Cookie and cookie verifier */
|
||||
|
||||
ptr[0] = dir->u.nfs.nfs_cookie[0];
|
||||
ptr[1] = dir->u.nfs.nfs_cookie[1];
|
||||
ptr[0] = ndir->nfs_cookie[0];
|
||||
ptr[1] = ndir->nfs_cookie[1];
|
||||
ptr += 2;
|
||||
reqlen += 2*sizeof(uint32_t);
|
||||
|
||||
memcpy(ptr, dir->u.nfs.nfs_verifier, DIRENT_NFS_VERFLEN);
|
||||
memcpy(ptr, ndir->nfs_verifier, DIRENT_NFS_VERFLEN);
|
||||
ptr += uint32_increment(DIRENT_NFS_VERFLEN);
|
||||
reqlen += DIRENT_NFS_VERFLEN;
|
||||
|
||||
@@ -1588,7 +1633,7 @@ read_dir:
|
||||
|
||||
/* Save the verification cookie */
|
||||
|
||||
memcpy(dir->u.nfs.nfs_verifier, ptr, DIRENT_NFS_VERFLEN);
|
||||
memcpy(ndir->nfs_verifier, ptr, DIRENT_NFS_VERFLEN);
|
||||
ptr += uint32_increment(DIRENT_NFS_VERFLEN);
|
||||
|
||||
next_entry:
|
||||
@@ -1650,8 +1695,8 @@ next_entry:
|
||||
|
||||
/* Save the cookie and increment the pointer to the next entry */
|
||||
|
||||
dir->u.nfs.nfs_cookie[0] = *ptr++;
|
||||
dir->u.nfs.nfs_cookie[1] = *ptr++;
|
||||
ndir->nfs_cookie[0] = *ptr++;
|
||||
ndir->nfs_cookie[1] = *ptr++;
|
||||
|
||||
/* Return the name of the node to the caller */
|
||||
|
||||
@@ -1674,8 +1719,8 @@ next_entry:
|
||||
* the file type.
|
||||
*/
|
||||
|
||||
fhandle.length = (uint32_t)dir->u.nfs.nfs_fhsize;
|
||||
memcpy(&fhandle.handle, dir->u.nfs.nfs_fhandle, fhandle.length);
|
||||
fhandle.length = (uint32_t)ndir->nfs_fhsize;
|
||||
memcpy(&fhandle.handle, ndir->nfs_fhandle, fhandle.length);
|
||||
|
||||
ret = nfs_lookup(nmp, entry->d_name, &fhandle, &obj_attributes, NULL);
|
||||
if (ret != OK)
|
||||
@@ -1744,19 +1789,23 @@ errout_with_semaphore:
|
||||
static int nfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct nfs_dir_s *ndir;
|
||||
|
||||
finfo("Entry\n");
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt != NULL && dir != NULL);
|
||||
|
||||
ndir = (FAR struct nfs_dir_s *)dir;
|
||||
|
||||
/* Reset the NFS-specific portions of dirent structure, retaining only the
|
||||
* file handle.
|
||||
*/
|
||||
|
||||
memset(&dir->u.nfs.nfs_verifier, 0, DIRENT_NFS_VERFLEN);
|
||||
dir->u.nfs.nfs_cookie[0] = 0;
|
||||
dir->u.nfs.nfs_cookie[1] = 0;
|
||||
memset(&ndir->nfs_verifier, 0, DIRENT_NFS_VERFLEN);
|
||||
ndir->nfs_cookie[0] = 0;
|
||||
ndir->nfs_cookie[1] = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1108,7 +1108,9 @@ int nxffs_truncate(FAR struct file *filep, off_t length);
|
||||
#endif
|
||||
|
||||
int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
int nxffs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
int nxffs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
|
||||
+48
-10
@@ -32,10 +32,20 @@
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "nxffs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
struct nxffs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
off_t offset;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -49,9 +59,10 @@
|
||||
****************************************************************************/
|
||||
|
||||
int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
struct nxffs_volume_s *volume;
|
||||
FAR struct nxffs_volume_s *volume;
|
||||
FAR struct nxffs_dir_s *ndir;
|
||||
int ret;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
@@ -63,10 +74,16 @@ int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
/* Recover the file system state from the NuttX inode instance */
|
||||
|
||||
volume = mountpt->i_private;
|
||||
ndir = kmm_zalloc(sizeof(*ndir));
|
||||
if (ndir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = nxsem_wait(&volume->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
goto errout_with_ndir;
|
||||
}
|
||||
|
||||
/* The requested directory must be the volume-relative "root" directory */
|
||||
@@ -79,16 +96,35 @@ int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
|
||||
/* Set the offset to the offset to the first valid inode */
|
||||
|
||||
dir->u.nxffs.nx_offset = volume->inoffset;
|
||||
ret = OK;
|
||||
ndir->offset = volume->inoffset;
|
||||
nxsem_post(&volume->exclsem);
|
||||
*dir = &ndir->base;
|
||||
return 0;
|
||||
|
||||
errout_with_semaphore:
|
||||
nxsem_post(&volume->exclsem);
|
||||
|
||||
errout:
|
||||
errout_with_ndir:
|
||||
kmm_free(ndir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxffs_closedir
|
||||
*
|
||||
* Description:
|
||||
* Close directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxffs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxffs_readdir
|
||||
*
|
||||
@@ -101,6 +137,7 @@ int nxffs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *dentry)
|
||||
{
|
||||
FAR struct nxffs_volume_s *volume;
|
||||
FAR struct nxffs_dir_s *ndir;
|
||||
struct nxffs_entry_s entry;
|
||||
off_t offset;
|
||||
int ret;
|
||||
@@ -112,6 +149,7 @@ int nxffs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover the file system state from the NuttX inode instance */
|
||||
|
||||
volume = mountpt->i_private;
|
||||
ndir = (FAR struct nxffs_dir_s *)dir;
|
||||
ret = nxsem_wait(&volume->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -120,7 +158,7 @@ int nxffs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Read the next inode header from the offset */
|
||||
|
||||
offset = dir->u.nxffs.nx_offset;
|
||||
offset = ndir->offset;
|
||||
ret = nxffs_nextentry(volume, offset, &entry);
|
||||
|
||||
/* If the read was successful, then handle the reported inode. Note
|
||||
@@ -138,7 +176,7 @@ int nxffs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Discard this entry and set the next offset. */
|
||||
|
||||
dir->u.nxffs.nx_offset = nxffs_inodeend(volume, &entry);
|
||||
ndir->offset = nxffs_inodeend(volume, &entry);
|
||||
nxffs_freeentry(&entry);
|
||||
ret = OK;
|
||||
}
|
||||
@@ -179,7 +217,7 @@ int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir)
|
||||
|
||||
/* Reset the offset to the FLASH offset to the first valid inode */
|
||||
|
||||
dir->u.nxffs.nx_offset = volume->inoffset;
|
||||
((FAR struct nxffs_dir_s *)dir)->offset = volume->inoffset;
|
||||
ret = OK;
|
||||
|
||||
nxsem_post(&volume->exclsem);
|
||||
|
||||
@@ -66,7 +66,7 @@ const struct mountpt_operations nxffs_operations =
|
||||
#endif
|
||||
|
||||
nxffs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
nxffs_closedir, /* closedir */
|
||||
nxffs_readdir, /* readdir */
|
||||
nxffs_rewinddir, /* rewinddir */
|
||||
|
||||
|
||||
+16
-27
@@ -45,7 +45,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "mount/mount.h"
|
||||
|
||||
@@ -224,7 +223,7 @@ static int procfs_fstat(FAR const struct file *filep,
|
||||
FAR struct stat *buf);
|
||||
|
||||
static int procfs_opendir(FAR struct inode *mountpt, const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int procfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int procfs_readdir(FAR struct inode *mountpt,
|
||||
@@ -551,14 +550,12 @@ static int procfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
||||
****************************************************************************/
|
||||
|
||||
static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct procfs_level0_s *level0;
|
||||
FAR struct procfs_dir_priv_s *dirpriv;
|
||||
FAR void *priv = NULL;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(mountpt && relpath && dir && !dir->u.procfs);
|
||||
DEBUGASSERT(mountpt && dir && relpath);
|
||||
|
||||
/* The relative must be either:
|
||||
*
|
||||
@@ -601,7 +598,7 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
level0->lastlen = 0;
|
||||
level0->base.procfsentry = NULL;
|
||||
|
||||
priv = (FAR void *)level0;
|
||||
*dir = (FAR struct fs_dirent_s *)level0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -619,7 +616,7 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
{
|
||||
/* Match found! Call the handler's opendir routine. If
|
||||
* successful, this opendir routine will create an entry
|
||||
* derived from struct procfs_dir_priv_s as dir->u.procfs.
|
||||
* derived from struct procfs_dir_priv_s as dir.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_procfs_entries[x].ops != NULL &&
|
||||
@@ -629,11 +626,13 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
DEBUGASSERT(dir->u.procfs);
|
||||
FAR struct procfs_dir_priv_s *dirpriv;
|
||||
|
||||
DEBUGASSERT(*dir);
|
||||
|
||||
/* Set the procfs_entry handler */
|
||||
|
||||
dirpriv = (FAR struct procfs_dir_priv_s *)dir->u.procfs;
|
||||
dirpriv = (FAR struct procfs_dir_priv_s *)(*dir);
|
||||
dirpriv->procfsentry = &g_procfs_entries[x];
|
||||
}
|
||||
|
||||
@@ -671,7 +670,7 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
level1->lastlen = 0;
|
||||
level1->base.procfsentry = NULL;
|
||||
|
||||
priv = (FAR void *)level1;
|
||||
*dir = (FAR struct fs_dirent_s *)level1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -682,7 +681,6 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
}
|
||||
}
|
||||
|
||||
dir->u.procfs = priv;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -696,17 +694,8 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
static int procfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct procfs_dir_priv_s *priv;
|
||||
|
||||
DEBUGASSERT(mountpt && dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(mountpt && dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -730,8 +719,8 @@ static int procfs_readdir(FAR struct inode *mountpt,
|
||||
pid_t pid;
|
||||
int ret = -ENOENT;
|
||||
|
||||
DEBUGASSERT(mountpt && dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(mountpt && dir);
|
||||
priv = (FAR struct procfs_dir_priv_s *)dir;
|
||||
|
||||
/* Are we reading the 1st directory level with dynamic PID and static
|
||||
* entries?
|
||||
@@ -953,8 +942,8 @@ static int procfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct procfs_dir_priv_s *priv;
|
||||
|
||||
DEBUGASSERT(mountpt && dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(mountpt && dir);
|
||||
priv = (FAR struct procfs_dir_priv_s *)dir;
|
||||
|
||||
if (priv->level > 0 && priv->procfsentry == NULL)
|
||||
{
|
||||
|
||||
+11
-20
@@ -51,7 +51,6 @@
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
#if defined(CONFIG_SCHED_CPULOAD) || defined(CONFIG_SCHED_CRITMONITOR)
|
||||
@@ -223,7 +222,7 @@ static int proc_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
|
||||
static int proc_opendir(const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int proc_closedir(FAR struct fs_dirent_s *dir);
|
||||
static int proc_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -1771,7 +1770,8 @@ static int proc_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
static int proc_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct proc_dir_s *procdir;
|
||||
FAR const struct proc_node_s *node;
|
||||
@@ -1781,7 +1781,7 @@ static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
pid_t pid;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath != NULL && dir != NULL && dir->u.procfs == NULL);
|
||||
DEBUGASSERT(relpath != NULL);
|
||||
|
||||
/* The relative must be either:
|
||||
*
|
||||
@@ -1887,7 +1887,7 @@ static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
}
|
||||
|
||||
procdir->pid = pid;
|
||||
dir->u.procfs = (FAR void *)procdir;
|
||||
*dir = (FAR struct fs_dirent_s *)procdir;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1900,17 +1900,8 @@ static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
|
||||
static int proc_closedir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct proc_dir_s *priv;
|
||||
|
||||
DEBUGASSERT(dir != NULL && dir->u.procfs != NULL);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir != NULL);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1931,8 +1922,8 @@ static int proc_readdir(FAR struct fs_dirent_s *dir,
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(dir != NULL && dir->u.procfs != NULL);
|
||||
procdir = dir->u.procfs;
|
||||
DEBUGASSERT(dir != NULL);
|
||||
procdir = (FAR struct proc_dir_s *)dir;
|
||||
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
@@ -2011,8 +2002,8 @@ static int proc_rewinddir(struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct proc_dir_s *priv;
|
||||
|
||||
DEBUGASSERT(dir != NULL && dir->u.procfs != NULL);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(dir != NULL);
|
||||
priv = (FAR struct proc_dir_s *)dir;
|
||||
|
||||
priv->base.index = 0;
|
||||
return OK;
|
||||
|
||||
+12
-21
@@ -42,7 +42,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
@@ -100,7 +99,7 @@ static int skel_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
|
||||
static int skel_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int skel_closedir(FAR struct fs_dirent_s *dir);
|
||||
static int skel_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -338,12 +337,13 @@ static int skel_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int skel_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
static int skel_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct skel_level1_s *level1;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath && dir && !dir->u.procfs);
|
||||
DEBUGASSERT(relpath);
|
||||
|
||||
/* The path refers to the 1st level sbdirectory. Allocate the level1
|
||||
* dirent structure.
|
||||
@@ -366,7 +366,7 @@ static int skel_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
level1->base.nentries = 0;
|
||||
level1->base.index = 0;
|
||||
|
||||
dir->u.procfs = (FAR void *) level1;
|
||||
*dir = (FAR struct fs_dirent_s *)level1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -379,17 +379,8 @@ static int skel_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
|
||||
|
||||
static int skel_closedir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct skel_level1_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -404,12 +395,12 @@ static int skel_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct skel_level1_s *level1;
|
||||
char filename[16];
|
||||
char filename[16];
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
level1 = (FAR struct skel_level1_s *)dir;
|
||||
|
||||
/* TODO: Perform device specific readdir function here. This may
|
||||
* or may not involve validating the nentries variable
|
||||
@@ -466,8 +457,8 @@ static int skel_rewinddir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct skel_level1_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
priv = (FAR struct skel_level1_s *)dir;
|
||||
|
||||
priv->base.index = 0;
|
||||
return OK;
|
||||
|
||||
+71
-19
@@ -40,10 +40,27 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "fs_romfs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure represents one entry node in the romfs file system */
|
||||
|
||||
struct romfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base; /* Vfs directory structure */
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
FAR struct romfs_nodeinfo_s **firstnode; /* The address of first node in the directory */
|
||||
FAR struct romfs_nodeinfo_s **currnode; /* The address of current node into the directory */
|
||||
#else
|
||||
off_t firstoffset; /* Offset to the first entry in the directory */
|
||||
off_t curroffset; /* Current offset into the directory contents */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -64,7 +81,9 @@ static int romfs_fstat(FAR const struct file *filep,
|
||||
|
||||
static int romfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int romfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int romfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -108,7 +127,7 @@ const struct mountpt_operations romfs_operations =
|
||||
NULL, /* truncate */
|
||||
|
||||
romfs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
romfs_closedir, /* closedir */
|
||||
romfs_readdir, /* readdir */
|
||||
romfs_rewinddir, /* rewinddir */
|
||||
|
||||
@@ -738,9 +757,10 @@ static int romfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
||||
****************************************************************************/
|
||||
|
||||
static int romfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct romfs_mountpt_s *rm;
|
||||
FAR struct romfs_dir_s *rdir;
|
||||
struct romfs_nodeinfo_s nodeinfo;
|
||||
int ret;
|
||||
|
||||
@@ -754,12 +774,18 @@ static int romfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
|
||||
rm = mountpt->i_private;
|
||||
|
||||
rdir = kmm_zalloc(sizeof(*rdir));
|
||||
if (rdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
ret = romfs_semtake(rm);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_rdir;
|
||||
}
|
||||
|
||||
ret = romfs_checkmount(rm);
|
||||
@@ -792,18 +818,40 @@ static int romfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
/* The entry is a directory */
|
||||
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
dir->u.romfs.fr_firstnode = nodeinfo.rn_child;
|
||||
dir->u.romfs.fr_currnode = nodeinfo.rn_child;
|
||||
rdir->firstnode = nodeinfo.rn_child;
|
||||
rdir->currnode = nodeinfo.rn_child;
|
||||
#else
|
||||
dir->u.romfs.fr_firstoffset = nodeinfo.rn_offset;
|
||||
dir->u.romfs.fr_curroffset = nodeinfo.rn_offset;
|
||||
rdir->firstoffset = nodeinfo.rn_offset;
|
||||
rdir->curroffset = nodeinfo.rn_offset;
|
||||
#endif
|
||||
|
||||
*dir = &rdir->base;
|
||||
romfs_semgive(rm);
|
||||
return OK;
|
||||
|
||||
errout_with_semaphore:
|
||||
romfs_semgive(rm);
|
||||
|
||||
errout_with_rdir:
|
||||
kmm_free(rdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_closedir
|
||||
*
|
||||
* Description: Close the directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int romfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_readdir
|
||||
*
|
||||
@@ -816,6 +864,7 @@ static int romfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct romfs_mountpt_s *rm;
|
||||
FAR struct romfs_dir_s *rdir;
|
||||
#ifndef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
uint32_t linkoffset;
|
||||
uint32_t info;
|
||||
@@ -833,6 +882,7 @@ static int romfs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
rm = mountpt->i_private;
|
||||
rdir = (FAR struct romfs_dir_s *)dir;
|
||||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
@@ -856,9 +906,9 @@ static int romfs_readdir(FAR struct inode *mountpt,
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
if (!dir->u.romfs.fr_currnode || !(*dir->u.romfs.fr_currnode))
|
||||
if (!rdir->currnode || !(*rdir->currnode))
|
||||
#else
|
||||
if (!dir->u.romfs.fr_curroffset)
|
||||
if (!rdir->curroffset)
|
||||
#endif
|
||||
{
|
||||
/* We signal the end of the directory by returning the
|
||||
@@ -871,14 +921,14 @@ static int romfs_readdir(FAR struct inode *mountpt,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
next = (*dir->u.romfs.fr_currnode)->rn_next;
|
||||
strlcpy(entry->d_name, (*dir->u.romfs.fr_currnode)->rn_name,
|
||||
next = (*rdir->currnode)->rn_next;
|
||||
strlcpy(entry->d_name, (*rdir->currnode)->rn_name,
|
||||
sizeof(entry->d_name));
|
||||
dir->u.romfs.fr_currnode++;
|
||||
rdir->currnode++;
|
||||
#else
|
||||
/* Parse the directory entry */
|
||||
|
||||
ret = romfs_parsedirentry(rm, dir->u.romfs.fr_curroffset, &linkoffset,
|
||||
ret = romfs_parsedirentry(rm, rdir->curroffset, &linkoffset,
|
||||
&next, &info, &size);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -888,7 +938,7 @@ static int romfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Save the filename */
|
||||
|
||||
ret = romfs_parsefilename(rm, dir->u.romfs.fr_curroffset,
|
||||
ret = romfs_parsefilename(rm, rdir->curroffset,
|
||||
entry->d_name);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -898,7 +948,7 @@ static int romfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Set up the next directory entry offset */
|
||||
|
||||
dir->u.romfs.fr_curroffset = next & RFNEXT_OFFSETMASK;
|
||||
rdir->curroffset = next & RFNEXT_OFFSETMASK;
|
||||
#endif
|
||||
|
||||
/* Check the file type */
|
||||
@@ -936,6 +986,7 @@ static int romfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct romfs_mountpt_s *rm;
|
||||
FAR struct romfs_dir_s *rdir;
|
||||
int ret;
|
||||
|
||||
finfo("Entry\n");
|
||||
@@ -947,6 +998,7 @@ static int romfs_rewinddir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
rm = mountpt->i_private;
|
||||
rdir = (FAR struct romfs_dir_s *)dir;
|
||||
|
||||
/* Make sure that the mount is still healthy */
|
||||
|
||||
@@ -960,9 +1012,9 @@ static int romfs_rewinddir(FAR struct inode *mountpt,
|
||||
if (ret == OK)
|
||||
{
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
dir->u.romfs.fr_currnode = dir->u.romfs.fr_firstnode;
|
||||
rdir->currnode = rdir->firstnode;
|
||||
#else
|
||||
dir->u.romfs.fr_curroffset = dir->u.romfs.fr_firstoffset;
|
||||
rdir->curroffset = rdir->firstoffset;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -30,8 +30,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -158,18 +156,20 @@ struct romfs_file_s
|
||||
char rf_path[1]; /* Path of open file */
|
||||
};
|
||||
|
||||
/* This structure is used internally for describing the result of
|
||||
* walking a path
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
struct romfs_nodeinfo_s
|
||||
{
|
||||
uint32_t rn_offset; /* Offset of real file header */
|
||||
uint32_t rn_next; /* Offset of the next file header+flags */
|
||||
uint32_t rn_size; /* Size (if file) */
|
||||
};
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
FAR struct romfs_nodeinfo_s **rn_child; /* The node array for link to lower level */
|
||||
uint16_t rn_count; /* The count of node in rn_child level */
|
||||
#endif
|
||||
uint32_t rn_offset; /* Offset of real file header */
|
||||
uint32_t rn_next; /* Offset of the next file header+flags */
|
||||
uint32_t rn_size; /* Size (if file) */
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
uint8_t rn_namesize; /* The length of name of the entry */
|
||||
char rn_name[1]; /* The name to the entry */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
|
||||
#include "fs_romfs.h"
|
||||
|
||||
+35
-13
@@ -38,7 +38,6 @@
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/fs/rpmsgfs.h>
|
||||
|
||||
@@ -54,6 +53,12 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct rpmsgfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
FAR void *dir;
|
||||
};
|
||||
|
||||
/* This structure describes the state of one open file. This structure
|
||||
* is protected by the volume semaphore.
|
||||
*/
|
||||
@@ -109,7 +114,7 @@ static int rpmsgfs_ftruncate(FAR struct file *filep,
|
||||
|
||||
static int rpmsgfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int rpmsgfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int rpmsgfs_readdir(FAR struct inode *mountpt,
|
||||
@@ -869,9 +874,10 @@ static int rpmsgfs_ftruncate(FAR struct file *filep, off_t length)
|
||||
|
||||
static int rpmsgfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct rpmsgfs_mountpt_s *fs;
|
||||
FAR struct rpmsgfs_dir_s *rdir;
|
||||
char path[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
@@ -882,13 +888,18 @@ static int rpmsgfs_opendir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
rdir = kmm_zalloc(sizeof(struct rpmsgfs_dir_s));
|
||||
if (rdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
ret = rpmsgfs_semtake(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_rdir;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
@@ -897,18 +908,23 @@ static int rpmsgfs_opendir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host's opendir function */
|
||||
|
||||
dir->u.rpmsgfs.fs_dir = rpmsgfs_client_opendir(fs->handle, path);
|
||||
if (dir->u.rpmsgfs.fs_dir == NULL)
|
||||
rdir->dir = rpmsgfs_client_opendir(fs->handle, path);
|
||||
if (rdir->dir == NULL)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
kmm_free(rdir);
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
*dir = (FAR struct fs_dirent_s *)rdir;
|
||||
rpmsgfs_semgive(fs);
|
||||
return OK;
|
||||
|
||||
errout_with_semaphore:
|
||||
|
||||
rpmsgfs_semgive(fs);
|
||||
|
||||
errout_with_rdir:
|
||||
kmm_free(rdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -922,7 +938,8 @@ errout_with_semaphore:
|
||||
static int rpmsgfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
struct rpmsgfs_mountpt_s *fs;
|
||||
FAR struct rpmsgfs_mountpt_s *fs;
|
||||
FAR struct rpmsgfs_dir_s *rdir;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -932,6 +949,7 @@ static int rpmsgfs_closedir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
rdir = (FAR struct rpmsgfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -943,9 +961,10 @@ static int rpmsgfs_closedir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host's closedir function */
|
||||
|
||||
rpmsgfs_client_closedir(fs->handle, dir->u.rpmsgfs.fs_dir);
|
||||
rpmsgfs_client_closedir(fs->handle, rdir->dir);
|
||||
|
||||
rpmsgfs_semgive(fs);
|
||||
kmm_free(rdir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -961,6 +980,7 @@ static int rpmsgfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct rpmsgfs_mountpt_s *fs;
|
||||
FAR struct rpmsgfs_dir_s *rdir;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -970,6 +990,7 @@ static int rpmsgfs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
rdir = (FAR struct rpmsgfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -981,8 +1002,7 @@ static int rpmsgfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host OS's readdir function */
|
||||
|
||||
ret = rpmsgfs_client_readdir(fs->handle,
|
||||
dir->u.rpmsgfs.fs_dir, entry);
|
||||
ret = rpmsgfs_client_readdir(fs->handle, rdir->dir, entry);
|
||||
|
||||
rpmsgfs_semgive(fs);
|
||||
return ret;
|
||||
@@ -999,6 +1019,7 @@ static int rpmsgfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct rpmsgfs_mountpt_s *fs;
|
||||
FAR struct rpmsgfs_dir_s *rdir;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -1008,6 +1029,7 @@ static int rpmsgfs_rewinddir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
rdir = (FAR struct rpmsgfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -1019,7 +1041,7 @@ static int rpmsgfs_rewinddir(FAR struct inode *mountpt,
|
||||
|
||||
/* Call the host and let it do all the work */
|
||||
|
||||
rpmsgfs_client_rewinddir(fs->handle, dir->u.rpmsgfs.fs_dir);
|
||||
rpmsgfs_client_rewinddir(fs->handle, rdir->dir);
|
||||
|
||||
rpmsgfs_semgive(fs);
|
||||
return OK;
|
||||
|
||||
+10
-20
@@ -42,7 +42,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/mtd/smart.h>
|
||||
|
||||
@@ -116,7 +115,7 @@ static int smartfs_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
|
||||
static int smartfs_opendir(const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int smartfs_closedir(FAR struct fs_dirent_s *dir);
|
||||
static int smartfs_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -535,13 +534,13 @@ static int smartfs_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
****************************************************************************/
|
||||
|
||||
static int smartfs_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct smartfs_level1_s *level1;
|
||||
int ret;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath && dir && !dir->u.procfs);
|
||||
DEBUGASSERT(relpath);
|
||||
|
||||
/* The path refers to the 1st level subdirectory. Allocate the level1
|
||||
* dirent structure.
|
||||
@@ -562,7 +561,7 @@ static int smartfs_opendir(FAR const char *relpath,
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
dir->u.procfs = (FAR void *) level1;
|
||||
*dir = (FAR struct fs_dirent_s *)level1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -581,17 +580,8 @@ static int smartfs_opendir(FAR const char *relpath,
|
||||
|
||||
static int smartfs_closedir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct smartfs_level1_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -609,8 +599,8 @@ static int smartfs_readdir(FAR struct fs_dirent_s *dir,
|
||||
int ret;
|
||||
int index;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
level1 = (FAR struct smartfs_level1_s *)dir;
|
||||
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
@@ -690,8 +680,8 @@ static int smartfs_rewinddir(struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct smartfs_level1_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
priv = (FAR struct smartfs_level1_s *)dir;
|
||||
|
||||
priv->base.index = 0;
|
||||
return OK;
|
||||
|
||||
+71
-30
@@ -39,13 +39,24 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/fat.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
#include <nuttx/fs/smart.h>
|
||||
|
||||
#include "smartfs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
struct smartfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s fs_base; /* VFS directory structure */
|
||||
uint16_t fs_firstsector; /* First sector of directory list */
|
||||
uint16_t fs_currsector; /* Current sector of directory list */
|
||||
uint16_t fs_curroffset; /* Current offset within current sector */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -71,6 +82,8 @@ static int smartfs_truncate(FAR struct file *filep, off_t length);
|
||||
|
||||
static int smartfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int smartfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
@@ -135,7 +148,7 @@ const struct mountpt_operations smartfs_operations =
|
||||
smartfs_truncate, /* truncate */
|
||||
|
||||
smartfs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
smartfs_closedir, /* closedir */
|
||||
smartfs_readdir, /* readdir */
|
||||
smartfs_rewinddir, /* rewinddir */
|
||||
|
||||
@@ -1190,13 +1203,14 @@ errout_with_semaphore:
|
||||
|
||||
static int smartfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
struct smartfs_mountpt_s *fs;
|
||||
int ret;
|
||||
struct smartfs_entry_s entry;
|
||||
uint16_t parentdirsector;
|
||||
const char *filename;
|
||||
FAR struct smartfs_mountpt_s *fs;
|
||||
FAR struct smartfs_dir_s *sdir;
|
||||
int ret;
|
||||
struct smartfs_entry_s entry;
|
||||
uint16_t parentdirsector;
|
||||
FAR const char *filename;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
@@ -1205,13 +1219,18 @@ static int smartfs_opendir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
sdir = kmm_zalloc(sizeof(*sdir));
|
||||
if (sdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
ret = smartfs_semtake(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_sdir;
|
||||
}
|
||||
|
||||
/* Search for the path on the volume */
|
||||
@@ -1226,11 +1245,13 @@ static int smartfs_opendir(FAR struct inode *mountpt,
|
||||
|
||||
/* Populate our private data in the fs_dirent_s struct */
|
||||
|
||||
dir->u.smartfs.fs_firstsector = entry.firstsector;
|
||||
dir->u.smartfs.fs_currsector = entry.firstsector;
|
||||
dir->u.smartfs.fs_curroffset = sizeof(struct smartfs_chain_header_s);
|
||||
sdir->fs_firstsector = entry.firstsector;
|
||||
sdir->fs_currsector = entry.firstsector;
|
||||
sdir->fs_curroffset = sizeof(struct smartfs_chain_header_s);
|
||||
|
||||
ret = OK;
|
||||
*dir = &sdir->fs_base;
|
||||
smartfs_semgive(fs);
|
||||
return OK;
|
||||
|
||||
errout_with_semaphore:
|
||||
|
||||
@@ -1243,9 +1264,27 @@ errout_with_semaphore:
|
||||
}
|
||||
|
||||
smartfs_semgive(fs);
|
||||
|
||||
errout_with_sdir:
|
||||
kmm_free(sdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: smartfs_closedir
|
||||
*
|
||||
* Description: Close directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int smartfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: smartfs_readdir
|
||||
*
|
||||
@@ -1257,7 +1296,8 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *dentry)
|
||||
{
|
||||
struct smartfs_mountpt_s *fs;
|
||||
FAR struct smartfs_mountpt_s *fs;
|
||||
FAR struct smartfs_dir_s *sdir;
|
||||
int ret;
|
||||
uint16_t entrysize;
|
||||
struct smartfs_chain_header_s *header;
|
||||
@@ -1271,6 +1311,7 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
sdir = (FAR struct smartfs_dir_s *)dir;
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
@@ -1284,11 +1325,11 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
entrysize = sizeof(struct smartfs_entry_header_s) +
|
||||
fs->fs_llformat.namesize;
|
||||
while (dir->u.smartfs.fs_currsector != SMARTFS_ERASEDSTATE_16BIT)
|
||||
while (sdir->fs_currsector != SMARTFS_ERASEDSTATE_16BIT)
|
||||
{
|
||||
/* Read the logical sector */
|
||||
|
||||
readwrite.logsector = dir->u.smartfs.fs_currsector;
|
||||
readwrite.logsector = sdir->fs_currsector;
|
||||
readwrite.count = fs->fs_llformat.availbytes;
|
||||
readwrite.buffer = (uint8_t *)fs->fs_rwbuffer;
|
||||
readwrite.offset = 0;
|
||||
@@ -1300,12 +1341,12 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Now search for entries, starting at curroffset */
|
||||
|
||||
while (dir->u.smartfs.fs_curroffset < ret)
|
||||
while (sdir->fs_curroffset < ret)
|
||||
{
|
||||
/* Point to next entry */
|
||||
|
||||
entry = (struct smartfs_entry_header_s *) &fs->fs_rwbuffer[
|
||||
dir->u.smartfs.fs_curroffset];
|
||||
sdir->fs_curroffset];
|
||||
|
||||
/* Test if this entry is valid and active */
|
||||
|
||||
@@ -1316,9 +1357,9 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
{
|
||||
/* This entry isn't valid, skip it */
|
||||
|
||||
dir->u.smartfs.fs_curroffset += entrysize;
|
||||
sdir->fs_curroffset += entrysize;
|
||||
entry = (struct smartfs_entry_header_s *)
|
||||
&fs->fs_rwbuffer[dir->u.smartfs.fs_curroffset];
|
||||
&fs->fs_rwbuffer[sdir->fs_curroffset];
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -1341,16 +1382,16 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Now advance to the next entry */
|
||||
|
||||
dir->u.smartfs.fs_curroffset += entrysize;
|
||||
if (dir->u.smartfs.fs_curroffset + entrysize >=
|
||||
sdir->fs_curroffset += entrysize;
|
||||
if (sdir->fs_curroffset + entrysize >=
|
||||
fs->fs_llformat.availbytes)
|
||||
{
|
||||
/* We advanced past the end of the sector. Go to next sector */
|
||||
|
||||
dir->u.smartfs.fs_curroffset =
|
||||
sdir->fs_curroffset =
|
||||
sizeof(struct smartfs_chain_header_s);
|
||||
header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
|
||||
dir->u.smartfs.fs_currsector = SMARTFS_NEXTSECTOR(header);
|
||||
sdir->fs_currsector = SMARTFS_NEXTSECTOR(header);
|
||||
}
|
||||
|
||||
/* Now exit */
|
||||
@@ -1365,8 +1406,8 @@ static int smartfs_readdir(FAR struct inode *mountpt,
|
||||
*/
|
||||
|
||||
header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
|
||||
dir->u.smartfs.fs_curroffset = sizeof(struct smartfs_chain_header_s);
|
||||
dir->u.smartfs.fs_currsector = SMARTFS_NEXTSECTOR(header);
|
||||
sdir->fs_curroffset = sizeof(struct smartfs_chain_header_s);
|
||||
sdir->fs_currsector = SMARTFS_NEXTSECTOR(header);
|
||||
}
|
||||
|
||||
/* If we arrive here, then there are no more entries */
|
||||
@@ -1387,7 +1428,7 @@ errout_with_semaphore:
|
||||
|
||||
static int smartfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
{
|
||||
int ret = OK;
|
||||
FAR struct smartfs_dir_s *sdir = (FAR struct smartfs_dir_s *)dir;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
@@ -1395,10 +1436,10 @@ static int smartfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
|
||||
/* Reset the directory to the first entry */
|
||||
|
||||
dir->u.smartfs.fs_currsector = dir->u.smartfs.fs_firstsector;
|
||||
dir->u.smartfs.fs_curroffset = sizeof(struct smartfs_chain_header_s);
|
||||
sdir->fs_currsector = sdir->fs_firstsector;
|
||||
sdir->fs_curroffset = sizeof(struct smartfs_chain_header_s);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
+39
-17
@@ -50,7 +50,6 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <queue.h>
|
||||
@@ -59,7 +58,6 @@
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
#include "spiffs.h"
|
||||
@@ -75,6 +73,17 @@
|
||||
#define spiffs_lock_volume(fs) (nxrmutex_lock(&fs->lock))
|
||||
#define spiffs_unlock_volume(fs) (nxrmutex_unlock(&fs->lock))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
struct spiffs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
int16_t block;
|
||||
int entry;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -97,10 +106,9 @@ static int spiffs_fstat(FAR const struct file *filep, FAR struct stat *buf);
|
||||
static int spiffs_truncate(FAR struct file *filep, off_t length);
|
||||
|
||||
static int spiffs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath, FAR struct fs_dirent_s *dir);
|
||||
FAR const char *relpath, FAR struct fs_dirent_s **dir);
|
||||
static int spiffs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int spiffs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *dentry);
|
||||
@@ -1244,17 +1252,26 @@ static int spiffs_truncate(FAR struct file *filep, off_t length)
|
||||
****************************************************************************/
|
||||
|
||||
static int spiffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct spiffs_dir_s *sdir;
|
||||
|
||||
finfo("mountpt=%p relpath=%s dir=%p\n",
|
||||
mountpt, relpath, dir);
|
||||
|
||||
DEBUGASSERT(mountpt != NULL && relpath != NULL && dir != NULL);
|
||||
|
||||
sdir = kmm_zalloc(sizeof(*sdir));
|
||||
if (sdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Initialize for traversal of the 'directory' */
|
||||
|
||||
dir->u.spiffs.block = 0;
|
||||
dir->u.spiffs.entry = 0;
|
||||
sdir->block = 0;
|
||||
sdir->entry = 0;
|
||||
*dir = &sdir->base;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1263,13 +1280,11 @@ static int spiffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
****************************************************************************/
|
||||
|
||||
static int spiffs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
finfo("mountpt=%p dir=%p\n", mountpt, dir);
|
||||
DEBUGASSERT(mountpt != NULL && dir != NULL);
|
||||
|
||||
/* There is nothing to be done */
|
||||
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1281,6 +1296,7 @@ static int spiffs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *dentry)
|
||||
{
|
||||
FAR struct spiffs_dir_s *sdir;
|
||||
FAR struct spiffs_s *fs;
|
||||
int16_t blkndx;
|
||||
int entry;
|
||||
@@ -1289,6 +1305,8 @@ static int spiffs_readdir(FAR struct inode *mountpt,
|
||||
finfo("mountpt=%p dir=%p\n", mountpt, dir);
|
||||
DEBUGASSERT(mountpt != NULL && dir != NULL);
|
||||
|
||||
sdir = (FAR struct spiffs_dir_s *)dir;
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
@@ -1300,13 +1318,13 @@ static int spiffs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* And visit the next file object */
|
||||
|
||||
ret = spiffs_foreach_objlu(fs, dir->u.spiffs.block, dir->u.spiffs.entry,
|
||||
ret = spiffs_foreach_objlu(fs, sdir->block, sdir->entry,
|
||||
SPIFFS_VIS_NO_WRAP, 0, spiffs_readdir_callback,
|
||||
NULL, dentry, &blkndx, &entry);
|
||||
if (ret >= 0)
|
||||
{
|
||||
dir->u.spiffs.block = blkndx;
|
||||
dir->u.spiffs.entry = entry + 1;
|
||||
sdir->block = blkndx;
|
||||
sdir->entry = entry + 1;
|
||||
}
|
||||
|
||||
/* Release the lock on the file system */
|
||||
@@ -1322,13 +1340,17 @@ static int spiffs_readdir(FAR struct inode *mountpt,
|
||||
static int spiffs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct spiffs_dir_s *sdir;
|
||||
|
||||
finfo("mountpt=%p dir=%p\n", mountpt, dir);
|
||||
DEBUGASSERT(mountpt != NULL && dir != NULL);
|
||||
|
||||
sdir = (FAR struct spiffs_dir_s *)dir;
|
||||
|
||||
/* Reset as when opendir() was called. */
|
||||
|
||||
dir->u.spiffs.block = 0;
|
||||
dir->u.spiffs.entry = 0;
|
||||
sdir->block = 0;
|
||||
sdir->entry = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
+35
-12
@@ -29,14 +29,12 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
#include "fs_tmpfs.h"
|
||||
@@ -72,6 +70,17 @@
|
||||
#define tmpfs_unlock_directory(tdo) \
|
||||
nxrmutex_unlock(&tdo->tdo_lock)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type
|
||||
****************************************************************************/
|
||||
|
||||
struct tmpfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s tf_base; /* Vfs directory structure */
|
||||
FAR struct tmpfs_directory_s *tf_tdo; /* Directory being enumerated */
|
||||
unsigned int tf_index; /* Directory index */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -132,7 +141,7 @@ static int tmpfs_fstat(FAR const struct file *filep, FAR struct stat *buf);
|
||||
static int tmpfs_truncate(FAR struct file *filep, off_t length);
|
||||
|
||||
static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int tmpfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int tmpfs_readdir(FAR struct inode *mountpt,
|
||||
@@ -1802,9 +1811,10 @@ errout_with_lock:
|
||||
****************************************************************************/
|
||||
|
||||
static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct tmpfs_s *fs;
|
||||
FAR struct tmpfs_dir_s *tdir;
|
||||
FAR struct tmpfs_directory_s *tdo;
|
||||
int ret;
|
||||
|
||||
@@ -1817,11 +1827,18 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
fs = mountpt->i_private;
|
||||
DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL);
|
||||
|
||||
tdir = kmm_zalloc(sizeof(*tdir));
|
||||
if (tdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get exclusive access to the file system */
|
||||
|
||||
ret = tmpfs_lock(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
kmm_free(tdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1839,8 +1856,8 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
ret = tmpfs_find_directory(fs, relpath, strlen(relpath), &tdo, NULL);
|
||||
if (ret >= 0)
|
||||
{
|
||||
dir->u.tmpfs.tf_tdo = tdo;
|
||||
dir->u.tmpfs.tf_index = tdo->tdo_nentries;
|
||||
tdir->tf_tdo = tdo;
|
||||
tdir->tf_index = tdo->tdo_nentries;
|
||||
|
||||
tmpfs_unlock_directory(tdo);
|
||||
}
|
||||
@@ -1848,6 +1865,7 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
/* Release the lock on the file system and return the result */
|
||||
|
||||
tmpfs_unlock(fs);
|
||||
*dir = &tdir->tf_base;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1865,7 +1883,7 @@ static int tmpfs_closedir(FAR struct inode *mountpt,
|
||||
|
||||
/* Get the directory structure from the dir argument */
|
||||
|
||||
tdo = dir->u.tmpfs.tf_tdo;
|
||||
tdo = ((FAR struct tmpfs_dir_s *)dir)->tf_tdo;
|
||||
DEBUGASSERT(tdo != NULL);
|
||||
|
||||
/* Decrement the reference count on the directory object */
|
||||
@@ -1873,6 +1891,7 @@ static int tmpfs_closedir(FAR struct inode *mountpt,
|
||||
tmpfs_lock_directory(tdo);
|
||||
tdo->tdo_refs--;
|
||||
tmpfs_unlock_directory(tdo);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1885,6 +1904,7 @@ static int tmpfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct tmpfs_directory_s *tdo;
|
||||
FAR struct tmpfs_dir_s *tdir;
|
||||
unsigned int index;
|
||||
int ret;
|
||||
|
||||
@@ -1893,14 +1913,15 @@ static int tmpfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Get the directory structure from the dir argument and lock it */
|
||||
|
||||
tdo = dir->u.tmpfs.tf_tdo;
|
||||
tdir = (FAR struct tmpfs_dir_s *)dir;
|
||||
tdo = tdir->tf_tdo;
|
||||
DEBUGASSERT(tdo != NULL);
|
||||
|
||||
tmpfs_lock_directory(tdo);
|
||||
|
||||
/* Have we reached the end of the directory? */
|
||||
|
||||
index = dir->u.tmpfs.tf_index;
|
||||
index = tdir->tf_index;
|
||||
if (index-- == 0)
|
||||
{
|
||||
/* We signal the end of the directory by returning the special error:
|
||||
@@ -1940,7 +1961,7 @@ static int tmpfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Save the index for next time */
|
||||
|
||||
dir->u.tmpfs.tf_index = index;
|
||||
tdir->tf_index = index;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
@@ -1956,18 +1977,20 @@ static int tmpfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct tmpfs_directory_s *tdo;
|
||||
FAR struct tmpfs_dir_s *tdir;
|
||||
|
||||
finfo("mountpt: %p dir: %p\n", mountpt, dir);
|
||||
DEBUGASSERT(mountpt != NULL && dir != NULL);
|
||||
|
||||
/* Get the directory structure from the dir argument and lock it */
|
||||
|
||||
tdo = dir->u.tmpfs.tf_tdo;
|
||||
tdir = (FAR struct tmpfs_dir_s *)dir;
|
||||
tdo = tdir->tf_tdo;
|
||||
DEBUGASSERT(tdo != NULL);
|
||||
|
||||
/* Set the readdir index pass the end */
|
||||
|
||||
dir->u.tmpfs.tf_index = tdo->tdo_nentries;
|
||||
tdir->tf_index = tdo->tdo_nentries;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+91
-112
@@ -42,7 +42,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/unionfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
@@ -63,6 +62,16 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct unionfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s fu_base; /* Vfs directory structure */
|
||||
uint8_t fu_ndx; /* Index of file system being enumerated */
|
||||
bool fu_eod; /* True: At end of directory */
|
||||
bool fu_prefix[2]; /* True: Fake directory in prefix */
|
||||
FAR char *fu_relpath; /* Path being enumerated */
|
||||
FAR struct fs_dirent_s *fu_lower[2]; /* dirent struct used by contained file system */
|
||||
};
|
||||
|
||||
/* This structure describes one contained file system mountpoint */
|
||||
|
||||
struct unionfs_mountpt_s
|
||||
@@ -107,7 +116,7 @@ static int unionfs_tryopen(FAR struct file *filep,
|
||||
mode_t mode);
|
||||
static int unionfs_tryopendir(FAR struct inode *inode,
|
||||
FAR const char *relpath, FAR const char *prefix,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int unionfs_trymkdir(FAR struct inode *inode,
|
||||
FAR const char *relpath, FAR const char *prefix,
|
||||
mode_t mode);
|
||||
@@ -159,7 +168,7 @@ static int unionfs_truncate(FAR struct file *filep, off_t length);
|
||||
/* Operations on directories */
|
||||
|
||||
static int unionfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int unionfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
@@ -427,7 +436,7 @@ static int unionfs_tryopen(FAR struct file *filep, FAR const char *relpath,
|
||||
static int unionfs_tryopendir(FAR struct inode *inode,
|
||||
FAR const char *relpath,
|
||||
FAR const char *prefix,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR const struct mountpt_operations *ops;
|
||||
FAR const char *trypath;
|
||||
@@ -1411,13 +1420,11 @@ static int unionfs_truncate(FAR struct file *filep, off_t length)
|
||||
|
||||
static int unionfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct unionfs_inode_s *ui;
|
||||
FAR struct unionfs_mountpt_s *um;
|
||||
FAR struct fs_unionfsdir_s *fu;
|
||||
FAR const struct mountpt_operations *ops;
|
||||
FAR struct fs_dirent_s *lowerdir;
|
||||
FAR struct unionfs_dir_s *udir;
|
||||
int ret;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
@@ -1432,16 +1439,21 @@ static int unionfs_opendir(FAR struct inode *mountpt,
|
||||
DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
|
||||
ui = (FAR struct unionfs_inode_s *)mountpt->i_private;
|
||||
|
||||
udir = kmm_zalloc(sizeof(*udir));
|
||||
if (udir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get exclusive access to the file system data structures */
|
||||
|
||||
ret = unionfs_semtake(ui, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_udir;
|
||||
}
|
||||
|
||||
DEBUGASSERT(dir);
|
||||
fu = &dir->u.unionfs;
|
||||
|
||||
/* Clone the path. We will need this when we traverse file system 2 to
|
||||
* omit duplicates on file system 1.
|
||||
@@ -1449,44 +1461,24 @@ static int unionfs_opendir(FAR struct inode *mountpt,
|
||||
|
||||
if (strlen(relpath) > 0)
|
||||
{
|
||||
fu->fu_relpath = strdup(relpath);
|
||||
if (!fu->fu_relpath)
|
||||
udir->fu_relpath = strdup(relpath);
|
||||
if (!udir->fu_relpath)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate another dirent structure for the lower file system */
|
||||
|
||||
lowerdir = (FAR struct fs_dirent_s *)
|
||||
kmm_zalloc(sizeof(struct fs_dirent_s));
|
||||
if (lowerdir == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_relpath;
|
||||
}
|
||||
|
||||
/* Check file system 2 first. */
|
||||
|
||||
um = &ui->ui_fs[1];
|
||||
lowerdir->fd_root = um->um_node;
|
||||
ret = unionfs_tryopendir(um->um_node, relpath, um->um_prefix, lowerdir);
|
||||
ret = unionfs_tryopendir(um->um_node, relpath, um->um_prefix,
|
||||
&udir->fu_lower[1]);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Save the file system 2 access info */
|
||||
|
||||
fu->fu_ndx = 1;
|
||||
fu->fu_lower[1] = lowerdir;
|
||||
|
||||
/* Allocate yet another dirent structure for the lower file system 1 */
|
||||
|
||||
lowerdir = (FAR struct fs_dirent_s *)
|
||||
kmm_zalloc(sizeof(struct fs_dirent_s));
|
||||
if (lowerdir == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_fs2open;
|
||||
}
|
||||
udir->fu_ndx = 1;
|
||||
udir->fu_lower[1]->fd_root = um->um_node;
|
||||
}
|
||||
|
||||
/* Check if the user is stat'ing some "fake" node between the unionfs root
|
||||
@@ -1497,30 +1489,24 @@ static int unionfs_opendir(FAR struct inode *mountpt,
|
||||
{
|
||||
/* File system 2 prefix includes this relpath */
|
||||
|
||||
fu->fu_ndx = 1;
|
||||
fu->fu_prefix[1] = true;
|
||||
udir->fu_ndx = 1;
|
||||
udir->fu_prefix[1] = true;
|
||||
}
|
||||
|
||||
/* Check file system 1 last, possibly overwriting fu_ndx */
|
||||
|
||||
um = &ui->ui_fs[0];
|
||||
lowerdir->fd_root = um->um_node;
|
||||
ret = unionfs_tryopendir(um->um_node, relpath, um->um_prefix, lowerdir);
|
||||
ret = unionfs_tryopendir(um->um_node, relpath, um->um_prefix,
|
||||
&udir->fu_lower[0]);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Save the file system 1 access info */
|
||||
|
||||
fu->fu_ndx = 0;
|
||||
fu->fu_lower[0] = lowerdir;
|
||||
udir->fu_ndx = 0;
|
||||
udir->fu_lower[0]->fd_root = um->um_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* File system 1 was not opened... then we won't be needing that last
|
||||
* localdir allocation after all.
|
||||
*/
|
||||
|
||||
kmm_free(lowerdir);
|
||||
|
||||
/* Check if the user is stat'ing some "fake" node between the unionfs
|
||||
* root and the file system 1 root directory.
|
||||
*/
|
||||
@@ -1531,16 +1517,16 @@ static int unionfs_opendir(FAR struct inode *mountpt,
|
||||
* one
|
||||
*/
|
||||
|
||||
fu->fu_ndx = 0;
|
||||
fu->fu_prefix[0] = true;
|
||||
fu->fu_prefix[1] = false;
|
||||
udir->fu_ndx = 0;
|
||||
udir->fu_prefix[0] = true;
|
||||
udir->fu_prefix[1] = false;
|
||||
}
|
||||
|
||||
/* If the directory was not found on either file system, then we have
|
||||
* failed to open this path on either file system.
|
||||
*/
|
||||
|
||||
else if (fu->fu_lower[1] == NULL && !fu->fu_prefix[1])
|
||||
else if (udir->fu_lower[1] == NULL && !udir->fu_prefix[1])
|
||||
{
|
||||
/* Neither of the two path file systems include this relpath */
|
||||
|
||||
@@ -1555,26 +1541,20 @@ static int unionfs_opendir(FAR struct inode *mountpt,
|
||||
DEBUGASSERT(ui->ui_nopen > 0);
|
||||
|
||||
unionfs_semgive(ui);
|
||||
*dir = &udir->fu_base;
|
||||
return OK;
|
||||
|
||||
errout_with_fs2open:
|
||||
ops = ui->ui_fs[1].um_node->u.i_mops;
|
||||
DEBUGASSERT(ops != NULL);
|
||||
if (ops->closedir != NULL)
|
||||
{
|
||||
ret = ops->closedir(um->um_node, fu->fu_lower[1]);
|
||||
}
|
||||
|
||||
kmm_free(fu->fu_lower[1]);
|
||||
|
||||
errout_with_relpath:
|
||||
if (fu->fu_relpath != NULL)
|
||||
if (udir->fu_relpath != NULL)
|
||||
{
|
||||
kmm_free(fu->fu_relpath);
|
||||
kmm_free(udir->fu_relpath);
|
||||
}
|
||||
|
||||
errout_with_semaphore:
|
||||
unionfs_semgive(ui);
|
||||
|
||||
errout_with_udir:
|
||||
kmm_free(udir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1588,7 +1568,7 @@ static int unionfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct unionfs_inode_s *ui;
|
||||
FAR struct unionfs_mountpt_s *um;
|
||||
FAR const struct mountpt_operations *ops;
|
||||
FAR struct fs_unionfsdir_s *fu;
|
||||
FAR struct unionfs_dir_s *udir;
|
||||
int ret = OK;
|
||||
int i;
|
||||
|
||||
@@ -1608,7 +1588,7 @@ static int unionfs_closedir(FAR struct inode *mountpt,
|
||||
}
|
||||
|
||||
DEBUGASSERT(dir);
|
||||
fu = &dir->u.unionfs;
|
||||
udir = (FAR struct unionfs_dir_s *)dir;
|
||||
|
||||
/* Close both contained file systems */
|
||||
|
||||
@@ -1616,7 +1596,7 @@ static int unionfs_closedir(FAR struct inode *mountpt,
|
||||
{
|
||||
/* Was this file system opened? */
|
||||
|
||||
if (fu->fu_lower[i] != NULL)
|
||||
if (udir->fu_lower[i] != NULL)
|
||||
{
|
||||
um = &ui->ui_fs[i];
|
||||
|
||||
@@ -1628,26 +1608,22 @@ static int unionfs_closedir(FAR struct inode *mountpt,
|
||||
|
||||
if (ops->closedir != NULL)
|
||||
{
|
||||
ret = ops->closedir(um->um_node, fu->fu_lower[i]);
|
||||
ret = ops->closedir(um->um_node, udir->fu_lower[i]);
|
||||
}
|
||||
|
||||
/* Free the lower dirent structure */
|
||||
|
||||
kmm_free(fu->fu_lower[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free any allocated path */
|
||||
|
||||
if (fu->fu_relpath != NULL)
|
||||
if (udir->fu_relpath != NULL)
|
||||
{
|
||||
kmm_free(fu->fu_relpath);
|
||||
kmm_free(udir->fu_relpath);
|
||||
}
|
||||
|
||||
fu->fu_ndx = 0;
|
||||
fu->fu_relpath = NULL;
|
||||
fu->fu_lower[0] = NULL;
|
||||
fu->fu_lower[1] = NULL;
|
||||
udir->fu_ndx = 0;
|
||||
udir->fu_relpath = NULL;
|
||||
udir->fu_lower[0] = NULL;
|
||||
udir->fu_lower[1] = NULL;
|
||||
|
||||
/* Decrement the count of open reference. If that count would go to zero
|
||||
* and if the file system has been unmounted, then destroy the file system
|
||||
@@ -1678,7 +1654,7 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct unionfs_mountpt_s *um;
|
||||
FAR struct unionfs_mountpt_s *um0;
|
||||
FAR const struct mountpt_operations *ops;
|
||||
FAR struct fs_unionfsdir_s *fu;
|
||||
FAR struct unionfs_dir_s *udir;
|
||||
FAR char *relpath;
|
||||
struct stat buf;
|
||||
bool duplicate;
|
||||
@@ -1690,11 +1666,11 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
ui = (FAR struct unionfs_inode_s *)mountpt->i_private;
|
||||
|
||||
DEBUGASSERT(dir);
|
||||
fu = &dir->u.unionfs;
|
||||
udir = (FAR struct unionfs_dir_s *)dir;
|
||||
|
||||
/* Check if we are at the end of the directory listing. */
|
||||
|
||||
if (fu->fu_eod)
|
||||
if (udir->fu_eod)
|
||||
{
|
||||
/* End of file and error conditions are not distinguishable
|
||||
* with readdir. Here we return -ENOENT to signal the end
|
||||
@@ -1704,16 +1680,17 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
DEBUGASSERT(fu->fu_ndx == 0 || fu->fu_ndx == 1);
|
||||
um = &ui->ui_fs[fu->fu_ndx];
|
||||
DEBUGASSERT(udir->fu_ndx == 0 || udir->fu_ndx == 1);
|
||||
um = &ui->ui_fs[udir->fu_ndx];
|
||||
|
||||
/* Special case: If the open directory is a 'fake' node in the prefix on
|
||||
* one of the mounted file system, then we must also fake the return value.
|
||||
*/
|
||||
|
||||
if (fu->fu_prefix[fu->fu_ndx])
|
||||
if (udir->fu_prefix[udir->fu_ndx])
|
||||
{
|
||||
DEBUGASSERT(fu->fu_lower[fu->fu_ndx] == NULL && um->um_prefix != NULL);
|
||||
DEBUGASSERT(udir->fu_lower[udir->fu_ndx] == NULL &&
|
||||
um->um_prefix != NULL);
|
||||
|
||||
/* Copy the file system offset into the dirent structure.
|
||||
* REVISIT: This will not handle the case where the prefix contains
|
||||
@@ -1729,17 +1706,18 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Increment the index to file system 2 (maybe) */
|
||||
|
||||
if (fu->fu_ndx == 0 && (fu->fu_prefix[1] || fu->fu_lower[1] != NULL))
|
||||
if (udir->fu_ndx == 0 && (udir->fu_prefix[1] ||
|
||||
udir->fu_lower[1] != NULL))
|
||||
{
|
||||
/* Yes.. set up to do file system 2 next time */
|
||||
|
||||
fu->fu_ndx++;
|
||||
udir->fu_ndx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. we are finished */
|
||||
|
||||
fu->fu_eod = true;
|
||||
udir->fu_eod = true;
|
||||
}
|
||||
|
||||
return OK;
|
||||
@@ -1747,11 +1725,11 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* This is a normal, mediated file system readdir() */
|
||||
|
||||
DEBUGASSERT(fu->fu_lower[fu->fu_ndx] != NULL);
|
||||
DEBUGASSERT(udir->fu_lower[udir->fu_ndx] != NULL);
|
||||
DEBUGASSERT(um->um_node != NULL && um->um_node->u.i_mops != NULL);
|
||||
ops = um->um_node->u.i_mops;
|
||||
|
||||
finfo("fu_ndx: %d\n", fu->fu_ndx);
|
||||
finfo("fu_ndx: %d\n", udir->fu_ndx);
|
||||
|
||||
/* Perform the lower level readdir operation */
|
||||
|
||||
@@ -1763,7 +1741,8 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
{
|
||||
/* Read the directory entry */
|
||||
|
||||
ret = ops->readdir(um->um_node, fu->fu_lower[fu->fu_ndx], entry);
|
||||
ret = ops->readdir(um->um_node, udir->fu_lower[udir->fu_ndx],
|
||||
entry);
|
||||
|
||||
/* Did the read operation fail because we reached the end of the
|
||||
* directory? In that case, the error would be -ENOENT. If we
|
||||
@@ -1771,20 +1750,20 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
* move to the second file system (if there is one).
|
||||
*/
|
||||
|
||||
if (ret == -ENOENT && fu->fu_ndx == 0)
|
||||
if (ret == -ENOENT && udir->fu_ndx == 0)
|
||||
{
|
||||
/* Special case: If the open directory is a 'fake' node in the
|
||||
* prefix on file system2, then we must also fake the return
|
||||
* value.
|
||||
*/
|
||||
|
||||
if (fu->fu_prefix[1])
|
||||
if (udir->fu_prefix[1])
|
||||
{
|
||||
DEBUGASSERT(fu->fu_lower[1] == NULL);
|
||||
DEBUGASSERT(udir->fu_lower[1] == NULL);
|
||||
|
||||
/* Switch to the second file system */
|
||||
|
||||
fu->fu_ndx = 1;
|
||||
udir->fu_ndx = 1;
|
||||
um = &ui->ui_fs[1];
|
||||
|
||||
DEBUGASSERT(um != NULL && um->um_prefix != NULL);
|
||||
@@ -1804,13 +1783,13 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Mark the end of the directory listing */
|
||||
|
||||
fu->fu_eod = true;
|
||||
udir->fu_eod = true;
|
||||
|
||||
/* Check if have already reported something of this name
|
||||
* in file system 1.
|
||||
*/
|
||||
|
||||
relpath = unionfs_relpath(fu->fu_relpath, um->um_prefix);
|
||||
relpath = unionfs_relpath(udir->fu_relpath, um->um_prefix);
|
||||
if (relpath)
|
||||
{
|
||||
int tmp;
|
||||
@@ -1845,11 +1824,11 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* No.. check for a normal directory access */
|
||||
|
||||
else if (fu->fu_lower[1] != NULL)
|
||||
else if (udir->fu_lower[1] != NULL)
|
||||
{
|
||||
/* Switch to the second file system */
|
||||
|
||||
fu->fu_ndx = 1;
|
||||
udir->fu_ndx = 1;
|
||||
um = &ui->ui_fs[1];
|
||||
|
||||
DEBUGASSERT(um != NULL && um->um_node != NULL &&
|
||||
@@ -1863,7 +1842,7 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
if (ops->rewinddir != NULL)
|
||||
{
|
||||
ret = ops->rewinddir(um->um_node, fu->fu_lower[1]);
|
||||
ret = ops->rewinddir(um->um_node, udir->fu_lower[1]);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
@@ -1872,7 +1851,7 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
/* Then try the read operation again */
|
||||
|
||||
ret = ops->readdir(um->um_node, fu->fu_lower[1], entry);
|
||||
ret = ops->readdir(um->um_node, udir->fu_lower[1], entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1883,14 +1862,14 @@ static int unionfs_readdir(FAR struct inode *mountpt,
|
||||
*/
|
||||
|
||||
duplicate = false;
|
||||
if (ret >= 0 && fu->fu_ndx == 1 && fu->fu_lower[0] != NULL)
|
||||
if (ret >= 0 && udir->fu_ndx == 1 && udir->fu_lower[0] != NULL)
|
||||
{
|
||||
/* Get the relative path to the same file on file system 1.
|
||||
* NOTE: the on any failures we just assume that the filep
|
||||
* is not a duplicate.
|
||||
*/
|
||||
|
||||
relpath = unionfs_relpath(fu->fu_relpath, entry->d_name);
|
||||
relpath = unionfs_relpath(udir->fu_relpath, entry->d_name);
|
||||
if (relpath)
|
||||
{
|
||||
int tmp;
|
||||
@@ -1931,7 +1910,7 @@ static int unionfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
FAR struct unionfs_inode_s *ui;
|
||||
FAR struct unionfs_mountpt_s *um;
|
||||
FAR const struct mountpt_operations *ops;
|
||||
FAR struct fs_unionfsdir_s *fu;
|
||||
FAR struct unionfs_dir_s *udir;
|
||||
int ret = -EINVAL;
|
||||
|
||||
finfo("mountpt=%p dir=%p\n", mountpt, dir);
|
||||
@@ -1942,24 +1921,24 @@ static int unionfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
ui = (FAR struct unionfs_inode_s *)mountpt->i_private;
|
||||
|
||||
DEBUGASSERT(dir);
|
||||
fu = &dir->u.unionfs;
|
||||
udir = (FAR struct unionfs_dir_s *)dir;
|
||||
|
||||
/* Were we currently enumerating on file system 1? If not, is an
|
||||
* enumeration possible on file system 1?
|
||||
*/
|
||||
|
||||
DEBUGASSERT(fu->fu_ndx == 0 || fu->fu_ndx == 1);
|
||||
if (/* fu->fu_ndx != 0 && */ fu->fu_prefix[0] || fu->fu_lower[0] != NULL)
|
||||
DEBUGASSERT(udir->fu_ndx == 0 || udir->fu_ndx == 1);
|
||||
if (/* udir->fu_ndx != 0 && */ udir->fu_prefix[0] || udir->fu_lower[0] != NULL)
|
||||
{
|
||||
/* Yes.. switch to file system 1 */
|
||||
|
||||
fu->fu_ndx = 0;
|
||||
udir->fu_ndx = 0;
|
||||
}
|
||||
|
||||
if (!fu->fu_prefix[fu->fu_ndx])
|
||||
if (!udir->fu_prefix[udir->fu_ndx])
|
||||
{
|
||||
DEBUGASSERT(fu->fu_lower[fu->fu_ndx] != NULL);
|
||||
um = &ui->ui_fs[fu->fu_ndx];
|
||||
DEBUGASSERT(udir->fu_lower[udir->fu_ndx] != NULL);
|
||||
um = &ui->ui_fs[udir->fu_ndx];
|
||||
|
||||
DEBUGASSERT(um != NULL && um->um_node != NULL &&
|
||||
um->um_node->u.i_mops != NULL);
|
||||
@@ -1969,7 +1948,7 @@ static int unionfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
|
||||
if (ops->rewinddir != NULL)
|
||||
{
|
||||
ret = ops->rewinddir(um->um_node, fu->fu_lower[fu->fu_ndx]);
|
||||
ret = ops->rewinddir(um->um_node, udir->fu_lower[udir->fu_ndx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-7
@@ -43,7 +43,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/userfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
@@ -58,6 +57,12 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct userfs_dir_s
|
||||
{
|
||||
struct fs_dirent_s base;
|
||||
FAR void *dir;
|
||||
};
|
||||
|
||||
/* This structure holds the internal state of the UserFS proxy */
|
||||
|
||||
struct userfs_state_s
|
||||
@@ -106,7 +111,7 @@ static int userfs_fstat(FAR const struct file *filep,
|
||||
static int userfs_truncate(FAR struct file *filep, off_t length);
|
||||
|
||||
static int userfs_opendir(FAR struct inode *mountpt,
|
||||
FAR const char *relpath, FAR struct fs_dirent_s *dir);
|
||||
FAR const char *relpath, FAR struct fs_dirent_s **dir);
|
||||
static int userfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
static int userfs_readdir(FAR struct inode *mountpt,
|
||||
@@ -1071,8 +1076,9 @@ static int userfs_truncate(FAR struct file *filep, off_t length)
|
||||
****************************************************************************/
|
||||
|
||||
static int userfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct userfs_dir_s *udir;
|
||||
FAR struct userfs_state_s *priv;
|
||||
FAR struct userfs_opendir_request_s *req;
|
||||
FAR struct userfs_opendir_response_s *resp;
|
||||
@@ -1150,7 +1156,14 @@ static int userfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
/* Save the opaque dir reference in struct fs_dirent_s */
|
||||
|
||||
DEBUGASSERT(dir != NULL);
|
||||
dir->u.userfs.fs_dir = resp->dir;
|
||||
udir = kmm_zalloc(sizeof(struct userfs_dir_s));
|
||||
if (udir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
udir->dir = resp->dir;
|
||||
*dir = (FAR struct fs_dirent_s *)udir;
|
||||
return resp->ret;
|
||||
}
|
||||
|
||||
@@ -1165,6 +1178,7 @@ static int userfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
static int userfs_closedir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct userfs_dir_s *udir;
|
||||
FAR struct userfs_state_s *priv;
|
||||
FAR struct userfs_closedir_request_s *req;
|
||||
FAR struct userfs_closedir_response_s *resp;
|
||||
@@ -1175,6 +1189,7 @@ static int userfs_closedir(FAR struct inode *mountpt,
|
||||
DEBUGASSERT(mountpt != NULL &&
|
||||
mountpt->i_private != NULL);
|
||||
priv = mountpt->i_private;
|
||||
udir = (FAR struct userfs_dir_s *)dir;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
@@ -1188,7 +1203,7 @@ static int userfs_closedir(FAR struct inode *mountpt,
|
||||
|
||||
req = (FAR struct userfs_closedir_request_s *)priv->iobuffer;
|
||||
req->req = USERFS_REQ_CLOSEDIR;
|
||||
req->dir = dir->u.userfs.fs_dir;
|
||||
req->dir = udir->dir;
|
||||
|
||||
nsent = psock_sendto(&priv->psock, priv->iobuffer,
|
||||
sizeof(struct userfs_closedir_request_s), 0,
|
||||
@@ -1226,6 +1241,7 @@ static int userfs_closedir(FAR struct inode *mountpt,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
kmm_free(udir);
|
||||
return resp->ret;
|
||||
}
|
||||
|
||||
@@ -1240,6 +1256,7 @@ static int userfs_readdir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct userfs_dir_s *udir;
|
||||
FAR struct userfs_state_s *priv;
|
||||
FAR struct userfs_readdir_request_s *req;
|
||||
FAR struct userfs_readdir_response_s *resp;
|
||||
@@ -1250,6 +1267,7 @@ static int userfs_readdir(FAR struct inode *mountpt,
|
||||
DEBUGASSERT(mountpt != NULL &&
|
||||
mountpt->i_private != NULL);
|
||||
priv = mountpt->i_private;
|
||||
udir = (FAR struct userfs_dir_s *)dir;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
@@ -1263,7 +1281,7 @@ static int userfs_readdir(FAR struct inode *mountpt,
|
||||
|
||||
req = (FAR struct userfs_readdir_request_s *)priv->iobuffer;
|
||||
req->req = USERFS_REQ_READDIR;
|
||||
req->dir = dir->u.userfs.fs_dir;
|
||||
req->dir = udir->dir;
|
||||
|
||||
nsent = psock_sendto(&priv->psock, priv->iobuffer,
|
||||
sizeof(struct userfs_readdir_request_s), 0,
|
||||
@@ -1318,6 +1336,7 @@ static int userfs_readdir(FAR struct inode *mountpt,
|
||||
static int userfs_rewinddir(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct userfs_dir_s *udir;
|
||||
FAR struct userfs_state_s *priv;
|
||||
FAR struct userfs_rewinddir_request_s *req;
|
||||
FAR struct userfs_rewinddir_response_s *resp;
|
||||
@@ -1328,6 +1347,7 @@ static int userfs_rewinddir(FAR struct inode *mountpt,
|
||||
DEBUGASSERT(mountpt != NULL &&
|
||||
mountpt->i_private != NULL);
|
||||
priv = mountpt->i_private;
|
||||
udir = (FAR struct userfs_dir_s *)dir;
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
@@ -1341,7 +1361,7 @@ static int userfs_rewinddir(FAR struct inode *mountpt,
|
||||
|
||||
req = (FAR struct userfs_rewinddir_request_s *)priv->iobuffer;
|
||||
req->req = USERFS_REQ_REWINDDIR;
|
||||
req->dir = dir->u.userfs.fs_dir;
|
||||
req->dir = udir->dir;
|
||||
|
||||
nsent = psock_sendto(&priv->psock, priv->iobuffer,
|
||||
sizeof(struct userfs_rewinddir_request_s), 0,
|
||||
|
||||
+74
-49
@@ -29,10 +29,24 @@
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* For the root pseudo-file system, we need retain only the 'next' inode
|
||||
* need for the next readdir() operation. We hold a reference on this
|
||||
* inode so we know that it will persist until closedir is called.
|
||||
*/
|
||||
|
||||
struct fs_pseudodir_s
|
||||
{
|
||||
struct fs_dirent_s dir;
|
||||
FAR struct inode *next;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions Prototypes
|
||||
****************************************************************************/
|
||||
@@ -92,8 +106,10 @@ static struct inode g_dir_inode =
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
static int open_mountpoint(FAR struct inode *inode, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* The inode itself as the 'root' of mounted volume. The actually
|
||||
* directory is at relpath into the mounted filesystem.
|
||||
*
|
||||
@@ -106,9 +122,13 @@ static int open_mountpoint(FAR struct inode *inode, FAR const char *relpath,
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
dir->fd_root = inode;
|
||||
ret = inode->u.i_mops->opendir(inode, relpath, dir);
|
||||
if (ret >= 0)
|
||||
{
|
||||
(*dir)->fd_root = inode;
|
||||
}
|
||||
|
||||
return inode->u.i_mops->opendir(inode, relpath, dir);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -124,16 +144,26 @@ static int open_mountpoint(FAR struct inode *inode, FAR const char *relpath,
|
||||
* dir -- the dirent structure to be initialized
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* On success, 0 is returned; Otherwise, a negative errno is returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void open_pseudodir(FAR struct inode *inode,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
static int open_pseudodir(FAR struct inode *inode,
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
dir->fd_root = inode; /* Save the inode where we start */
|
||||
dir->u.pseudo.fd_next = inode->i_child; /* The next node for readdir */
|
||||
FAR struct fs_pseudodir_s *pdir;
|
||||
|
||||
pdir = kmm_zalloc(sizeof(*pdir));
|
||||
if (pdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*dir = &pdir->dir;
|
||||
pdir->dir.fd_root = inode; /* Save the inode where we start */
|
||||
pdir->next = inode->i_child; /* This next node for readdir */
|
||||
inode_addref(inode->i_child);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -142,7 +172,7 @@ static void open_pseudodir(FAR struct inode *inode,
|
||||
|
||||
static off_t seek_pseudodir(FAR struct file *filep, off_t offset)
|
||||
{
|
||||
FAR struct fs_dirent_s *dir = filep->f_priv;
|
||||
FAR struct fs_pseudodir_s *pdir = filep->f_priv;
|
||||
FAR struct inode *curr;
|
||||
FAR struct inode *prev;
|
||||
off_t pos;
|
||||
@@ -156,12 +186,12 @@ static off_t seek_pseudodir(FAR struct file *filep, off_t offset)
|
||||
if (offset < filep->f_pos)
|
||||
{
|
||||
pos = 0;
|
||||
curr = dir->fd_root->i_child;
|
||||
curr = pdir->dir.fd_root->i_child;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = filep->f_pos;
|
||||
curr = dir->u.pseudo.fd_next;
|
||||
curr = pdir->next;
|
||||
}
|
||||
|
||||
/* Traverse the peer list starting at the 'root' of the
|
||||
@@ -176,11 +206,11 @@ static off_t seek_pseudodir(FAR struct file *filep, off_t offset)
|
||||
|
||||
/* Now get the inode to vist next time that readdir() is called */
|
||||
|
||||
prev = dir->u.pseudo.fd_next;
|
||||
prev = pdir->next;
|
||||
|
||||
/* The next node to visit (might be null) */
|
||||
|
||||
dir->u.pseudo.fd_next = curr;
|
||||
pdir->next = curr;
|
||||
if (curr != NULL)
|
||||
{
|
||||
/* Increment the reference count on this next node */
|
||||
@@ -263,11 +293,12 @@ static off_t seek_mountptdir(FAR struct file *filep, off_t offset)
|
||||
static int read_pseudodir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry)
|
||||
{
|
||||
FAR struct fs_pseudodir_s *pdir = (FAR struct fs_pseudodir_s *)dir;
|
||||
FAR struct inode *prev;
|
||||
|
||||
/* Check if we are at the end of the list */
|
||||
|
||||
if (dir->u.pseudo.fd_next == NULL)
|
||||
if (pdir->next == NULL)
|
||||
{
|
||||
/* End of file and error conditions are not distinguishable with
|
||||
* readdir. Here we return -ENOENT to signal the end of the directory.
|
||||
@@ -278,49 +309,48 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir,
|
||||
|
||||
/* Copy the inode name into the dirent structure */
|
||||
|
||||
strlcpy(entry->d_name, dir->u.pseudo.fd_next->i_name,
|
||||
sizeof(entry->d_name));
|
||||
strlcpy(entry->d_name, pdir->next->i_name, sizeof(entry->d_name));
|
||||
|
||||
/* If the node has file operations, we will say that it is a file. */
|
||||
|
||||
entry->d_type = DTYPE_UNKNOWN;
|
||||
if (dir->u.pseudo.fd_next->u.i_ops != NULL)
|
||||
if (pdir->next->u.i_ops != NULL)
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
if (INODE_IS_BLOCK(dir->u.pseudo.fd_next))
|
||||
if (INODE_IS_BLOCK(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_BLK;
|
||||
}
|
||||
else if (INODE_IS_MTD(dir->u.pseudo.fd_next))
|
||||
else if (INODE_IS_MTD(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_MTD;
|
||||
}
|
||||
else if (INODE_IS_MOUNTPT(dir->u.pseudo.fd_next))
|
||||
else if (INODE_IS_MOUNTPT(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_DIRECTORY;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||
if (INODE_IS_SOFTLINK(dir->u.pseudo.fd_next))
|
||||
if (INODE_IS_SOFTLINK(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_LINK;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (INODE_IS_DRIVER(dir->u.pseudo.fd_next))
|
||||
if (INODE_IS_DRIVER(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_CHR;
|
||||
}
|
||||
else if (INODE_IS_NAMEDSEM(dir->u.pseudo.fd_next))
|
||||
else if (INODE_IS_NAMEDSEM(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_SEM;
|
||||
}
|
||||
else if (INODE_IS_MQUEUE(dir->u.pseudo.fd_next))
|
||||
else if (INODE_IS_MQUEUE(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_MQ;
|
||||
}
|
||||
else if (INODE_IS_SHM(dir->u.pseudo.fd_next))
|
||||
else if (INODE_IS_SHM(pdir->next))
|
||||
{
|
||||
entry->d_type = DTYPE_SHM;
|
||||
}
|
||||
@@ -331,8 +361,8 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir,
|
||||
* be both!
|
||||
*/
|
||||
|
||||
if (dir->u.pseudo.fd_next->i_child != NULL ||
|
||||
dir->u.pseudo.fd_next->u.i_ops == NULL)
|
||||
if (pdir->next->i_child != NULL ||
|
||||
pdir->next->u.i_ops == NULL)
|
||||
{
|
||||
entry->d_type = DTYPE_DIRECTORY;
|
||||
}
|
||||
@@ -341,14 +371,14 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir,
|
||||
|
||||
inode_semtake();
|
||||
|
||||
prev = dir->u.pseudo.fd_next;
|
||||
dir->u.pseudo.fd_next = prev->i_peer; /* The next node to visit */
|
||||
prev = pdir->next;
|
||||
pdir->next = prev->i_peer; /* The next node to visit */
|
||||
|
||||
if (dir->u.pseudo.fd_next != NULL)
|
||||
if (pdir->next != NULL)
|
||||
{
|
||||
/* Increment the reference count on this next node */
|
||||
|
||||
dir->u.pseudo.fd_next->i_crefs++;
|
||||
pdir->next->i_crefs++;
|
||||
}
|
||||
|
||||
inode_semgive();
|
||||
@@ -391,13 +421,15 @@ static int dir_close(FAR struct file *filep)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FAR struct fs_pseudodir_s *pdir = filep->f_priv;
|
||||
|
||||
/* The node is part of the root pseudo file system, release
|
||||
* our contained reference to the 'next' inode.
|
||||
*/
|
||||
|
||||
if (dir->u.pseudo.fd_next != NULL)
|
||||
if (pdir->next != NULL)
|
||||
{
|
||||
inode_release(dir->u.pseudo.fd_next);
|
||||
inode_release(pdir->next);
|
||||
}
|
||||
|
||||
/* Then release the container */
|
||||
@@ -517,13 +549,7 @@ int dir_allocate(FAR struct file *filep, FAR const char *relpath)
|
||||
{
|
||||
FAR struct fs_dirent_s *dir;
|
||||
FAR struct inode *inode = filep->f_inode;
|
||||
int ret = 0;
|
||||
|
||||
dir = kmm_zalloc(sizeof(struct fs_dirent_s));
|
||||
if (dir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
int ret;
|
||||
|
||||
/* Is this a node in the pseudo filesystem? Or a mountpoint? */
|
||||
|
||||
@@ -532,25 +558,24 @@ int dir_allocate(FAR struct file *filep, FAR const char *relpath)
|
||||
{
|
||||
/* Open the directory at the relative path */
|
||||
|
||||
ret = open_mountpoint(inode, relpath, dir);
|
||||
ret = open_mountpoint(inode, relpath, &dir);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_direntry;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
open_pseudodir(inode, dir);
|
||||
ret = open_pseudodir(inode, &dir);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
filep->f_inode = &g_dir_inode;
|
||||
filep->f_priv = dir;
|
||||
inode_addref(&g_dir_inode);
|
||||
|
||||
return ret;
|
||||
|
||||
errout_with_direntry:
|
||||
kmm_free(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,348 +0,0 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/fs/dirent.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_FS_DIRENT_H
|
||||
#define __INCLUDE_NUTTX_FS_DIRENT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NFS
|
||||
# define DIRENT_NFS_MAXHANDLE 64 /* Maximum length of an NFSv3 file handle */
|
||||
# define DIRENT_NFS_VERFLEN 8 /* Length of the copy verifier */
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* The internal representation of type DIR is just a container for an inode
|
||||
* reference, a position, a dirent structure, and file-system-specific
|
||||
* information.
|
||||
*
|
||||
* For the root pseudo-file system, we need retain only the 'next' inode
|
||||
* need for the next readdir() operation. We hold a reference on this
|
||||
* inode so we know that it will persist until closedir is called.
|
||||
*/
|
||||
|
||||
struct fs_pseudodir_s
|
||||
{
|
||||
struct inode *fd_next; /* The inode for the next call to readdir() */
|
||||
};
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
#ifdef CONFIG_FS_FAT
|
||||
/* For fat, we need to return the start cluster, current cluster, current
|
||||
* sector and current directory index.
|
||||
*/
|
||||
|
||||
struct fs_fatdir_s
|
||||
{
|
||||
off_t fd_startcluster; /* Start cluster number of the directory */
|
||||
off_t fd_currcluster; /* Current cluster number being read */
|
||||
off_t fd_currsector; /* Current sector being read */
|
||||
unsigned int fd_index; /* Current index of the directory entry to read */
|
||||
};
|
||||
#endif /* CONFIG_FS_FAT */
|
||||
|
||||
#ifdef CONFIG_FS_ROMFS
|
||||
#ifdef CONFIG_FS_ROMFS_CACHE_NODE
|
||||
|
||||
/* This structure represents one entry node in the romfs file system */
|
||||
|
||||
struct romfs_nodeinfo_s
|
||||
{
|
||||
FAR struct romfs_nodeinfo_s **rn_child; /* The node array for link to lower level */
|
||||
uint16_t rn_count; /* The count of node in rn_child level */
|
||||
uint32_t rn_offset; /* The offset to real file header of the current entry */
|
||||
uint32_t rn_next; /* The offset of the next file header+flags */
|
||||
uint32_t rn_size; /* The size to the entry (if file) */
|
||||
uint8_t rn_namesize; /* The length of name of the entry */
|
||||
char rn_name[1]; /* The name to the entry */
|
||||
};
|
||||
|
||||
/* For ROMFS, we need to return the node to the current and start node
|
||||
* of the directory entry being read
|
||||
*/
|
||||
|
||||
struct fs_romfsdir_s
|
||||
{
|
||||
FAR struct romfs_nodeinfo_s **fr_firstnode; /* The address of first node in the directory */
|
||||
FAR struct romfs_nodeinfo_s **fr_currnode; /* The address of current node into the directory */
|
||||
};
|
||||
#else
|
||||
|
||||
/* For ROMFS, we need to return the offset to the current and start positions
|
||||
* of the directory entry being read
|
||||
*/
|
||||
|
||||
struct fs_romfsdir_s
|
||||
{
|
||||
off_t fr_firstoffset; /* Offset to the first entry in the directory */
|
||||
off_t fr_curroffset; /* Current offset into the directory contents */
|
||||
};
|
||||
#endif
|
||||
#endif /* CONFIG_FS_ROMFS */
|
||||
|
||||
#ifdef CONFIG_FS_CROMFS
|
||||
/* For CROMFS, we need to return the next compressed node to be examined. */
|
||||
|
||||
struct fs_cromfsdir_s
|
||||
{
|
||||
uint32_t cr_firstoffset; /* Offset to the first entry in the directory */
|
||||
uint32_t cr_curroffset; /* Current offset into the directory contents */
|
||||
};
|
||||
#endif /* CONFIG_FS_CROMFS */
|
||||
|
||||
#ifdef CONFIG_FS_TMPFS
|
||||
/* For TMPFS, we need the directory object and an index into the directory
|
||||
* entries.
|
||||
*/
|
||||
|
||||
struct tmpfs_directory_s; /* Forward reference */
|
||||
struct fs_tmpfsdir_s
|
||||
{
|
||||
FAR struct tmpfs_directory_s *tf_tdo; /* Directory being enumerated */
|
||||
unsigned int tf_index; /* Directory index */
|
||||
};
|
||||
#endif /* CONFIG_FS_TMPFS */
|
||||
|
||||
#ifdef CONFIG_FS_BINFS
|
||||
/* The apps/ pseudo bin/ directory. The state value is simply an index */
|
||||
|
||||
struct fs_binfsdir_s
|
||||
{
|
||||
unsigned int fb_index; /* Index to the next named entry point */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_NXFFS
|
||||
/* NXFFS is the tiny NuttX wear-leveling FLASH file system.
|
||||
* The state value is the offset in FLASH memory to the next inode entry.
|
||||
*/
|
||||
|
||||
struct fs_nxffsdir_s
|
||||
{
|
||||
off_t nx_offset; /* Offset to the next inode */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NFS
|
||||
/* The NFS client file system */
|
||||
|
||||
struct nfsdir_s
|
||||
{
|
||||
uint8_t nfs_fhsize; /* Length of the file handle */
|
||||
uint8_t nfs_fhandle[DIRENT_NFS_MAXHANDLE]; /* File handle (max size allocated) */
|
||||
uint8_t nfs_verifier[DIRENT_NFS_VERFLEN]; /* Cookie verifier */
|
||||
uint32_t nfs_cookie[2]; /* Cookie */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_SMARTFS
|
||||
/* SMARTFS is the Sector Mapped Allocation for Really Tiny FLASH filesystem.
|
||||
* it is designed to use small sectors on small serial FLASH devices, using
|
||||
* minimal RAM footprint.
|
||||
*/
|
||||
|
||||
struct fs_smartfsdir_s
|
||||
{
|
||||
uint16_t fs_firstsector; /* First sector of directory list */
|
||||
uint16_t fs_currsector; /* Current sector of directory list */
|
||||
uint16_t fs_curroffset; /* Current offset within current sector */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_SPIFFS
|
||||
|
||||
/* SPIFFS is an SPI-oriented FLASH file system
|
||||
* originally by Peter Andersson
|
||||
*/
|
||||
|
||||
struct fs_spiffsdir_s
|
||||
{
|
||||
int16_t block; /* Current block */
|
||||
int entry; /* Current entry */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_UNIONFS
|
||||
/* The Union File System can be used to merge to different mountpoints so
|
||||
* that they appear as a single merged directory.
|
||||
*/
|
||||
|
||||
struct fs_dirent_s; /* Forward reference */
|
||||
struct fs_unionfsdir_s
|
||||
{
|
||||
uint8_t fu_ndx; /* Index of file system being enumerated */
|
||||
bool fu_eod; /* True: At end of directory */
|
||||
bool fu_prefix[2]; /* True: Fake directory in prefix */
|
||||
FAR char *fu_relpath; /* Path being enumerated */
|
||||
FAR struct fs_dirent_s *fu_lower[2]; /* dirent struct used by contained file system */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_USERFS
|
||||
/* The UserFS uses an opaque representation since the actual userspace
|
||||
* representation of the directory state structure is unknowable.
|
||||
*/
|
||||
|
||||
struct fs_userfsdir_s
|
||||
{
|
||||
FAR void *fs_dir; /* Opaque pointer to UserFS DIR */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_HOSTFS
|
||||
/* HOSTFS provides mapping to directories on the host machine in the
|
||||
* sim environment.
|
||||
*/
|
||||
|
||||
struct fs_hostfsdir_s
|
||||
{
|
||||
FAR void *fs_dir; /* Opaque pointer to host DIR */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_RPMSGFS
|
||||
/* RPMSGFS provides mapping to directories on the host machine in the
|
||||
* sim environment.
|
||||
*/
|
||||
|
||||
struct fs_rpmsgfsdir_s
|
||||
{
|
||||
FAR void *fs_dir; /* Opaque pointer to remote DIR */
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DISABLE_MOUNTPOINT */
|
||||
|
||||
struct fs_dirent_s
|
||||
{
|
||||
/* This is the node that was opened by opendir. The type of the inode
|
||||
* determines the way that the readdir() operations are performed. For the
|
||||
* pseudo root pseudo-file system, it is also used to support rewind.
|
||||
*
|
||||
* We hold a reference on this inode so we know that it will persist until
|
||||
* closedir() is called (although inodes linked to this inode may change).
|
||||
*/
|
||||
|
||||
struct inode *fd_root;
|
||||
|
||||
/* Retained control information depends on the type of file system that
|
||||
* provides the mountpoint. Ideally this information should
|
||||
* be hidden behind an opaque, file-system-dependent void *, but we put
|
||||
* the private definitions in line here for now to reduce allocations.
|
||||
*/
|
||||
|
||||
union
|
||||
{
|
||||
/* Private data used by the built-in pseudo-file system */
|
||||
|
||||
struct fs_pseudodir_s pseudo;
|
||||
|
||||
/* Private data used by other file systems */
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
#ifdef CONFIG_FS_FAT
|
||||
struct fs_fatdir_s fat;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_ROMFS
|
||||
struct fs_romfsdir_s romfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_CROMFS
|
||||
struct fs_cromfsdir_s cromfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_TMPFS
|
||||
struct fs_tmpfsdir_s tmpfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_BINFS
|
||||
struct fs_binfsdir_s binfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_PROCFS
|
||||
FAR void *procfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_NXFFS
|
||||
struct fs_nxffsdir_s nxffs;
|
||||
#endif
|
||||
#ifdef CONFIG_NFS
|
||||
struct nfsdir_s nfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_SMARTFS
|
||||
struct fs_smartfsdir_s smartfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_SPIFFS
|
||||
struct fs_spiffsdir_s spiffs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_LITTLEFS
|
||||
FAR void *littlefs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_UNIONFS
|
||||
struct fs_unionfsdir_s unionfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_USERFS
|
||||
struct fs_userfsdir_s userfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_HOSTFS
|
||||
struct fs_hostfsdir_s hostfs;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_RPMSGFS
|
||||
struct fs_rpmsgfsdir_s rpmsgfs;
|
||||
#endif
|
||||
#endif /* !CONFIG_DISABLE_MOUNTPOINT */
|
||||
} u;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_FS_DIRENT_H */
|
||||
+18
-2
@@ -174,9 +174,25 @@ struct inode;
|
||||
struct stat;
|
||||
struct statfs;
|
||||
struct pollfd;
|
||||
struct fs_dirent_s;
|
||||
struct mtd_dev_s;
|
||||
|
||||
/* The internal representation of type DIR is just a container for an inode
|
||||
* reference, and the path of directory.
|
||||
*/
|
||||
|
||||
struct fs_dirent_s
|
||||
{
|
||||
/* This is the node that was opened by opendir. The type of the inode
|
||||
* determines the way that the readdir() operations are performed. For the
|
||||
* pseudo root pseudo-file system, it is also used to support rewind.
|
||||
*
|
||||
* We hold a reference on this inode so we know that it will persist until
|
||||
* closedir() is called (although inodes linked to this inode may change).
|
||||
*/
|
||||
|
||||
FAR struct inode *fd_root;
|
||||
};
|
||||
|
||||
/* This structure is provided by devices when they are registered with the
|
||||
* system. It is used to call back to perform device specific operations.
|
||||
*/
|
||||
@@ -302,7 +318,7 @@ struct mountpt_operations
|
||||
/* Directory operations */
|
||||
|
||||
int (*opendir)(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
int (*closedir)(FAR struct inode *mountpt,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
int (*readdir)(FAR struct inode *mountpt,
|
||||
|
||||
@@ -73,7 +73,7 @@ struct procfs_operations
|
||||
/* Directory operations */
|
||||
|
||||
int (*opendir)(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
int (*closedir)(FAR struct fs_dirent_s *dir);
|
||||
int (*readdir)(FAR struct fs_dirent_s *dir, FAR struct dirent *entry);
|
||||
int (*rewinddir)(FAR struct fs_dirent_s *dir);
|
||||
@@ -119,6 +119,7 @@ struct procfs_file_s
|
||||
|
||||
struct procfs_dir_priv_s
|
||||
{
|
||||
struct fs_dirent_s dir; /* VFS directory structure */
|
||||
uint8_t level; /* Directory level. Currently 0 or 1 */
|
||||
uint16_t index; /* Index to the next directory entry */
|
||||
uint16_t nentries; /* Number of directory entries */
|
||||
|
||||
+10
-20
@@ -40,7 +40,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#include "netdev/netdev.h"
|
||||
@@ -91,7 +90,7 @@ static int netprocfs_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
|
||||
static int netprocfs_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int netprocfs_closedir(FAR struct fs_dirent_s *dir);
|
||||
static int netprocfs_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -380,14 +379,14 @@ static int netprocfs_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
****************************************************************************/
|
||||
|
||||
static int netprocfs_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct netprocfs_level1_s *level1;
|
||||
int ndevs;
|
||||
int ret;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath && dir && !dir->u.procfs);
|
||||
DEBUGASSERT(relpath && dir);
|
||||
|
||||
/* "net" and "net/route" are the only values of relpath that are
|
||||
* directories.
|
||||
@@ -449,7 +448,7 @@ static int netprocfs_opendir(FAR const char *relpath,
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
dir->u.procfs = (FAR void *)level1;
|
||||
*dir = (FAR struct fs_dirent_s *)level1;
|
||||
return OK;
|
||||
|
||||
errout_with_alloc:
|
||||
@@ -466,17 +465,8 @@ errout_with_alloc:
|
||||
|
||||
static int netprocfs_closedir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct netprocfs_level1_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -495,8 +485,8 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir,
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
level1 = (FAR struct netprocfs_level1_s *)dir;
|
||||
DEBUGASSERT(level1->base.level > 0);
|
||||
|
||||
/* Are we searching this directory? Or is it just an intermediate on the
|
||||
@@ -630,8 +620,8 @@ static int netprocfs_rewinddir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct netprocfs_level1_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
priv = (FAR struct netprocfs_level1_s *)dir;
|
||||
|
||||
priv->base.index = 0;
|
||||
return OK;
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "route/route.h"
|
||||
|
||||
@@ -159,7 +158,7 @@ static int route_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
|
||||
static int route_opendir(const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
FAR struct fs_dirent_s **dir);
|
||||
static int route_closedir(FAR struct fs_dirent_s *dir);
|
||||
static int route_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR struct dirent *entry);
|
||||
@@ -610,12 +609,12 @@ static int route_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
****************************************************************************/
|
||||
|
||||
static int route_opendir(FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir)
|
||||
FAR struct fs_dirent_s **dir)
|
||||
{
|
||||
FAR struct route_dir_s *level2;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath && dir && !dir->u.procfs);
|
||||
DEBUGASSERT(relpath);
|
||||
|
||||
/* Check the relative path */
|
||||
|
||||
@@ -652,7 +651,7 @@ static int route_opendir(FAR const char *relpath,
|
||||
level2->base.nentries = 2;
|
||||
level2->name = "";
|
||||
level2->node = PROC_ROUTE;
|
||||
dir->u.procfs = (FAR void *)level2;
|
||||
*dir = (FAR struct fs_dirent_s *)level2;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -665,17 +664,8 @@ static int route_opendir(FAR const char *relpath,
|
||||
|
||||
static int route_closedir(FAR struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct route_dir_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
|
||||
if (priv != NULL)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
dir->u.procfs = NULL;
|
||||
DEBUGASSERT(dir);
|
||||
kmm_free(dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -693,8 +683,8 @@ static int route_readdir(FAR struct fs_dirent_s *dir,
|
||||
FAR const char *dname;
|
||||
unsigned int index;
|
||||
|
||||
DEBUGASSERT(dir != NULL && dir->u.procfs != NULL);
|
||||
level2 = dir->u.procfs;
|
||||
DEBUGASSERT(dir != NULL);
|
||||
level2 = (FAR struct route_dir_s *)dir;
|
||||
|
||||
/* The index determines which entry to return */
|
||||
|
||||
@@ -746,8 +736,8 @@ static int route_rewinddir(struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR struct route_dir_s *priv;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
priv = dir->u.procfs;
|
||||
DEBUGASSERT(dir);
|
||||
priv = (FAR struct route_dir_s *)dir;
|
||||
|
||||
priv->base.index = 0;
|
||||
return OK;
|
||||
|
||||
Reference in New Issue
Block a user