fs: allocate file/socket dynamically

Change-Id: I8aea63eaf0275f47f21fc8d5482b51ffecd5c906
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong
2021-03-16 20:13:02 +08:00
committed by Xiang Xiao
parent 59eb4fa8d6
commit e96c8b9283
35 changed files with 760 additions and 599 deletions

View File

@@ -69,18 +69,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -84,18 +84,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -68,18 +68,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -86,18 +86,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -79,18 +79,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefssinfo);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -79,17 +79,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n", i, inode->i_crefssinfo);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -84,18 +84,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode != NULL)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefssinfo);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -68,18 +68,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -86,18 +86,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -68,18 +68,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -63,29 +63,30 @@
#ifdef CONFIG_DUMP_ON_EXIT
static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct filelist *filelist;
#ifdef CONFIG_FILE_STREAM
FAR struct file_struct *filep;
#endif
int i;
#endif
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
#if CONFIG_NFILE_DESCRIPTORS > 0
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}
#endif
#ifdef CONFIG_FILE_STREAM
filep = tcb->group->tg_streamlist->sl_head;

View File

@@ -57,7 +57,7 @@
* assumed.
*/
#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0
#if !defined(CONFIG_DEV_CONSOLE)
# undef USE_SERIALDRIVER
# undef USE_EARLYSERIALINIT
# undef CONFIG_DEV_LOWCONSOLE
@@ -115,9 +115,9 @@ typedef void (*up_vector_t)(void);
extern volatile uint64_t *g_current_regs;
/* This is the beginning of heap as provided from up_head.S. This is the first
* address in DRAM after the loaded program+bss+idle stack. The end of the
* heap is CONFIG_RAM_END
/* This is the beginning of heap as provided from up_head.S. This is the
* first address in DRAM after the loaded program+bss+idle stack. The
* end of the heap is CONFIG_RAM_END
*/
extern uint64_t g_idle_topstack;
@@ -128,14 +128,14 @@ extern uint64_t g_idle_topstack;
extern uint64_t g_intstackbase;
#endif
/* These 'addresses' of these values are setup by the linker script. They are
* not actual uint32_t storage locations! They are only used meaningfully in the
* following way:
/* These 'addresses' of these values are setup by the linker script. They
* are not actual uint32_t storage locations! They are only used
* meaningfully in the following way:
*
* - The linker script defines, for example, the symbol_sdata.
* - The declareion extern uint32_t _sdata; makes C happy. C will believe
* that the value _sdata is the address of a uint32_t variable _data (it is
* not!).
* that the value _sdata is the address of a uint32_t variable _data
* (it is not!).
* - We can recoved the linker value then by simply taking the address of
* of _data. like: uint32_t *pdata = &_sdata;
*/
@@ -202,13 +202,8 @@ void up_addregion(void);
/* Defined in xyz_serial.c */
#if CONFIG_NFILE_DESCRIPTORS > 0
void up_earlyserialinit(void);
void up_serialinit(void);
#else
# define up_earlyserialinit()
# define up_serialinit()
#endif
/* Defined in xyz_watchdog.c */

View File

@@ -85,18 +85,23 @@ static void _xtensa_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -68,18 +68,23 @@ static void _z16_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -70,18 +70,23 @@ static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg)
FAR struct file_struct *filep;
#endif
int i;
int j;
sinfo(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
filelist = tcb->group->tg_filelist;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < filelist->fl_rows; i++)
{
struct inode *inode = filelist->fl_files[i].f_inode;
if (inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
sinfo(" fd=%d refcount=%d\n",
i, inode->i_crefs);
struct inode *inode = filelist->fl_files[i][j].f_inode;
if (inode)
{
sinfo(" fd=%d refcount=%d\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j,
inode->i_crefs);
}
}
}

View File

@@ -62,10 +62,6 @@
# error "Mountpoint support is disabled"
#endif
#if CONFIG_NFILE_DESCRIPTORS < 4
# error "Not enough file descriptors"
#endif
#ifndef CONFIG_FS_ROMFS
# error "ROMFS support not enabled"
#endif

View File

