From 00e878e84883fcf996e14f49e94943a37a1f4cf7 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Tue, 2 Jul 2024 21:46:19 +0800 Subject: [PATCH] fs/inode: add reference to protect filelist of group Signed-off-by: dongjiuzhu1 --- fs/inode/fs_files.c | 42 +++++++++++++++++++++++++++++++++------ include/nuttx/fs/fs.h | 17 +++++++++++++--- sched/group/group_leave.c | 2 +- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 6eda34bc1a..e035264dfb 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -173,8 +173,7 @@ static void task_fssync(FAR struct tcb_s *tcb, FAR void *arg) int i; int j; - list = &tcb->group->tg_filelist; - + list = files_getlist(tcb); for (i = 0; i < list->fl_rows; i++) { for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++) @@ -188,6 +187,8 @@ static void task_fssync(FAR struct tcb_s *tcb, FAR void *arg) } } } + + files_putlist(list); } /**************************************************************************** @@ -308,6 +309,7 @@ void files_initlist(FAR struct filelist *list) */ list->fl_rows = 1; + list->fl_crefs = 1; list->fl_files = &list->fl_prefile; list->fl_prefile = list->fl_prefiles; } @@ -374,19 +376,47 @@ void files_dumplist(FAR struct filelist *list) } /**************************************************************************** - * Name: files_releaselist + * Name: files_getlist * * Description: - * Release a reference to the file list + * Get the list of files by tcb. + * + * Assumptions: + * Called during task deletion in a safe context. * ****************************************************************************/ -void files_releaselist(FAR struct filelist *list) +FAR struct filelist *files_getlist(FAR struct tcb_s *tcb) +{ + FAR struct filelist *list = &tcb->group->tg_filelist; + + DEBUGASSERT(list->fl_crefs >= 1); + list->fl_crefs++; + + return list; +} + +/**************************************************************************** + * Name: files_putlist + * + * Description: + * Release the list of files. + * + * Assumptions: + * Called during task deletion in a safe context. + * + ****************************************************************************/ + +void files_putlist(FAR struct filelist *list) { int i; int j; - DEBUGASSERT(list); + DEBUGASSERT(list->fl_crefs >= 1); + if (--list->fl_crefs > 0) + { + return; + } /* Close each file descriptor .. Normally, you would need take the list * mutex, but it is safe to ignore the mutex in this context diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 5189c48978..6e600c3827 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -495,6 +495,7 @@ struct file struct filelist { uint8_t fl_rows; /* The number of rows of fl_files array */ + uint8_t fl_crefs; /* The references to filelist */ FAR struct file **fl_files; /* The pointer of two layer file descriptors array */ /* Pre-allocated files to avoid allocator access during thread creation @@ -875,14 +876,24 @@ void files_initlist(FAR struct filelist *list); void files_dumplist(FAR struct filelist *list); /**************************************************************************** - * Name: files_releaselist + * Name: files_getlist * * Description: - * Release a reference to the file list + * Get the list of files by tcb. * ****************************************************************************/ -void files_releaselist(FAR struct filelist *list); +FAR struct filelist *files_getlist(FAR struct tcb_s *tcb); + +/**************************************************************************** + * Name: files_putlist + * + * Description: + * Release the list of files. + * + ****************************************************************************/ + +void files_putlist(FAR struct filelist * list); /**************************************************************************** * Name: files_countlist diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 4cab22c46a..193e364b0c 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -96,7 +96,7 @@ group_release(FAR struct task_group_s *group, uint8_t ttype) /* Free resources held by the file descriptor list */ - files_releaselist(&group->tg_filelist); + files_putlist(&group->tg_filelist); #ifndef CONFIG_DISABLE_ENVIRON /* Release all shared environment variables */