vfs/file: add reference counting to prevent accidental close during reading writing...

Signed-off-by: Shoukui Zhang <zhangshoukui@xiaomi.com>
This commit is contained in:
Shoukui Zhang 2023-12-25 15:04:01 +08:00 committed by Xiang Xiao
parent f2fd0bc148
commit 43223124ec
50 changed files with 335 additions and 146 deletions

View File

@ -603,6 +603,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
audinfo("AUDIOIOC_UNREGISTERMQ\n");
fs_putfilep(upper->usermq);
upper->usermq = NULL;
ret = OK;
}

View File

@ -901,6 +901,7 @@ static int telnet_session(FAR struct telnet_session_s *session)
{
FAR struct telnet_dev_s *priv;
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Allocate instance data for this driver */
@ -931,7 +932,7 @@ static int telnet_session(FAR struct telnet_session_s *session)
* instance resided in the daemon's task group`).
*/
ret = sockfd_socket(session->ts_sd, &psock);
ret = sockfd_socket(session->ts_sd, &filep, &psock);
if (ret != OK)
{
nerr("ERROR: Failed to convert sd=%d to a socket structure\n",
@ -940,6 +941,7 @@ static int telnet_session(FAR struct telnet_session_s *session)
}
ret = psock_dup2(psock, &priv->td_psock);
fs_putfilep(filep);
if (ret < 0)
{
nerr("ERROR: psock_dup2 failed: %d\n", ret);

View File

@ -80,35 +80,40 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp)
*/
aioc = aioc_alloc();
if (aioc != NULL)
if (aioc == NULL)
{
/* Initialize the container */
ret = -ENOMEM;
goto err_putfilep;
}
memset(aioc, 0, sizeof(struct aio_container_s));
aioc->aioc_aiocbp = aiocbp;
aioc->aioc_filep = filep;
aioc->aioc_pid = nxsched_getpid();
/* Initialize the container */
memset(aioc, 0, sizeof(struct aio_container_s));
aioc->aioc_aiocbp = aiocbp;
aioc->aioc_filep = filep;
aioc->aioc_pid = nxsched_getpid();
#ifdef CONFIG_PRIORITY_INHERITANCE
DEBUGVERIFY(nxsched_get_param (aioc->aioc_pid, &param));
aioc->aioc_prio = param.sched_priority;
DEBUGVERIFY(nxsched_get_param(aioc->aioc_pid, &param));
aioc->aioc_prio = param.sched_priority;
#endif
/* Add the container to the pending transfer list. */
/* Add the container to the pending transfer list. */
ret = aio_lock();
if (ret < 0)
{
aioc_free(aioc);
goto errout;
}
dq_addlast(&aioc->aioc_link, &g_aio_pending);
aio_unlock();
ret = aio_lock();
if (ret < 0)
{
aioc_free(aioc);
goto err_putfilep;
}
dq_addlast(&aioc->aioc_link, &g_aio_pending);
aio_unlock();
return aioc;
err_putfilep:
fs_putfilep(filep);
errout:
set_errno(-ret);
return NULL;
@ -148,6 +153,7 @@ FAR struct aiocb *aioc_decant(FAR struct aio_container_s *aioc)
*/
aiocbp = aioc->aioc_aiocbp;
fs_putfilep(aioc->aioc_filep);
aioc_free(aioc);
aio_unlock();

View File

@ -63,7 +63,7 @@
****************************************************************************/
static FAR struct file *files_fget_by_index(FAR struct filelist *list,
int l1, int l2)
int l1, int l2, FAR bool *new)
{
FAR struct file *filep;
irqstate_t flags;
@ -71,9 +71,25 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list,
flags = spin_lock_irqsave(NULL);
filep = &list->fl_files[l1][l2];
if (filep->f_inode != NULL)
{
filep->f_refs++;
}
else if (new == NULL)
{
filep = NULL;
}
else if (filep->f_refs)
{
filep->f_refs++;
}
else
{
filep->f_refs = 2;
*new = true;
}
spin_unlock_irqrestore(NULL, flags);
return filep;
}
@ -180,10 +196,11 @@ static void task_fssync(FAR struct tcb_s *tcb, FAR void *arg)
{
FAR struct file *filep;
filep = files_fget_by_index(list, i, j);
if (filep->f_inode != NULL)
filep = files_fget_by_index(list, i, j, NULL);
if (filep != NULL)
{
file_fsync(filep);
fs_putfilep(filep);
}
}
}
@ -215,6 +232,7 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
int flags)
{
FAR struct filelist *list;
FAR struct file *filep1;
FAR struct file *filep;
#ifdef CONFIG_FDCHECK
uint8_t f_tag_fdcheck;
@ -222,6 +240,7 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
#ifdef CONFIG_FDSAN
uint64_t f_tag_fdsan;
#endif
bool new = false;
int count;
int ret;
@ -254,12 +273,17 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
}
}
filep = files_fget(list, fd2);
if (filep == NULL)
filep1 = files_fget(list, fd1);
if (filep1 == NULL)
{
return -EBADF;
}
filep = files_fget_by_index(list,
fd2 / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK,
fd2 % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK,
&new);
#ifdef CONFIG_FDSAN
f_tag_fdsan = filep->f_tag_fdsan;
#endif
@ -270,9 +294,16 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
/* Perform the dup3 operation */
ret = file_dup3(files_fget(list, fd1), filep, flags);
ret = file_dup3(filep1, filep, flags);
fs_putfilep(filep1);
fs_putfilep(filep);
if (ret < 0)
{
if (new)
{
fs_putfilep(filep);
}
return ret;
}
@ -482,7 +513,7 @@ int files_countlist(FAR struct filelist *list)
FAR struct file *files_fget(FAR struct filelist *list, int fd)
{
return files_fget_by_index(list, fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK,
fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK);
fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK, NULL);
}
/****************************************************************************
@ -541,6 +572,7 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode,
filep->f_pos = pos;
filep->f_inode = inode;
filep->f_priv = priv;
filep->f_refs = 1;
goto found;
}
@ -607,7 +639,9 @@ int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist,
{
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
{
FAR struct file *filep2;
FAR struct file *filep;
bool new = false;
fd = i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j;
#ifdef CONFIG_FDCLONE_STDIO
@ -625,8 +659,8 @@ int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist,
}
#endif
filep = files_fget_by_index(plist, i, j);
if (filep->f_inode == NULL)
filep = files_fget_by_index(plist, i, j, NULL);
if (filep == NULL)
{
continue;
}
@ -642,25 +676,36 @@ int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist,
#endif
if (!spawn_file_is_duplicateable(actions, fd, fcloexec))
{
fs_putfilep(filep);
continue;
}
}
else if (fcloexec)
{
fs_putfilep(filep);
continue;
}
ret = files_extend(clist, i + 1);
if (ret < 0)
{
fs_putfilep(filep);
return ret;
}
/* Yes... duplicate it for the child, include O_CLOEXEC flag. */
ret = file_dup2(filep, files_fget_by_index(clist, i, j));
filep2 = files_fget_by_index(clist, i, j, &new);
ret = file_dup2(filep, filep2);
fs_putfilep(filep2);
fs_putfilep(filep);
if (ret < 0)
{
if (new)
{
fs_putfilep(filep2);
}
return ret;
}
}
@ -721,17 +766,55 @@ int fs_getfilep(int fd, FAR struct file **filep)
*filep = files_fget(list, fd);
/* if f_inode is NULL, fd was closed */
/* if *filep is NULL, fd was closed */
if ((*filep)->f_inode == NULL)
if (*filep == NULL)
{
*filep = NULL;
return -EBADF;
}
return OK;
}
/****************************************************************************
* Name: fs_putfilep
*
* Description:
* Handles reference counts for files, less than or equal to 0 and close
* the file
*
* Input Parameters:
* filep - The caller provided location in which to return the 'struct
* file' instance.
****************************************************************************/
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)
{
ret = file_close(filep);
if (ret < 0)
{
ferr("ERROR: fs putfilep file_close() failed: %d\n", ret);
}
}
return ret;
}
/****************************************************************************
* Name: nx_dup2_from_tcb
*
@ -870,12 +953,20 @@ int nx_close_from_tcb(FAR struct tcb_s *tcb, int fd)
/* If the file was properly opened, there should be an inode assigned */
if (filep->f_inode == NULL)
if (filep == NULL)
{
return -EBADF;
}
return file_close(filep);
/* files_fget will increase the reference count, there call fs_putfilep
* reduce reference count.
*/
fs_putfilep(filep);
/* Undo the last reference count from file_allocate_from_tcb */
return fs_putfilep(filep);
}
/****************************************************************************

View File

@ -286,6 +286,11 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
ret = file_mmap_(filep, start, length,
prot, flags, offset, false, &mapped);
if (fd != -1)
{
fs_putfilep(filep);
}
if (ret < 0)
{
goto errout;

View File

@ -596,21 +596,21 @@ static int inotify_close(FAR struct file *filep)
*
****************************************************************************/
static FAR struct inotify_device_s *inotify_get_device_from_fd(int fd)
static FAR struct inotify_device_s *
inotify_get_device_from_fd(int fd, FAR struct file **filep)
{
FAR struct file *filep;
if (fs_getfilep(fd, &filep) < 0)
if (fs_getfilep(fd, filep) < 0)
{
return NULL;
}
if (filep == NULL || filep->f_inode != &g_inotify_inode)
if ((*filep)->f_inode != &g_inotify_inode)
{
fs_putfilep(*filep);
return NULL;
}
return filep->f_priv;
return (*filep)->f_priv;
}
/****************************************************************************
@ -1056,6 +1056,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
FAR struct inotify_watch_s *watch;
FAR struct inotify_watch_s *old;
FAR struct inotify_device_s *dev;
FAR struct file *filep;
FAR char *abspath;
struct stat buf;
int ret;
@ -1066,7 +1067,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
return ERROR;
}
dev = inotify_get_device_from_fd(fd);
dev = inotify_get_device_from_fd(fd, &filep);
if (dev == NULL)
{
set_errno(EBADF);
@ -1076,6 +1077,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
abspath = lib_realpath(pathname, NULL, mask & IN_DONT_FOLLOW);
if (abspath == NULL)
{
fs_putfilep(filep);
return ERROR;
}
@ -1146,6 +1148,7 @@ out:
nxmutex_unlock(&g_inotify.lock);
out_free:
fs_putfilep(filep);
lib_free(abspath);
if (ret < 0)
{
@ -1177,8 +1180,9 @@ int inotify_rm_watch(int fd, int wd)
{
FAR struct inotify_device_s *dev;
FAR struct inotify_watch_s *watch;
FAR struct file *filep;
dev = inotify_get_device_from_fd(fd);
dev = inotify_get_device_from_fd(fd, &filep);
if (dev == NULL)
{
set_errno(EBADF);
@ -1192,6 +1196,7 @@ int inotify_rm_watch(int fd, int wd)
{
nxmutex_unlock(&dev->lock);
nxmutex_unlock(&g_inotify.lock);
fs_putfilep(filep);
set_errno(EINVAL);
return ERROR;
}
@ -1199,6 +1204,7 @@ int inotify_rm_watch(int fd, int wd)
inotify_remove_watch(dev, watch);
nxmutex_unlock(&dev->lock);
nxmutex_unlock(&g_inotify.lock);
fs_putfilep(filep);
return OK;
}

View File

@ -1295,7 +1295,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
/* Is there an inode associated with the file descriptor? */
if (filep->f_inode == NULL)
if (filep == NULL)
{
continue;
}
@ -1321,6 +1321,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
procfile->line[linesize - 2] = '\n';
}
fs_putfilep(filep);
copysize = procfs_memcpy(procfile->line, linesize,
buffer, remaining, &offset);

