diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 9f04b2197c134..63312f7d02048 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -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) @@ -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) { @@ -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. */ @@ -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; }