@@ -44,8 +44,10 @@
struct hostfs_rpmsg_server_s
{
struct rpmsg_endpoint ept;
struct file files[CONFIG_NFILE_DESCRIPTORS];
void *dirs[CONFIG_NFILE_DESCRIPTORS];
FAR struct file **files;
FAR void **dirs;
int file_rows;
int dir_nums;
sem_t sem;
};
@@ -154,33 +156,181 @@ static const rpmsg_ept_cb g_hostfs_rpmsg_handler[] =
* Private Functions
****************************************************************************/
static int hostfs_rpmsg_attach_file(FAR struct hostfs_rpmsg_server_s *priv,
FAR struct file *filep)
{
FAR struct file **tmp;
int ret;
int i;
int j;
nxsem_wait(&priv->sem);
for (i = 0; i < priv->file_rows; i++)
{
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
if (priv->files[i][j].f_inode == NULL)
{
memcpy(&priv->files[i][j], filep, sizeof(*filep));
ret = i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j;
goto out;
}
}
}
tmp = kmm_realloc(priv->files, sizeof(FAR struct file *) * (i + 1));
DEBUGASSERT(tmp);
if (tmp == NULL)
{
ret = -ENFILE;
goto out;
}
tmp[i] = kmm_zalloc(sizeof(struct file) *
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK);
DEBUGASSERT(tmp[i]);
if (tmp[i] == NULL)
{
kmm_free(tmp);
ret = -ENFILE;
goto out;
}
priv->files = tmp;
priv->file_rows++;
memcpy(&priv->files[i][0], filep, sizeof(*filep));
ret = i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
out:
nxsem_post(&priv->sem);
return ret;
}
static int hostfs_rpmsg_detach_file(FAR struct hostfs_rpmsg_server_s *priv,
int fd, FAR struct file *filep)
{
struct file *tfilep;
if (fd < 0 || fd >= priv->file_rows * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK)
{
return -EBADF;
}
nxsem_wait(&priv->sem);
tfilep = &priv->files[fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK];
memcpy(filep, tfilep, sizeof(*filep));
memset(tfilep, 0, sizeof(*tfilep));
nxsem_post(&priv->sem);
return 0;
}
static FAR struct file *hostfs_rpmsg_get_file(
FAR struct hostfs_rpmsg_server_s *priv,
int fd)
{
FAR struct file *filep;
if (fd < 0 || fd >= priv->file_rows * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK)
{
return NULL;
}
nxsem_wait(&priv->sem);
filep = &priv->files[fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK];
nxsem_post(&priv->sem);
return filep;
}
static int hostfs_rpmsg_attach_dir(FAR struct hostfs_rpmsg_server_s *priv,
FAR void *dir)
{
FAR void **tmp;
int i;
nxsem_wait(&priv->sem);
for (i = 1; i < priv->dir_nums; i++)
{
if (priv->dirs[i] == NULL)
{
priv->dirs[i] = dir;
nxsem_post(&priv->sem);
return i;
}
}
tmp = kmm_realloc(priv->dirs, sizeof(FAR void *) *
(priv->dir_nums + CONFIG_NFILE_DESCRIPTORS_PER_BLOCK));
DEBUGASSERT(tmp);
if (tmp == NULL)
{
nxsem_post(&priv->sem);
return -ENOMEM;
}
priv->dirs = tmp;
priv->dir_nums += CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
priv->dirs[i] = dir;
nxsem_post(&priv->sem);
return i;
}
static void *hostfs_rpmsg_detach_dir(FAR struct hostfs_rpmsg_server_s *priv,
int fd)
{
FAR void *dir = NULL;
if (fd >= 1 && fd < priv->dir_nums)
{
nxsem_wait(&priv->sem);
dir = priv->dirs[fd];
priv->dirs[fd] = NULL;
nxsem_post(&priv->sem);
}
return dir;
}
static FAR void *hostfs_rpmsg_get_dir(
FAR struct hostfs_rpmsg_server_s *priv,
int fd)
{
FAR void *dir = NULL;
if (fd >= 1 && fd < priv->dir_nums)
{
nxsem_wait(&priv->sem);
dir = priv->dirs[fd];
nxsem_post(&priv->sem);
}
return dir;
}
static int hostfs_rpmsg_open_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_open_s *msg = data;
int i;
int ret = -ENOENT;
struct file file;
int ret;
nxsem_wait(&priv->sem);
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
ret = file_open(&file, msg->pathname, msg->flags, msg->mode);
if (ret >= 0)
{
if (!priv->files[i].f_inode)
ret = hostfs_rpmsg_attach_file(priv_, &file);
if (ret < 0)
{
ret = file_open(&priv->files[i], msg->pathname, msg->flags,
msg->mode);
if (ret >= 0)
{
ret = i;
}
break;
file_close(&file);
}
}
nxsem_post(&priv->sem);
msg->header.result = ret;
return rpmsg_send(ept, msg, sizeof(*msg));
}
@@ -189,15 +339,14 @@ static int hostfs_rpmsg_close_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_close_s *msg = data;
int ret = -ENOENT;
struct file file;
int ret;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
ret = hostfs_rpmsg_detach_file(priv_, msg->fd, &file);
if (ret >= 0)
{
nxsem_wait(&priv->sem);
ret = file_close(&priv->files[msg->fd]);
nxsem_post(&priv->sem);
ret = file_close(&file);
}
msg->header.result = ret;
@@ -208,9 +357,9 @@ static int hostfs_rpmsg_read_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_read_s *msg = data;
FAR struct hostfs_rpmsg_read_s *rsp;
FAR struct file *filep;
int ret = -ENOENT;
uint32_t space;
@@ -228,9 +377,10 @@ static int hostfs_rpmsg_read_handler(FAR struct rpmsg_endpoint *ept,
space = msg->count;
}
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_read(&priv->files[msg->fd], rsp->buf, space);
ret = file_read(filep, rsp->buf, space);
}
rsp->header.result = ret;
@@ -241,13 +391,14 @@ static int hostfs_rpmsg_write_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_write_s *msg = data;
FAR struct file *filep;
int ret = -ENOENT;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_write(&priv->files[msg->fd], msg->buf, msg->count);
ret = file_write(filep, msg->buf, msg->count);
}
msg->header.result = ret;
@@ -258,13 +409,14 @@ static int hostfs_rpmsg_lseek_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_lseek_s *msg = data;
FAR struct file *filep;
int ret = -ENOENT;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_seek(&priv->files[msg->fd], msg->offset, msg->whence);
ret = file_seek(filep, msg->offset, msg->whence);
}
msg->header.result = ret;
@@ -275,13 +427,14 @@ static int hostfs_rpmsg_ioctl_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_ioctl_s *msg = data;
FAR struct file *filep;
int ret = -ENOENT;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_ioctl(&priv->files[msg->fd], msg->request, msg->arg);
ret = file_ioctl(filep, msg->request, msg->arg);
}
msg->header.result = ret;
@@ -292,13 +445,14 @@ static int hostfs_rpmsg_sync_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_sync_s *msg = data;
FAR struct file *filep;
int ret = -ENOENT;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_fsync(&priv->files[msg->fd]);
ret = file_fsync(filep);
}
msg->header.result = ret;
@@ -309,29 +463,23 @@ static int hostfs_rpmsg_dup_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_dup_s *msg = data;
int i;
FAR struct file *filep;
struct file newfile;
int ret = -ENOENT;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
nxsem_wait(&priv->sem);
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
ret = file_dup2(filep, &newfile);
if (ret >= 0)
{
if (!priv->files[i].f_inode)
ret = hostfs_rpmsg_attach_file(priv_, &newfile);
if (ret < 0)
{
ret = file_dup2(&priv->files[msg->fd], &priv->files[i]);
if (ret >= 0)
{
ret = i;
}
break;
file_close(&newfile);
}
}
nxsem_post(&priv->sem);
}
msg->header.result = ret;
@@ -342,14 +490,15 @@ static int hostfs_rpmsg_fstat_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_fstat_s *msg = data;
FAR struct file *filep;
int ret = -ENOENT;
struct stat buf;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_fstat(&priv->files[msg->fd], &buf);
ret = file_fstat(filep, &buf);
if (ret >= 0)
{
msg->buf = buf;
@@ -364,13 +513,14 @@ static int hostfs_rpmsg_ftruncate_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_ftruncate_s *msg = data;
FAR struct file *filep;
int ret = -ENOENT;
if (msg->fd >= 0 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
filep = hostfs_rpmsg_get_file(priv_, msg->fd);
if (filep != NULL)
{
ret = file_truncate(&priv->files[msg->fd], msg->length);
ret = file_truncate(filep, msg->length);
}
msg->header.result = ret;
@@ -381,28 +531,14 @@ static int hostfs_rpmsg_opendir_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_opendir_s *msg = data;
FAR void *dir;
int i;
int ret = -ENOENT;
dir = opendir(msg->pathname);
if (dir)
{
nxsem_wait(&priv->sem);
for (i = 1; i < CONFIG_NFILE_DESCRIPTORS; i++)
{
if (!priv->dirs[i])
{
priv->dirs[i] = dir;
ret = i;
break;
}
}
nxsem_post(&priv->sem);
ret = hostfs_rpmsg_attach_dir(priv_, dir);
if (ret < 0)
{
closedir(dir);
@@ -417,14 +553,15 @@ static int hostfs_rpmsg_readdir_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_readdir_s *msg = data;
FAR struct dirent *entry;
int ret = -ENOENT;
FAR void *dir;
if (msg->fd >= 1 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
dir = hostfs_rpmsg_get_dir(priv_, msg->fd);
if (dir)
{
entry = readdir(priv->dirs[msg->fd]);
entry = readdir(dir);
if (entry)
{
msg->type = entry->d_type;
@@ -442,13 +579,14 @@ static int hostfs_rpmsg_rewinddir_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_rewinddir_s *msg = data;
int ret = -ENOENT;
FAR void *dir;
if (msg->fd >= 1 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
dir = hostfs_rpmsg_get_dir(priv_, msg->fd);
if (dir)
{
rewinddir(priv->dirs[msg->fd]);
rewinddir(dir);
ret = 0;
}
@@ -460,17 +598,14 @@ static int hostfs_rpmsg_closedir_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv_)
{
FAR struct hostfs_rpmsg_server_s *priv = priv_;
FAR struct hostfs_rpmsg_closedir_s *msg = data;
int ret = -ENOENT;
FAR void *dir;
if (msg->fd >= 1 && msg->fd < CONFIG_NFILE_DESCRIPTORS)
dir = hostfs_rpmsg_detach_dir(priv_, msg->fd);
if (dir)
{
ret = closedir(priv->dirs[msg->fd]);
nxsem_wait(&priv->sem);
priv->dirs[msg->fd] = NULL;
nxsem_post(&priv->sem);
ret = ret ? -get_errno() : 0;
ret = closedir(dir) ? -get_errno() : 0;
}
msg->header.result = ret;
@@ -603,16 +738,22 @@ static void hostfs_rpmsg_ns_unbind(FAR struct rpmsg_endpoint *ept)
{
FAR struct hostfs_rpmsg_server_s *priv = ept->priv;
int i;
int j;
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < priv->file_rows; i++)
{
if (priv->files[i].f_inode)
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
file_close(&priv->files[i]);
if (priv->files[i][j].f_inode)
{
file_close(&priv->files[i][j]);
}
}
kmm_free(priv->files[i]);
}
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
for (i = 0; i < priv->dir_nums; i++)
{
if (priv->dirs[i])
{
@@ -623,6 +764,8 @@ static void hostfs_rpmsg_ns_unbind(FAR struct rpmsg_endpoint *ept)
rpmsg_destroy_ept(&priv->ept);
nxsem_destroy(&priv->sem);
kmm_free(priv->files);
kmm_free(priv->dirs);
kmm_free(priv);
}

View File

@@ -29,6 +29,7 @@
#include <assert.h>
#include <sched.h>
#include <errno.h>
#include <fcntl.h>
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
@@ -56,6 +57,50 @@ static int _files_semtake(FAR struct filelist *list)
#define _files_semgive(list) nxsem_post(&list->fl_sem)
/****************************************************************************
* Name: files_extend
****************************************************************************/
static int files_extend(FAR struct filelist *list, size_t row)
{
FAR struct file **tmp;
int i;
if (row <= list->fl_rows)
{
return 0;
}
tmp = kmm_realloc(list->fl_files, sizeof(FAR struct file *) * row);
DEBUGASSERT(tmp);
if (tmp == NULL)
{
return -ENFILE;
}
i = list->fl_rows;
do
{
tmp[i] = kmm_zalloc(sizeof(struct file) *
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK);
if (tmp[i] == NULL)
{
while (--i >= list->fl_rows)
{
kmm_free(tmp[i]);
}
kmm_free(tmp);
return -ENFILE;
}
}
while (++i < row);
list->fl_files = tmp;
list->fl_rows = row;
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -87,6 +132,7 @@ void files_initlist(FAR struct filelist *list)
void files_releaselist(FAR struct filelist *list)
{
int i;
int j;
DEBUGASSERT(list);
@@ -95,11 +141,18 @@ void files_releaselist(FAR struct filelist *list)
* because there should not be any references in this context.
*/
for (i = CONFIG_NFILE_DESCRIPTORS; i > 0; i--)
for (i = list->fl_rows - 1; i >= 0; i--)
{
file_close(&list->fl_files[i - 1]);
for (j = CONFIG_NFILE_DESCRIPTORS_PER_BLOCK - 1; j >= 0; j--)
{
file_close(&list->fl_files[i][j]);
}
kmm_free(list->fl_files[i]);
}
kmm_free(list->fl_files);
/* Destroy the semaphore */
nxsem_destroy(&list->fl_sem);
@@ -120,6 +173,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos,
FAR struct filelist *list;
int ret;
int i;
int j;
/* Get the file descriptor list. It should not be NULL in this context. */
@@ -134,21 +188,188 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos,
return ret;
}
for (i = minfd; i < CONFIG_NFILE_DESCRIPTORS; i++)
/* Calcuate minfd whether is in list->fl_files.
* if not, allocate a new filechunk.
*/
i = minfd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
if (i >= list->fl_rows)
{
if (!list->fl_files[i].f_inode)
ret = files_extend(list, i + 1);
if (ret < 0)
{
list->fl_files[i].f_oflags = oflags;
list->fl_files[i].f_pos = pos;
list->fl_files[i].f_inode = inode;
list->fl_files[i].f_priv = priv;
_files_semgive(list);
return i;
return ret;
}
}
/* Find free file */
j = minfd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
do
{
do
{
if (!list->fl_files[i][j].f_inode)
{
list->fl_files[i][j].f_oflags = oflags;
list->fl_files[i][j].f_pos = pos;
list->fl_files[i][j].f_inode = inode;
list->fl_files[i][j].f_priv = priv;
_files_semgive(list);
return i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j;
}
}
while (++j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK);
j = 0;
}
while (++i < list->fl_rows);
/* The space of file array isn't enough, allocate a new filechunk */
ret = files_extend(list, i + 1);
if (ret >= 0)
{
list->fl_files[i][0].f_oflags = oflags;
list->fl_files[i][0].f_pos = pos;
list->fl_files[i][0].f_inode = inode;
list->fl_files[i][0].f_priv = priv;
ret = i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
}
_files_semgive(list);
return -EMFILE;
return ret;
}
/****************************************************************************
* Name: files_duplist
*
* Description:
* Duplicate parent task's file descriptors.
*
****************************************************************************/
int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist)
{
int ret;
int i;
int j;
ret = _files_semtake(plist);
if (ret < 0)
{
/* Probably canceled */
return ret;
}
for (i = 0; i < plist->fl_rows; i++)
{
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
FAR struct file *filep;
#ifdef CONFIG_FDCLONE_STDIO
/* Determine how many file descriptors to clone. If
* CONFIG_FDCLONE_DISABLE is set, no file descriptors will be
* cloned. If CONFIG_FDCLONE_STDIO is set, only the first
* three descriptors (stdin, stdout, and stderr) will be
* cloned. Otherwise all file descriptors will be cloned.
*/
if (i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j >= 3)
{
goto out;
}
#endif
filep = &plist->fl_files[i][j];
if (filep->f_inode == NULL || (filep->f_oflags & O_CLOEXEC) != 0)
{
continue;
}
ret = files_extend(clist, i + 1);
if (ret < 0)
{
goto out;
}
/* Yes... duplicate it for the child */
ret = file_dup2(filep, &clist->fl_files[i][j]);
if (ret < 0)
{
goto out;
}
}
}
out:
_files_semgive(plist);
return ret;
}
/****************************************************************************
* Name: fs_getfilep
*
* Description:
* Given a file descriptor, return the corresponding instance of struct
* file.
*
* Input Parameters:
* fd - The file descriptor
* filep - The location to return the struct file instance
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int fs_getfilep(int fd, FAR struct file **filep)
{
FAR struct filelist *list;
int ret;
DEBUGASSERT(filep != NULL);
*filep = (FAR struct file *)NULL;
list = nxsched_get_files();
/* The file list can be NULL under two cases: (1) One is an obscure
* cornercase: When memory management debug output is enabled. Then
* there may be attempts to write to stdout from malloc before the group
* data has been allocated. The other other is (2) if this is a kernel
* thread. Kernel threads have no allocated file descriptors.
*/
if (list == NULL)
{
return -EAGAIN;
}
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * list->fl_rows)
{
return -EBADF;
}
/* The descriptor is in a valid range to file descriptor... Get the
* thread-specific file list.
*/
/* And return the file pointer from the list */
ret = _files_semtake(list);
if (ret >= 0)
{
*filep = &list->fl_files[fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK];
_files_semgive(list);
}
return OK;
}
/****************************************************************************
@@ -174,17 +395,17 @@ int nx_dup2(int fd1, int fd2)
FAR struct filelist *list;
int ret;
if (fd1 < 0 || fd1 >= CONFIG_NFILE_DESCRIPTORS ||
fd2 < 0 || fd2 >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
}
/* Get the file descriptor list. It should not be NULL in this context. */
list = nxsched_get_files();
DEBUGASSERT(list != NULL);
if (fd1 < 0 || fd1 >= CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * list->fl_rows ||
fd2 < 0)
{
return -EBADF;
}
ret = _files_semtake(list);
if (ret < 0)
{
@@ -193,16 +414,25 @@ int nx_dup2(int fd1, int fd2)
return ret;
}
/* Perform the dup2 operation */
ret = file_dup2(&list->fl_files[fd1], &list->fl_files[fd2]);
_files_semgive(list);
if (ret < 0)
if (fd2 >= CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * list->fl_rows)
{
return ret;
ret = files_extend(list, fd2 / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + 1);
if (ret < 0)
{
_files_semgive(list);
return ret;
}
}
return fd2;
/* Perform the dup2 operation */
ret = file_dup2(&list->fl_files[fd1 / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd1 % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK],
&list->fl_files[fd2 / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd2 % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]);
_files_semgive(list);
return ret < 0 ? ret : fd2;
}
/****************************************************************************
@@ -262,23 +492,28 @@ int nx_close(int fd)
list = nxsched_get_files();
DEBUGASSERT(list != NULL);
/* If the file was properly opened, there should be an inode assigned */
if (fd < 0 || fd >= CONFIG_NFILE_DESCRIPTORS ||
!list->fl_files[fd].f_inode)
{
return -EBADF;
}
/* Perform the protected close operation */
ret = _files_semtake(list);
if (ret >= 0)
if (ret < 0)
{
ret = file_close(&list->fl_files[fd]);
_files_semgive(list);
return ret;
}
/* If the file was properly opened, there should be an inode assigned */
if (fd < 0 || fd >= list->fl_rows * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK ||
!list->fl_files[fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK].f_inode)
{
_files_semgive(list);
return -EBADF;
}
ret = file_close(&list->fl_files[fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]
[fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK]);
_files_semgive(list);
return ret;
}

View File

@@ -1024,6 +1024,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
size_t copysize;
size_t totalsize;
int i;
int j;
DEBUGASSERT(group != NULL);
@@ -1046,27 +1047,32 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
/* Examine each open file descriptor */
for (i = 0, file = group->tg_filelist.fl_files;
i < CONFIG_NFILE_DESCRIPTORS;
i++, file++)
for (i = 0; i < group->tg_filelist.fl_rows; i++)
{
/* Is there an inode associated with the file descriptor? */
if (file->f_inode && !INODE_IS_SOCKET(file->f_inode))
for (j = 0, file = group->tg_filelist.fl_files[i];
j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
j++, file++)
{
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %8ld %04x\n", i, (long)file->f_pos,
file->f_oflags);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
remaining, &offset);
/* Is there an inode associated with the file descriptor? */
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
if (file->f_inode && !INODE_IS_SOCKET(file->f_inode))
{
return totalsize;
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %8ld %04x\n",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK +
j, (long)file->f_pos,
file->f_oflags);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
remaining, &offset);
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
{
return totalsize;
}
}
}
}
@@ -1089,30 +1095,33 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
/* Examine each open socket descriptor */
for (i = 0, file = group->tg_filelist.fl_files;
i < CONFIG_NFILE_DESCRIPTORS;
i++, file++)
for (i = 0; i < group->tg_filelist.fl_rows; i++)
{
/* Is there an connection associated with the socket descriptor? */
if (file->f_inode && INODE_IS_SOCKET(file->f_inode))
for (j = 0, file = group->tg_filelist.fl_files[i];
j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
j++, file++)
{
FAR struct socket *socket = file->f_priv;
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %3d %02x",
i + CONFIG_NFILE_DESCRIPTORS,
socket->s_type,
socket->s_flags);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
remaining, &offset);
/* Is there an connection associated with the socket descriptor? */
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
if (file->f_inode && INODE_IS_SOCKET(file->f_inode))
{
return totalsize;
FAR struct socket *socket = file->f_priv;
linesize = snprintf(procfile->line, STATUS_LINELEN,
"%3d %3d %02x",
i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK +
j, socket->s_type,
socket->s_flags);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
remaining, &offset);
totalsize += copysize;
buffer += copysize;
remaining -= copysize;
if (totalsize >= buflen)
{
return totalsize;
}
}
}
}