View File

@ -192,8 +192,7 @@ int sockfd_allocate(FAR struct socket *psock, int oflags)
FAR struct socket *file_socket(FAR struct file *filep)
{
if (filep != NULL && filep->f_inode != NULL &&
INODE_IS_SOCKET(filep->f_inode))
if (filep != NULL && INODE_IS_SOCKET(filep->f_inode))
{
return filep->f_priv;
}
@ -201,17 +200,20 @@ FAR struct socket *file_socket(FAR struct file *filep)
return NULL;
}
int sockfd_socket(int sockfd, FAR struct socket **socketp)
int sockfd_socket(int sockfd, FAR struct file **filep,
FAR struct socket **socketp)
{
FAR struct file *filep;
if (fs_getfilep(sockfd, &filep) < 0)
if (fs_getfilep(sockfd, filep) < 0)
{
*socketp = NULL;
return -EBADF;
}
*socketp = file_socket(filep);
*socketp = file_socket(*filep);
if (*socketp == NULL)
{
fs_putfilep(*filep);
}
return *socketp != NULL ? OK : -ENOTSOCK;
}

View File

@ -70,7 +70,6 @@ int file_dup(FAR struct file *filep, int minfd, int flags)
if (fd2 < 0)
{
file_close(&filep2);
return fd2;
}
return fd2;
@ -97,11 +96,10 @@ int dup(int fd)
goto err;
}
DEBUGASSERT(filep != NULL);
/* Let file_dup() do the real work */
ret = file_dup(filep, 0, 0);
fs_putfilep(filep);
if (ret < 0)
{
goto err;

View File

@ -134,14 +134,13 @@ static struct inode g_epoll_inode =
* Private Functions
****************************************************************************/
static FAR epoll_head_t *epoll_head_from_fd(int fd)
static FAR epoll_head_t *epoll_head_from_fd(int fd, FAR struct file **filep)
{
FAR struct file *filep;
int ret;
/* Get file pointer by file descriptor */
ret = fs_getfilep(fd, &filep);
ret = fs_getfilep(fd, filep);
if (ret < 0)
{
set_errno(-ret);
@ -150,13 +149,14 @@ static FAR epoll_head_t *epoll_head_from_fd(int fd)
/* Check fd come from us */
if (!filep->f_inode || filep->f_inode->u.i_ops != &g_epoll_ops)
if ((*filep)->f_inode->u.i_ops != &g_epoll_ops)
{
fs_putfilep(*filep);
set_errno(EBADF);
return NULL;
}
return (FAR epoll_head_t *)filep->f_priv;
return (*filep)->f_priv;
}
static int epoll_do_open(FAR struct file *filep)
@ -476,12 +476,13 @@ void epoll_close(int epfd)
int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
{
FAR struct list_node *extend;
FAR struct file *filep;
FAR epoll_head_t *eph;
FAR epoll_node_t *epn;
int ret;
int i;
eph = epoll_head_from_fd(epfd);
eph = epoll_head_from_fd(epfd, &filep);
if (eph == NULL)
{
return ERROR;
@ -690,10 +691,12 @@ int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
out:
nxmutex_unlock(&eph->lock);
fs_putfilep(filep);
return OK;
err:
nxmutex_unlock(&eph->lock);
err_without_lock:
fs_putfilep(filep);
set_errno(-ret);
return ERROR;
}
@ -705,11 +708,12 @@ err_without_lock:
int epoll_pwait(int epfd, FAR struct epoll_event *evs,
int maxevents, int timeout, FAR const sigset_t *sigmask)
{
FAR struct file *filep;
FAR epoll_head_t *eph;
sigset_t oldsigmask;
int ret;
eph = epoll_head_from_fd(epfd);
eph = epoll_head_from_fd(epfd, &filep);
if (eph == NULL)
{
return ERROR;
@ -755,9 +759,11 @@ retry:
ret = num;
}
fs_putfilep(filep);
return ret;
err:
fs_putfilep(filep);
set_errno(-ret);
return ERROR;
}
@ -776,10 +782,11 @@ err:
int epoll_wait(int epfd, FAR struct epoll_event *evs,
int maxevents, int timeout)
{
FAR struct file *filep;
FAR epoll_head_t *eph;
int ret;
eph = epoll_head_from_fd(epfd);
eph = epoll_head_from_fd(epfd, &filep);
if (eph == NULL)
{
return ERROR;
@ -822,9 +829,11 @@ retry:
ret = num;
}
fs_putfilep(filep);
return ret;
err:
fs_putfilep(filep);
set_errno(-ret);
return ERROR;
}

View File

@ -60,6 +60,7 @@ static int fchstat(int fd, FAR struct stat *buf, int flags)
/* Perform the fchstat operation */
ret = file_fchstat(filep, buf, flags);
fs_putfilep(filep);
if (ret >= 0)
{
/* Successfully fchstat'ed the file */

View File

@ -350,13 +350,12 @@ int fcntl(int fd, int cmd, ...)
ret = fs_getfilep(fd, &filep);
if (ret >= 0)
{
DEBUGASSERT(filep != NULL);
/* Let file_vfcntl() do the real work. The errno is not set on
* failures.
*/
ret = file_vfcntl(filep, cmd, ap);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -236,7 +236,8 @@ int nx_fstat(int fd, FAR struct stat *buf)
{
/* Perform the fstat operation */
return file_fstat(filep, buf);
ret = file_fstat(filep, buf);
fs_putfilep(filep);
}
return ret;

View File

@ -72,22 +72,10 @@ int fstatfs(int fd, FAR struct statfs *buf)
goto errout;
}
DEBUGASSERT(filep != NULL);
/* Get the inode from the file structure */
inode = filep->f_inode;
DEBUGASSERT(inode != NULL);
/* Check if the file is open */
if (inode == NULL)
{
/* The descriptor does not refer to an open file. */
ret = -EBADF;
}
else
#ifndef CONFIG_DISABLE_MOUNTPOINT
/* The way we handle the stat depends on the type of inode that we
* are dealing with.
@ -121,6 +109,7 @@ int fstatfs(int fd, FAR struct statfs *buf)
/* Check if the fstat operation was successful */
fs_putfilep(filep);
if (ret >= 0)
{
/* Successfully statfs'ed the file */

View File

@ -110,11 +110,10 @@ int fsync(int fd)
goto errout;
}
DEBUGASSERT(filep != NULL);
/* Perform the fsync operation */
ret = file_fsync(filep);
fs_putfilep(filep);
if (ret < 0)
{
goto errout;

View File

@ -276,6 +276,7 @@ int ioctl(int fd, int req, ...)
ret = file_vioctl(filep, req, ap);
va_end(ap);
fs_putfilep(filep);
if (ret < 0)
{
goto err;

View File

@ -131,11 +131,11 @@ off_t nx_seek(int fd, off_t offset, int whence)
return ret;
}
DEBUGASSERT(filep != NULL);
/* Then let file_seek do the real work */
return file_seek(filep, offset, whence);
ret = file_seek(filep, offset, whence);
fs_putfilep(filep);
return ret;
}
/****************************************************************************

View File

@ -218,7 +218,9 @@ int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup)
/* Let file_poll() do the rest */
return file_poll(filep, fds, setup);
ret = file_poll(filep, fds, setup);
fs_putfilep(filep);
return ret;
}
/****************************************************************************

View File

@ -138,11 +138,10 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
goto errout;
}
DEBUGASSERT(filep != NULL);
/* Let file_pread do the real work */
ret = file_pread(filep, buf, nbytes, offset);
fs_putfilep(filep);
if (ret < 0)
{
goto errout;

View File

@ -144,6 +144,7 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset)
/* Let file_pwrite do the real work */
ret = file_pwrite(filep, buf, nbytes, offset);
fs_putfilep(filep);
if (ret < 0)
{
goto errout;

View File

@ -145,7 +145,9 @@ ssize_t nx_read(int fd, FAR void *buf, size_t nbytes)
/* Then let file_read do all of the work. */
return file_read(filep, buf, nbytes);
ret = file_read(filep, buf, nbytes);
fs_putfilep(filep);
return ret;
}
/****************************************************************************

View File

@ -342,10 +342,13 @@ ssize_t sendfile(int outfd, int infd, FAR off_t *offset, size_t count)
ret = fs_getfilep(infd, &infile);
if (ret < 0)
{
fs_putfilep(outfile);
goto errout;
}
ret = file_sendfile(outfile, infile, offset, count);
fs_putfilep(outfile);
fs_putfilep(infile);
if (ret < 0)
{
goto errout;

View File

@ -328,6 +328,7 @@ out:
int signalfd(int fd, FAR const sigset_t *mask, int flags)
{
FAR struct signalfd_priv_s *dev;
FAR struct file *filep = NULL;
struct sigaction act;
int ret = EINVAL;
int signo;
@ -360,8 +361,6 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
}
else
{
FAR struct file *filep;
if (fs_getfilep(fd, &filep) < 0)
{
ret = EBADF;
@ -370,6 +369,7 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
if (filep->f_inode->u.i_ops != &g_signalfd_fileops)
{
fs_putfilep(filep);
goto errout;
}
@ -397,6 +397,11 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
}
}
if (filep != NULL)
{
fs_putfilep(filep);
}
return fd;
errout_with_dev:

View File

@ -85,8 +85,8 @@ int syncfs(int fd)
ret = fs_getfilep(fd, &filep);
if (ret == OK)
{
DEBUGASSERT(filep != NULL);
ret = file_syncfs(filep);
fs_putfilep(filep);
}
leave_cancellation_point();

View File

@ -511,12 +511,9 @@ int timerfd_settime(int fd, int flags,
goto errout;
}
/* Check fd come from us */
if (!filep->f_inode || filep->f_inode->u.i_ops != &g_timerfd_fops)
if (filep->f_inode->u.i_ops != &g_timerfd_fops)
{
ret = -EINVAL;
goto errout;
goto errout_with_filep;
}
dev = (FAR struct timerfd_priv_s *)filep->f_priv;
@ -556,6 +553,7 @@ int timerfd_settime(int fd, int flags,
if (new_value->it_value.tv_sec <= 0 && new_value->it_value.tv_nsec <= 0)
{
leave_critical_section(intflags);
fs_putfilep(filep);
return OK;
}
@ -601,12 +599,15 @@ int timerfd_settime(int fd, int flags,
if (ret < 0)
{
leave_critical_section(intflags);
goto errout;
goto errout_with_filep;
}
leave_critical_section(intflags);
fs_putfilep(filep);
return OK;
errout_with_filep:
fs_putfilep(filep);
errout:
set_errno(-ret);
return ERROR;
@ -635,11 +636,9 @@ int timerfd_gettime(int fd, FAR struct itimerspec *curr_value)
goto errout;
}
/* Check fd come from us */
if (!filep->f_inode || filep->f_inode->u.i_ops != &g_timerfd_fops)
if (filep->f_inode->u.i_ops != &g_timerfd_fops)
{
ret = -EINVAL;
fs_putfilep(filep);
goto errout;
}
@ -653,6 +652,7 @@ int timerfd_gettime(int fd, FAR struct itimerspec *curr_value)
clock_ticks2time(&curr_value->it_value, ticks);
clock_ticks2time(&curr_value->it_interval, dev->delay);
fs_putfilep(filep);
return OK;
errout:

View File

@ -174,11 +174,10 @@ int ftruncate(int fd, off_t length)
goto errout;
}
DEBUGASSERT(filep != NULL);
/* Perform the truncate operation */
ret = file_truncate(filep, length);
fs_putfilep(filep);
if (ret >= 0)
{
return 0;

View File

@ -146,6 +146,7 @@ ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes)
*/
ret = file_write(filep, buf, nbytes);
fs_putfilep(filep);
}
return ret;

View File

@ -465,6 +465,7 @@ typedef struct cookie_io_functions_t
struct file
{
int f_oflags; /* Open mode flags */
int f_refs; /* Reference count */
off_t f_pos; /* File position */
FAR struct inode *f_inode; /* Driver or file system interface */
FAR void *f_priv; /* Per file driver private data */
@ -1151,6 +1152,21 @@ int nx_open(FAR const char *path, int oflags, ...);
int fs_getfilep(int fd, FAR struct file **filep);
/****************************************************************************
* Name: fs_putfilep
*
* Description:
* Release reference counts for files, less than or equal to 0 and close
* the file
*
* Input Parameters:
* filep - The caller provided location in which to return the 'struct
* file' instance.
*
****************************************************************************/
int fs_putfilep(FAR struct file *filep);
/****************************************************************************
* Name: file_close
*

View File

@ -597,7 +597,8 @@ int sockfd_allocate(FAR struct socket *psock, int oflags);
****************************************************************************/
FAR struct socket *file_socket(FAR struct file *filep);
int sockfd_socket(int sockfd, FAR struct socket **socketp);
int sockfd_socket(int sockfd, FAR struct file **filep,
FAR struct socket **socketp);
/****************************************************************************
* Name: psock_socket

View File

@ -120,11 +120,13 @@ static int local_sendctl(FAR struct local_conn_s *conn,
filep2 = kmm_zalloc(sizeof(*filep2));
if (!filep2)
{
fs_putfilep(filep);
ret = -ENOMEM;
goto fail;
}
ret = file_dup2(filep, filep2);
fs_putfilep(filep);
if (ret < 0)
{
kmm_free(filep2);

View File

@ -245,6 +245,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
{
FAR struct socket *psock = NULL;
FAR struct socket *newsock;
FAR struct file *filep;
int oflags = O_RDWR;
int errcode;
int newfd;
@ -262,7 +263,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Verify that the sockfd corresponds to valid, allocated socket */
@ -276,7 +277,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
if (newsock == NULL)
{
errcode = ENOMEM;
goto errout;
goto errout_with_filep;
}
ret = psock_accept(psock, addr, addrlen, newsock, flags);
@ -307,6 +308,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
goto errout_with_psock;
}
fs_putfilep(filep);
leave_cancellation_point();
return newfd;
@ -316,6 +318,9 @@ errout_with_psock:
errout_with_alloc:
kmm_free(newsock);
errout_with_filep:
fs_putfilep(filep);
errout:
leave_cancellation_point();

View File

@ -32,6 +32,7 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -151,17 +152,19 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr,
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Then let psock_bind do all of the work */
if (ret == OK)
{
ret = psock_bind(psock, addr, addrlen);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -35,6 +35,7 @@
#include <debug.h>
#include <nuttx/cancelpt.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -224,6 +225,7 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* accept() is a cancellation point */
@ -232,13 +234,14 @@ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Then let psock_connect() do all of the work */
if (ret == OK)
{
ret = psock_connect(psock, addr, addrlen);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -33,6 +33,7 @@
#include <errno.h>
#include <assert.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -147,17 +148,19 @@ int getpeername(int sockfd, FAR struct sockaddr *addr,
FAR socklen_t *addrlen)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Let psock_getpeername() do all of the work */
if (ret == OK)
{
ret = psock_getpeername(psock, addr, addrlen);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -33,6 +33,7 @@
#include <errno.h>
#include <assert.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -145,17 +146,19 @@ int getsockname(int sockfd, FAR struct sockaddr *addr,
FAR socklen_t *addrlen)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Let psock_getsockname() do all of the work */
if (ret == OK)
{
ret = psock_getsockname(psock, addr, addrlen);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -34,6 +34,8 @@
#include <assert.h>
#include <errno.h>
#include <nuttx/fs/fs.h>
#include "socket/socket.h"
#include "utils/utils.h"
@ -348,17 +350,19 @@ int getsockopt(int sockfd, int level, int option,
void *value, socklen_t *value_len)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Then let psock_getsockopt() do all of the work */
if (ret == OK)
{
ret = psock_getsockopt(psock, level, option, value, value_len);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -140,11 +140,12 @@ int psock_listen(FAR struct socket *psock, int backlog)
int listen(int sockfd, int backlog)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* The let psock_listen to the work. If psock_listen() fails, it will have
* set the errno variable.
@ -153,6 +154,7 @@ int listen(int sockfd, int backlog)
if (ret == OK)
{
ret = psock_listen(psock, backlog);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -155,6 +155,7 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
FAR struct sockaddr *from, FAR socklen_t *fromlen)
{
FAR struct socket *psock;
FAR struct file *filep;
ssize_t ret;
#ifdef CONFIG_BUILD_KERNEL
struct sockaddr_storage kaddr;
@ -192,13 +193,14 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Then let psock_recvfrom() do all of the work */
if (ret == OK)
{
ret = psock_recvfrom(psock, buf, len, flags, from, fromlen);
fs_putfilep(filep);
}
#ifdef CONFIG_BUILD_KERNEL

View File

@ -30,6 +30,7 @@
#include <errno.h>
#include <nuttx/cancelpt.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -167,6 +168,7 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
{
FAR struct socket *psock;
FAR struct file *filep;
ssize_t ret;
/* recvmsg() is a cancellation point */
@ -175,13 +177,14 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Let psock_recvmsg() do all of the work */
if (ret == OK)
{
ret = psock_recvmsg(psock, msg, flags);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -30,6 +30,7 @@
#include <errno.h>
#include <nuttx/cancelpt.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -141,6 +142,7 @@ ssize_t psock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
{
FAR struct socket *psock;
FAR struct file *filep;
ssize_t ret;
/* sendmsg() is a cancellation point */
@ -149,13 +151,14 @@ ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Let psock_sendmsg() do all of the work */
if (ret == OK)
{
ret = psock_sendmsg(psock, msg, flags);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -201,6 +201,7 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
FAR const struct sockaddr *to, socklen_t tolen)
{
FAR struct socket *psock;
FAR struct file *filep;
ssize_t ret;
#ifdef CONFIG_BUILD_KERNEL
struct sockaddr_storage kaddr;
@ -237,13 +238,14 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* And let psock_sendto do all of the work */
if (ret == OK)
{
ret = psock_sendto(psock, buf, len, flags, to, tolen);
fs_putfilep(filep);
}
#ifdef CONFIG_BUILD_KERNEL

View File

@ -35,6 +35,7 @@
#include <assert.h>
#include <arch/irq.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netdev.h>
#include <netdev/netdev.h>
@ -385,17 +386,19 @@ int setsockopt(int sockfd, int level, int option, const void *value,
socklen_t value_len)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Then let psock_setockopt() do all of the work */
if (ret == OK)
{
ret = psock_setsockopt(psock, level, option, value, value_len);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -29,6 +29,7 @@
#include <errno.h>
#include <sys/socket.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include "socket/socket.h"
@ -128,17 +129,19 @@ int psock_shutdown(FAR struct socket *psock, int how)
int shutdown(int sockfd, int how)
{
FAR struct socket *psock;
FAR struct file *filep;
int ret;
/* Get the underlying socket structure */
ret = sockfd_socket(sockfd, &psock);
ret = sockfd_socket(sockfd, &filep, &psock);
/* Then let psock_shutdown() do all of the work */
if (ret == OK)
{
ret = psock_shutdown(psock, how);
fs_putfilep(filep);
}
if (ret < 0)

View File

@ -106,18 +106,16 @@ int mq_getattr(mqd_t mqdes, struct mq_attr *mq_stat)
int ret;
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
if (ret >= 0)
{
set_errno(-ret);
return ERROR;
ret = file_mq_getattr(filep, mq_stat);
fs_putfilep(filep);
if (ret >= 0)
{
return OK;
}
}
ret = file_mq_getattr(filep, mq_stat);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
return OK;
set_errno(-ret);
return ERROR;
}

View File

@ -115,12 +115,12 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
/* Was a valid message queue descriptor provided? */
if (!inode || !inode->i_private)
if (!inode->i_private)
{
/* No.. return EBADF */
errval = EBADF;
goto errout_without_lock;
goto errout_with_filep;
}
/* Get a pointer to the message queue */
@ -184,11 +184,15 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
}
leave_critical_section(flags);
fs_putfilep(filep);
return OK;
errout:
leave_critical_section(flags);
errout_with_filep:
fs_putfilep(filep);
errout_without_lock:
set_errno(errval);
return ERROR;

View File

@ -153,7 +153,7 @@ ssize_t nxmq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
FAR unsigned int *prio)
{
FAR struct file *filep;
int ret;
ssize_t ret;
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
@ -161,7 +161,9 @@ ssize_t nxmq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
return ret;
}
return file_mq_receive(filep, msg, msglen, prio);
ret = file_mq_receive(filep, msg, msglen, prio);
fs_putfilep(filep);
return ret;
}
/****************************************************************************

View File

@ -181,7 +181,9 @@ int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
return ret;
}
return file_mq_send(filep, msg, msglen, prio);
ret = file_mq_send(filep, msg, msglen, prio);
fs_putfilep(filep);
return ret;
}
/****************************************************************************

View File

@ -118,18 +118,16 @@ int mq_setattr(mqd_t mqdes, const struct mq_attr *mq_stat,
int ret;
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
if (ret >= 0)
{
set_errno(-ret);
return ERROR;
ret = file_mq_setattr(filep, mq_stat, oldstat);
fs_putfilep(filep);
if (ret >= 0)
{
return OK;
}
}
ret = file_mq_setattr(filep, mq_stat, oldstat);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
return OK;
set_errno(-ret);
return ERROR;
}

View File

@ -357,7 +357,7 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
FAR const struct timespec *abstime)
{
FAR struct file *filep;
int ret;
ssize_t ret;
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
@ -365,7 +365,9 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
return ret;
}
return file_mq_timedreceive_internal(filep, msg, msglen, prio, abstime, 0);
ret = file_mq_timedreceive_internal(filep, msg, msglen, prio, abstime, 0);
fs_putfilep(filep);
return ret;
}
/****************************************************************************

View File

@ -437,7 +437,9 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
return ret;
}
return file_mq_timedsend_internal(filep, msg, msglen, prio, abstime, 0);
ret = file_mq_timedsend_internal(filep, msg, msglen, prio, abstime, 0);
fs_putfilep(filep);
return ret;
}
/****************************************************************************