Skip to content

Commit

Permalink
use small lock 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 12, 2024
1 parent 890cf47 commit 634f337
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
19 changes: 13 additions & 6 deletions fs/inode/fs_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ 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
Expand All @@ -84,25 +86,30 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list,

if (filep->f_refs == 0)
{
spin_unlock_irqrestore(&filep->lock, flags);
filep = NULL;
}
else
{
filep->f_refs++;
spin_unlock_irqrestore(&filep->lock, flags);
}
}
else if (new == NULL)
{
spin_unlock_irqrestore(&filep->lock, flags);
filep = NULL;
}
else if (filep->f_refs)
{
filep->f_refs++;
spin_unlock_irqrestore(&filep->lock, flags);
}
else
{
filep->f_refs = 2;
*new = true;
spin_unlock_irqrestore(&filep->lock, flags);
}
#else
if (filep->f_inode == NULL && new == NULL)
Expand All @@ -111,7 +118,6 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list,
}
#endif

spin_unlock_irqrestore(&list->fl_lock, flags);
return filep;
}

Expand Down Expand Up @@ -629,6 +635,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;
Expand Down Expand Up @@ -861,9 +868,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);
}

/****************************************************************************
Expand All @@ -885,11 +892,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. */

Expand Down
1 change: 1 addition & 0 deletions include/nuttx/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 634f337

Please sign in to comment.