View File

@@ -21,7 +21,7 @@
# Common file/socket descriptor support
CSRCS += fs_close.c fs_dup.c fs_dup2.c fs_fcntl.c
CSRCS += fs_epoll.c fs_fstat.c fs_fstatfs.c fs_getfilep.c fs_ioctl.c
CSRCS += fs_epoll.c fs_fstat.c fs_fstatfs.c fs_ioctl.c
CSRCS += fs_lseek.c fs_mkdir.c fs_open.c fs_poll.c fs_read.c fs_rename.c
CSRCS += fs_rmdir.c fs_statfs.c fs_stat.c fs_select.c fs_unlink.c fs_write.c

View File

@@ -1,92 +0,0 @@
/****************************************************************************
* fs/vfs/fs_getfilep.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <errno.h>
#include "inode/inode.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: fs_getfilep
*
* Description:
* Given a file descriptor, return the corresponding instance of struct
* file. NOTE that this function will currently fail if it is provided
* with a socket descriptor.
*
* Input Parameters:
* fd - The file descriptor
* filep - The location to return the struct file instance
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int fs_getfilep(int fd, FAR struct file **filep)
{
FAR struct filelist *list;
DEBUGASSERT(filep != NULL);
*filep = (FAR struct file *)NULL;
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
}
/* The descriptor is in a valid range to file descriptor... Get the
* thread-specific file list.
*/
list = nxsched_get_files();
/* The file list can be NULL under two cases: (1) One is an obscure
* cornercase: When memory management debug output is enabled. Then
* there may be attempts to write to stdout from malloc before the group
* data has been allocated. The other other is (2) if this is a kernel
* thread. Kernel threads have no allocated file descriptors.
*/
if (list == NULL)
{
return -EAGAIN;
}
/* And return the file pointer from the list */
*filep = &list->fl_files[fd];
return OK;
}

