Skip to content

Commit

Permalink
use atomic to protect f_refs
Browse files Browse the repository at this point in the history
fix regresion from #14801

Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 committed Dec 13, 2024
1 parent 5cdc6c7 commit cefe424
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 27 deletions.
48 changes: 22 additions & 26 deletions fs/inode/fs_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_try_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)
Expand Down Expand Up @@ -628,7 +635,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;
Expand Down Expand Up @@ -858,12 +865,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);
}

/****************************************************************************
Expand All @@ -880,20 +883,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)
Expand Down
3 changes: 2 additions & 1 deletion include/nuttx/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <nuttx/queue.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock_type.h>
#include <nuttx/atomic.h>

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit cefe424

Please sign in to comment.