fs: allocate file/socket dynamically

MIRTOS-273

Change-Id: I8aea63eaf0275f47f21fc8d5482b51ffecd5c906
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong
2021-03-08 14:51:00 +08:00
committed by 刘海涛
parent d07669e2ed
commit 7a6a1c1f42
35 changed files with 731 additions and 473 deletions
+9 -5
View File
@@ -69,18 +69,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -84,18 +84,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -68,18 +68,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -86,18 +86,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -79,18 +79,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -4
View File
@@ -79,17 +79,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -84,18 +84,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -68,18 +68,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -86,18 +86,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -68,18 +68,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -9
View File
@@ -63,29 +63,29 @@
#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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
#endif
#ifdef CONFIG_FILE_STREAM
filep = tcb->group->tg_streamlist->sl_head;
+1 -6
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
@@ -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 */
+9 -5
View File
@@ -85,18 +85,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -68,18 +68,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
+9 -5
View File
@@ -70,18 +70,22 @@ 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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + j, inode->i_crefs);
}
}
}
-4
View File
@@ -61,10 +61,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
File diff suppressed because it is too large Load Diff
+269 -34
View File
@@ -30,6 +30,7 @@
#include <assert.h>
#include <sched.h>
#include <errno.h>
#include <fcntl.h>
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
@@ -57,6 +58,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_NFCHUNK_DESCRIPTORS);
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
****************************************************************************/
@@ -100,6 +145,7 @@ void files_initlist(FAR struct filelist *list)
void files_releaselist(FAR struct filelist *list)
{
int i;
int j;
DEBUGASSERT(list);
@@ -108,11 +154,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_NFCHUNK_DESCRIPTORS - 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);
@@ -133,6 +186,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. */
@@ -147,21 +201,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_NFCHUNK_DESCRIPTORS;
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_NFCHUNK_DESCRIPTORS;
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_NFCHUNK_DESCRIPTORS + j;
}
}
while (++j < CONFIG_NFCHUNK_DESCRIPTORS);
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_NFCHUNK_DESCRIPTORS;
}
_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_NFCHUNK_DESCRIPTORS; 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_NFCHUNK_DESCRIPTORS + 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_NFCHUNK_DESCRIPTORS * 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_NFCHUNK_DESCRIPTORS]
[fd % CONFIG_NFCHUNK_DESCRIPTORS];
_files_semgive(list);
}
return OK;
}
/****************************************************************************
@@ -187,17 +408,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_NFCHUNK_DESCRIPTORS * list->fl_rows ||
fd2 < 0)
{
return -EBADF;
}
ret = _files_semtake(list);
if (ret < 0)
{
@@ -206,16 +427,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_NFCHUNK_DESCRIPTORS * list->fl_rows)
{
return ret;
ret = files_extend(list, fd2 / CONFIG_NFCHUNK_DESCRIPTORS + 1);
if (ret < 0)
{
_files_semgive(list);
return ret;
}
}
return fd2;
/* Perform the dup2 operation */
ret = file_dup2(&list->fl_files[fd1 / CONFIG_NFCHUNK_DESCRIPTORS]
[fd1 % CONFIG_NFCHUNK_DESCRIPTORS],
&list->fl_files[fd2 / CONFIG_NFCHUNK_DESCRIPTORS]
[fd2 % CONFIG_NFCHUNK_DESCRIPTORS]);
_files_semgive(list);
return ret < 0 ? ret : fd2;
}
/****************************************************************************
@@ -275,23 +505,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_NFCHUNK_DESCRIPTORS ||
!list->fl_files[fd / CONFIG_NFCHUNK_DESCRIPTORS]
[fd % CONFIG_NFCHUNK_DESCRIPTORS].f_inode)
{
_files_semgive(list);
return -EBADF;
}
ret = file_close(&list->fl_files[fd / CONFIG_NFCHUNK_DESCRIPTORS]
[fd % CONFIG_NFCHUNK_DESCRIPTORS]);
_files_semgive(list);
return ret;
}
-6
View File
@@ -140,12 +140,6 @@ FAR void *rammap(int fd, size_t length, off_t offset)
/* Allocate a region of memory of the specified size */
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
{
errcode = EBADF;
goto errout;
}
alloc = (FAR uint8_t *)kumm_malloc(sizeof(struct fs_rammap_s) + length);
if (!alloc)
{
+46 -37
View File
@@ -1080,6 +1080,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);
@@ -1102,27 +1103,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_NFCHUNK_DESCRIPTORS;
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_NFCHUNK_DESCRIPTORS + 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;
}
}
}
}
@@ -1145,30 +1151,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_NFCHUNK_DESCRIPTORS;
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_NFCHUNK_DESCRIPTORS + 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;
}
}
}
}
+1 -1
View File
@@ -36,7 +36,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
-107
View File
@@ -1,107 +0,0 @@
/****************************************************************************
* fs/vfs/fs_getfilep.c
*
* Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* 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;
}
-4
View File
@@ -128,11 +128,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) */
+2 -2
View File
@@ -135,10 +135,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
+23 -3
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_NFCHUNK_DESCRIPTORS.
* You can get file instance in filelist by the follow methods:
* (file descriptor / CONFIG_NFCHUNK_DESCRIPTORS) as row index and
* (file descriptor % CONFIG_NFCHUNK_DESCRIPTORS) 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
*
-7
View File
@@ -81,13 +81,6 @@
# define _NX_GETERRVAL(r) (-errno)
#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
+1 -1
View File
@@ -52,7 +52,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?
+1 -1
View File
@@ -78,7 +78,7 @@ int posix_spawn_file_actions_addclose(FAR posix_spawn_file_actions_t *file_actio
{
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 */
+1 -3
View File
@@ -79,9 +79,7 @@ int posix_spawn_file_actions_adddup2(FAR posix_spawn_file_actions_t *file_action
{
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 */
+1 -2
View File
@@ -87,8 +87,7 @@ int posix_spawn_file_actions_addopen(FAR posix_spawn_file_actions_t *file_action
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.
+1 -1
View File
@@ -224,7 +224,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
+2 -1
View File
@@ -244,6 +244,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;
@@ -261,7 +262,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;
}
+4 -1
View File
@@ -44,6 +44,8 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/fs/fs.h>
#include "socket/socket.h"
/****************************************************************************
@@ -143,6 +145,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;
@@ -155,7 +158,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;
}
+4 -4
View File
@@ -1065,12 +1065,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 NFCHUNK_DESCRIPTORS
int "The number of file descriptors per row"
default 8
range 3 99999
---help---
The maximum number of file descriptors per task (one for each open)
The number of file descriptors per row (one for each open)
config FILE_STREAM
bool "Enable FILE stream"
+13 -83
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 */