View File

@@ -113,11 +113,7 @@ struct aiocb
FAR volatile void *aio_buf; /* Location of buffer */
off_t aio_offset; /* File offset */
size_t aio_nbytes; /* Length of transfer */
#if CONFIG_NFILE_DESCRIPTORS > 127
int16_t aio_fildes; /* File descriptor (should be int) */
#else
int8_t aio_fildes; /* File descriptor (should be int) */
#endif
int8_t aio_reqprio; /* Request priority offset (not used, should be int) */
uint8_t aio_lio_opcode; /* Operation to be performed (should be int) */

View File

@@ -120,10 +120,10 @@
#define _POSIX_MAX_INPUT 255
#define _POSIX_NAME_MAX CONFIG_NAME_MAX
#define _POSIX_NGROUPS_MAX 0
#define _POSIX_OPEN_MAX CONFIG_NFILE_DESCRIPTORS
#define _POSIX_OPEN_MAX INT_MAX
#define _POSIX_PATH_MAX CONFIG_PATH_MAX
#define _POSIX_PIPE_BUF 512
#define _POSIX_STREAM_MAX CONFIG_NFILE_DESCRIPTORS
#define _POSIX_STREAM_MAX INT_MAX
#define _POSIX_TZNAME_MAX 3
#ifdef CONFIG_SMALL_MEMORY

