From 03f1f1a7fb63f8972aab7bb28b1756a5f1457507 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Thu, 12 Dec 2024 21:15:51 +0800 Subject: [PATCH] use small lock to protect f_refs fix regresion from https://github.com/apache/nuttx/pull/14801 Signed-off-by: hujun5 --- fs/inode/fs_files.c | 17 +++++++++++------ include/nuttx/fs/fs.h | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 8374ad06d3041..2a1408d81f51f 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -73,9 +73,12 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list, irqstate_t flags; flags = spin_lock_irqsave(&list->fl_lock); - filep = &list->fl_files[l1][l2]; + spin_unlock_irqrestore(&list->fl_lock, flags); + #ifdef CONFIG_FS_REFCOUNT + + flags = spin_lock_irqsave(&filep->lock); if (filep->f_inode != NULL) { /* When the reference count is zero but the inode has not yet been @@ -104,6 +107,8 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list, filep->f_refs = 2; *new = true; } + + spin_unlock_irqrestore(&filep->lock, flags); #else if (filep->f_inode == NULL && new == NULL) { @@ -111,7 +116,6 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list, } #endif - spin_unlock_irqrestore(&list->fl_lock, flags); return filep; } @@ -629,6 +633,7 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode, filep->f_priv = priv; #ifdef CONFIG_FS_REFCOUNT filep->f_refs = 1; + spin_lock_init(&filep->lock); #endif #ifdef CONFIG_FDSAN filep->f_tag_fdsan = 0; @@ -861,9 +866,9 @@ void fs_reffilep(FAR struct file *filep) irqstate_t flags; DEBUGASSERT(filep); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&filep->lock); filep->f_refs++; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&filep->lock, flags); } /**************************************************************************** @@ -885,11 +890,11 @@ int fs_putfilep(FAR struct file *filep) int refs; DEBUGASSERT(filep); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&filep->lock); refs = --filep->f_refs; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&filep->lock, flags); /* If refs is zero, the close() had called, closing it now. */ diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index e82df41bffea5..6c17a051797e3 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -462,6 +462,7 @@ struct file int f_oflags; /* Open mode flags */ #ifdef CONFIG_FS_REFCOUNT int f_refs; /* Reference count */ + spinlock_t lock; /* Reference spinlock */ #endif off_t f_pos; /* File position */ FAR struct inode *f_inode; /* Driver or file system interface */