This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 60b25556d4b282c4f14e415e44365216d0457637 Author: ligd <[email protected]> AuthorDate: Thu Dec 7 16:46:01 2023 +0800 fs: enhance file_allocate_from_tcb() mulit-threads saftey Signed-off-by: ligd <[email protected]> --- fs/inode/fs_files.c | 58 ++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 7018bef995..bcf301d397 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -379,64 +379,54 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode, int oflags, off_t pos, FAR void *priv, int minfd, bool addref) { + int i = minfd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; + int j = minfd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; FAR struct filelist *list; FAR struct file *filep; + irqstate_t flags; int ret; - int i; - int j; /* Get the file descriptor list. It should not be NULL in this context. */ list = nxsched_get_files_from_tcb(tcb); - /* Calculate minfd whether is in list->fl_files. - * if not, allocate a new filechunk. - */ + /* Find free file */ + + flags = spin_lock_irqsave(&list->fl_lock); - i = minfd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; - if (i >= list->fl_rows) + for (; ; i++, j = 0) { - ret = files_extend(list, i + 1); - if (ret < 0) + if (i >= list->fl_rows) { - return ret; - } - } + spin_unlock_irqrestore(&list->fl_lock, flags); - /* Find free file */ + ret = files_extend(list, i + 1); + if (ret < 0) + { + return ret; + } + + flags = spin_lock_irqsave(&list->fl_lock); + } - j = minfd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; - do - { do { - filep = files_fget_by_index(list, i, j); + filep = &list->fl_files[i][j]; if (filep->f_inode == NULL) { + filep->f_oflags = oflags; + filep->f_pos = pos; + filep->f_inode = inode; + filep->f_priv = priv; + goto found; } } 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) - { - return ret; - } - - filep = files_fget_by_index(list, i, 0); found: - - filep->f_oflags = oflags; - filep->f_pos = pos; - filep->f_inode = inode; - filep->f_priv = priv; + spin_unlock_irqrestore(&list->fl_lock, flags); if (addref) {