View File

@@ -377,12 +377,18 @@ struct file
FAR void *f_priv; /* Per file driver private data */
};
/* This defines a list of files indexed by the file descriptor */
/* This defines a two layer array of files indexed by the file descriptor.
* Each row of this array is fixed size: CONFIG_NFILE_DESCRIPTORS_PER_BLOCK.
* You can get file instance in filelist by the follow methods:
* (file descriptor / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK) as row index and
* (file descriptor % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK) as column index.
*/
struct filelist
{
sem_t fl_sem; /* Manage access to the file list */
struct file fl_files[CONFIG_NFILE_DESCRIPTORS];
sem_t fl_sem; /* Manage access to the file list */
uint8_t fl_rows; /* The number of rows of fl_files array */
FAR struct file **fl_files; /* The pointer of two layer file descriptors array */
};
/* The following structure defines the list of files used for standard C I/O.
@@ -713,6 +719,20 @@ void files_initlist(FAR struct filelist *list);
void files_releaselist(FAR struct filelist *list);
/****************************************************************************
* Name: files_duplist
*
* Description:
* Duplicate parent task's file descriptors.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist);
/****************************************************************************
* Name: file_dup
*

View File

@@ -77,13 +77,6 @@
# define _NX_RECVFROM(s,b,l,f,a,n) recvfrom(s,b,l,f,a,n)
#endif
/* Socket descriptors are the index into the TCB sockets list, offset by the
* following amount. This offset is used to distinguish file descriptors from
* socket descriptors
*/
#define __SOCKFD_OFFSET CONFIG_NFILE_DESCRIPTORS
/* Capabilities of a socket */
#define SOCKCAP_NONBLOCKING (1 << 0) /* Bit 0: Socket supports non-blocking

