This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new a459280fac use atomic to protect f_refs
a459280fac is described below
commit a459280fac220f137455059e635e65015d657e88
Author: hujun5 <[email protected]>
AuthorDate: Fri Dec 13 16:50:59 2024 +0800
use atomic to protect f_refs
fix regresion from https://github.com/apache/nuttx/pull/14801
Signed-off-by: hujun5 <[email protected]>
---
fs/inode/fs_files.c | 48 ++++++++++++++++++++++--------------------------
include/nuttx/fs/fs.h | 3 ++-
2 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c
index c2268bb9e5..5135a856b6 100644
--- a/fs/inode/fs_files.c
+++ b/fs/inode/fs_files.c
@@ -76,33 +76,40 @@ static FAR struct file *files_fget_by_index(FAR struct
filelist *list,
filep = &list->fl_files[l1][l2];
#ifdef CONFIG_FS_REFCOUNT
+ int32_t refs = 0;
+
if (filep->f_inode != NULL)
{
/* When the reference count is zero but the inode has not yet been
* released, At this point we should return a null pointer
*/
- if (filep->f_refs == 0)
- {
- filep = NULL;
- }
- else
+ do
{
- filep->f_refs++;
+ refs = atomic_read(&filep->f_refs);
+ if (refs == 0)
+ {
+ filep = NULL;
+ break;
+ }
}
+ while (!atomic_try_cmpxchg(&filep->f_refs, &refs, refs + 1));
}
else if (new == NULL)
{
filep = NULL;
}
- else if (filep->f_refs)
- {
- filep->f_refs++;
- }
else
{
- filep->f_refs = 2;
- *new = true;
+ do
+ {
+ if (atomic_cmpxchg(&filep->f_refs, &refs, 2))
+ {
+ *new = true;
+ break;
+ }
+ }
+ while (!atomic_try_cmpxchg(&filep->f_refs, &refs, refs + 1));
}
#else
if (filep->f_inode == NULL && new == NULL)
@@ -593,7 +600,7 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR
struct inode *inode,
filep->f_inode = inode;
filep->f_priv = priv;
#ifdef CONFIG_FS_REFCOUNT
- filep->f_refs = 1;
+ atomic_set(&filep->f_refs, 1);
#endif
#ifdef CONFIG_FDSAN
filep->f_tag_fdsan = 0;
@@ -823,12 +830,8 @@ void fs_reffilep(FAR struct file *filep)
{
/* This interface is used to increase the reference count of filep */
- irqstate_t flags;
-
DEBUGASSERT(filep);
- flags = spin_lock_irqsave(NULL);
- filep->f_refs++;
- spin_unlock_irqrestore(NULL, flags);
+ atomic_fetch_add(&filep->f_refs, 1);
}
/****************************************************************************
@@ -845,20 +848,13 @@ void fs_reffilep(FAR struct file *filep)
int fs_putfilep(FAR struct file *filep)
{
- irqstate_t flags;
int ret = 0;
- int refs;
DEBUGASSERT(filep);
- flags = spin_lock_irqsave(NULL);
-
- refs = --filep->f_refs;
-
- spin_unlock_irqrestore(NULL, flags);
/* If refs is zero, the close() had called, closing it now. */
- if (refs == 0)
+ if (atomic_fetch_sub(&filep->f_refs, 1) == 1)
{
ret = file_close(filep);
if (ret < 0)
diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h
index 31e2158b26..dd3ff75403 100644
--- a/include/nuttx/fs/fs.h
+++ b/include/nuttx/fs/fs.h
@@ -50,6 +50,7 @@
#include <nuttx/queue.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock_type.h>
+#include <nuttx/atomic.h>
/****************************************************************************
* Pre-processor Definitions
@@ -461,7 +462,7 @@ struct file
{
int f_oflags; /* Open mode flags */
#ifdef CONFIG_FS_REFCOUNT
- int f_refs; /* Reference count */
+ atomic_t f_refs; /* Reference count */
#endif
off_t f_pos; /* File position */
FAR struct inode *f_inode; /* Driver or file system interface */