Skip to content

Commit

Permalink
fs/inode: improve the performance of get file pointer
Browse files Browse the repository at this point in the history
After entering the critical section, we can access the
file pointer without locking the file list directly.
This is safe since the array access will not cause scheduling switching.

Signed-off-by: chao an <[email protected]>
  • Loading branch information
anchao committed Nov 7, 2023
1 parent 57ab766 commit d5f2208
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions fs/inode/fs_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ static FAR struct file *files_fget(int fd, FAR struct filelist *list)
static int files_extend(FAR struct filelist *list, size_t row)
{
FAR struct file **tmp;
irqstate_t flags;
int i;

if (row <= list->fl_rows)
Expand All @@ -80,7 +81,7 @@ static int files_extend(FAR struct filelist *list, size_t row)
return -EMFILE;
}

tmp = kmm_realloc(list->fl_files, sizeof(FAR struct file *) * row);
tmp = kmm_malloc(sizeof(FAR struct file *) * row);
DEBUGASSERT(tmp);
if (tmp == NULL)
{
Expand All @@ -105,9 +106,16 @@ static int files_extend(FAR struct filelist *list, size_t row)
}
while (++i < row);

flags = enter_critical_section();

memcpy(tmp, list->fl_files,
list->fl_rows * sizeof(FAR struct file *));

list->fl_files = tmp;
list->fl_rows = row;

leave_critical_section(flags);

/* Note: If assertion occurs, the fl_rows has a overflow.
* And there may be file descriptors leak in system.
*/
Expand Down Expand Up @@ -594,26 +602,42 @@ int fs_getfilep(int fd, FAR struct file **filep)
* thread-specific file list.
*/

/* And return the file pointer from the list */

ret = nxmutex_lock(&list->fl_lock);
if (ret < 0)
if (!nxmutex_is_locked(&list->fl_lock))
{
leave_critical_section(flags);
return ret;
*filep = files_fget(fd, list);

/* if f_inode is NULL, fd was closed */

if (!(*filep)->f_inode)
{
*filep = NULL;
ret = -EBADF;
}
}
else
{
/* And return the file pointer from the list */

*filep = files_fget(fd, list);
ret = nxmutex_lock(&list->fl_lock);
if (ret < 0)
{
leave_critical_section(flags);
return ret;
}

/* if f_inode is NULL, fd was closed */
*filep = files_fget(fd, list);

if (!(*filep)->f_inode)
{
*filep = NULL;
ret = -EBADF;
/* if f_inode is NULL, fd was closed */

if (!(*filep)->f_inode)
{
*filep = NULL;
ret = -EBADF;
}

nxmutex_unlock(&list->fl_lock);
}

nxmutex_unlock(&list->fl_lock);
leave_critical_section(flags);
return ret;
}
Expand Down

0 comments on commit d5f2208

Please sign in to comment.