View File

@@ -37,7 +37,7 @@
/* Get the total number of descriptors that we will have to support */
#define FD_SETSIZE CONFIG_NFILE_DESCRIPTORS
#define FD_SETSIZE 256
/* We will use a 32-bit bitsets to represent the set of descriptors. How
* many uint32_t's do we need to span all descriptors?

View File

@@ -64,7 +64,7 @@ int posix_spawn_file_actions_addclose(
{
FAR struct spawn_close_file_action_s *entry;
DEBUGASSERT(file_actions && fd >= 0 && fd < CONFIG_NFILE_DESCRIPTORS);
DEBUGASSERT(file_actions && fd >= 0);
/* Allocate the action list entry */

View File

@@ -65,9 +65,7 @@ int posix_spawn_file_actions_adddup2(
{
FAR struct spawn_dup2_file_action_s *entry;
DEBUGASSERT(file_actions &&
fd1 >= 0 && fd1 < CONFIG_NFILE_DESCRIPTORS &&
fd2 >= 0 && fd2 < CONFIG_NFILE_DESCRIPTORS);
DEBUGASSERT(file_actions && fd1 >= 0 && fd2 >= 0);
/* Allocate the action list entry */

View File

@@ -79,16 +79,16 @@
*
****************************************************************************/
int posix_spawn_file_actions_addopen(FAR posix_spawn_file_actions_t *file_actions,
int fd, FAR const char *path, int oflags,
mode_t mode)
int posix_spawn_file_actions_addopen(
FAR posix_spawn_file_actions_t *file_actions,
int fd, FAR const char *path, int oflags,
mode_t mode)
{
FAR struct spawn_open_file_action_s *entry;
size_t len;
size_t alloc;
DEBUGASSERT(file_actions && path &&
fd >= 0 && fd < CONFIG_NFILE_DESCRIPTORS);
DEBUGASSERT(file_actions && path && fd >= 0);
/* Get the size of the action including storage for the path plus its NUL
* terminating character.
@@ -111,10 +111,11 @@ int posix_spawn_file_actions_addopen(FAR posix_spawn_file_actions_t *file_action
entry->fd = fd;
entry->oflags = oflags;
entry->mode = mode;
strncpy(entry->path, path, len+1);
strncpy(entry->path, path, len + 1);
/* And add it to the file action list */
add_file_action(file_actions, (FAR struct spawn_general_file_action_s *)entry);
add_file_action(file_actions,
(FAR struct spawn_general_file_action_s *)entry);
return OK;
}

View File

@@ -208,7 +208,7 @@ long sysconf(int name)
switch (name)
{
case _SC_OPEN_MAX:
return CONFIG_NFILE_DESCRIPTORS;
return _POSIX_OPEN_MAX;
case _SC_ATEXIT_MAX:
#ifdef CONFIG_SCHED_EXIT_MAX

View File

@@ -229,6 +229,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
FAR struct socket *psock = sockfd_socket(sockfd);
FAR struct socket *newsock;
FAR struct file *filep;
int newfd;
int errcode;
int ret;
@@ -246,7 +247,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
* used in the wrong context.
*/
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
if (fs_getfilep(sockfd, &filep) == 0)
{
errcode = ENOTSOCK;
}

View File

@@ -29,6 +29,8 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/fs/fs.h>
#include "socket/socket.h"
/****************************************************************************
@@ -128,6 +130,7 @@ int psock_listen(FAR struct socket *psock, int backlog)
int listen(int sockfd, int backlog)
{
FAR struct socket *psock = sockfd_socket(sockfd);
FAR struct file *filep;
int errcode;
int ret;
@@ -140,7 +143,7 @@ int listen(int sockfd, int backlog)
* descriptor used in the wrong context.
*/
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
if (fs_getfilep(sockfd, &filep) == 0)
{
errcode = ENOTSOCK;
}

View File

@@ -1,134 +0,0 @@
/****************************************************************************
* net/socket/net_dup.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/socket.h>
#include <sched.h>
#include <errno.h>
#include <debug.h>
#include "socket/socket.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: psock_dup
*
* Description:
* Clone a socket descriptor to an arbitrary descriptor number.
*
* Returned Value:
* On success, returns the number of new socket. On any error,
* a negated errno value is returned.
*
****************************************************************************/
int psock_dup(FAR struct socket *psock, int minsd)
{
FAR struct socket *psock2;
int sockfd2;
int ret;
/* Make sure that the minimum socket descriptor is within the legal range.
* The minimum value we receive is relative to file descriptor 0; we need
* map it relative of the first socket descriptor.
*/
if (minsd >= CONFIG_NFILE_DESCRIPTORS)
{
minsd -= CONFIG_NFILE_DESCRIPTORS;
}
else
{
minsd = 0;
}
/* Lock the scheduler throughout the following */
sched_lock();
/* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0)
{
ret = -EBADF;
goto errout;
}
/* Allocate a new socket descriptor */
sockfd2 = sockfd_allocate(minsd);
if (sockfd2 < 0)
{
ret = -ENFILE;
goto errout;
}
/* Get the socket structure underlying the new descriptor */
psock2 = sockfd_socket(sockfd2);
if (!psock2)
{
ret = -ENOSYS; /* Should not happen */
goto errout_with_sockfd;
}
/* Duplicate the socket state */
ret = psock_dup2(psock, psock2);
if (ret < 0)
{
goto errout_with_sockfd;
}
sched_unlock();
return sockfd2;
errout_with_sockfd:
sockfd_release(sockfd2);
errout:
sched_unlock();
return ret;
}
/****************************************************************************
* Name: net_dup
*
* Description:
* Clone a socket descriptor to an arbitrary descriptor number.
*
* Returned Value:
* On success, returns the number of new socket. On any error,
* a negated errno value is returned.
*
****************************************************************************/
int net_dup(int sockfd, int minsd)
{
return psock_dup(sockfd_socket(sockfd), minsd);
}

View File

@@ -1058,12 +1058,12 @@ config SDCLONE_DISABLE
descriptors by task_create() when a new task is started. If
set, all sockets will appear to be closed in the new task.
config NFILE_DESCRIPTORS
int "Maximum number of file descriptors per task"
default 16
config NFILE_DESCRIPTORS_PER_BLOCK
int "The number of file descriptors per block"
default 8
range 3 99999
---help---
The maximum number of file descriptors per task (one for each open)
The number of file descriptors per block(one for each open)
config FILE_STREAM
bool "Enable FILE stream"

View File

@@ -25,94 +25,12 @@
#include <nuttx/config.h>
#include <sched.h>
#include <errno.h>
#include <fcntl.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "sched/sched.h"
#include "group/group.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Determine how many file descriptors to clone. If CONFIG_FDCLONE_DISABLE
* is set, no file descriptors will be cloned. If CONFIG_FDCLONE_STDIO is
* set, only the first three descriptors (stdin, stdout, and stderr) will
* be cloned. Otherwise all file descriptors will be cloned.
*/
#if defined(CONFIG_FDCLONE_STDIO) && CONFIG_NFILE_DESCRIPTORS > 3
# define NFDS_TOCLONE 3
#else
# define NFDS_TOCLONE CONFIG_NFILE_DESCRIPTORS
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sched_dupfiles
*
* Description:
* Duplicate parent task's file descriptors.
*
* Input Parameters:
* tcb - tcb of the new task.
*
* Returned Value:
* None
*
****************************************************************************/
#ifndef CONFIG_FDCLONE_DISABLE
static inline void sched_dupfiles(FAR struct task_tcb_s *tcb)
{
/* The parent task is the one at the head of the ready-to-run list */
FAR struct tcb_s *rtcb = this_task();
FAR struct file *parent;
FAR struct file *child;
int i;
DEBUGASSERT(tcb && tcb->cmn.group && rtcb->group);
/* Duplicate the file descriptors. This will be either all of the
* file descriptors or just the first three (stdin, stdout, and stderr)
* if CONFIG_FDCLONE_STDIO is defined. NFSDS_TOCLONE is set
* accordingly above.
*/
/* Get pointers to the parent and child task file lists */
parent = rtcb->group->tg_filelist.fl_files;
child = tcb->cmn.group->tg_filelist.fl_files;
/* Check each file in the parent file list */
for (i = 0; i < NFDS_TOCLONE; i++)
{
/* Check if this file is opened by the parent. We can tell if
* if the file is open because it contain a reference to a non-NULL
* i-node structure.
*/
if (parent[i].f_inode &&
(parent[i].f_oflags & O_CLOEXEC) == 0)
{
/* Yes... duplicate it for the child */
file_dup2(&parent[i], &child[i]);
}
}
}
#else /* !CONFIG_FDCLONE_DISABLE */
# define sched_dupfiles(tcb)
#endif /* !CONFIG_FDCLONE_DISABLE */
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -138,6 +56,10 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb)
int group_setuptaskfiles(FAR struct task_tcb_s *tcb)
{
FAR struct task_group_s *group = tcb->cmn.group;
#ifndef CONFIG_FDCLONE_DISABLE
FAR struct tcb_s *rtcb = this_task();
int ret;
#endif
DEBUGASSERT(group);
#ifndef CONFIG_DISABLE_PTHREAD
@@ -149,9 +71,17 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb)
files_initlist(&group->tg_filelist);
#ifndef CONFIG_FDCLONE_DISABLE
DEBUGASSERT(rtcb->group);
/* Duplicate the parent task's file descriptors */
sched_dupfiles(tcb);
ret = files_duplist(&rtcb->group->tg_filelist, &group->tg_filelist);
if (ret < 0)
{
return ret;
}
#endif
/* Allocate file/socket streams for the new TCB */