From 43223124ec3dd26ad295d6c49298994adfbeabe9 Mon Sep 17 00:00:00 2001 From: Shoukui Zhang Date: Mon, 25 Dec 2023 15:04:01 +0800 Subject: [PATCH] vfs/file: add reference counting to prevent accidental close during reading writing... Signed-off-by: Shoukui Zhang --- audio/audio.c | 1 + drivers/net/telnet.c | 4 +- fs/aio/aioc_contain.c | 42 ++++++----- fs/inode/fs_files.c | 123 ++++++++++++++++++++++++++++----- fs/mmap/fs_mmap.c | 5 ++ fs/notify/inotify.c | 22 +++--- fs/procfs/fs_procfsproc.c | 3 +- fs/socket/socket.c | 16 +++-- fs/vfs/fs_dup.c | 4 +- fs/vfs/fs_epoll.c | 25 ++++--- fs/vfs/fs_fchstat.c | 1 + fs/vfs/fs_fcntl.c | 3 +- fs/vfs/fs_fstat.c | 3 +- fs/vfs/fs_fstatfs.c | 13 +--- fs/vfs/fs_fsync.c | 3 +- fs/vfs/fs_ioctl.c | 1 + fs/vfs/fs_lseek.c | 6 +- fs/vfs/fs_poll.c | 4 +- fs/vfs/fs_pread.c | 3 +- fs/vfs/fs_pwrite.c | 1 + fs/vfs/fs_read.c | 4 +- fs/vfs/fs_sendfile.c | 3 + fs/vfs/fs_signalfd.c | 9 ++- fs/vfs/fs_syncfs.c | 2 +- fs/vfs/fs_timerfd.c | 20 +++--- fs/vfs/fs_truncate.c | 3 +- fs/vfs/fs_write.c | 1 + include/nuttx/fs/fs.h | 16 +++++ include/nuttx/net/net.h | 3 +- net/local/local_sendmsg.c | 2 + net/socket/accept.c | 9 ++- net/socket/bind.c | 5 +- net/socket/connect.c | 5 +- net/socket/getpeername.c | 5 +- net/socket/getsockname.c | 5 +- net/socket/getsockopt.c | 6 +- net/socket/listen.c | 4 +- net/socket/recvfrom.c | 4 +- net/socket/recvmsg.c | 5 +- net/socket/sendmsg.c | 5 +- net/socket/sendto.c | 4 +- net/socket/setsockopt.c | 5 +- net/socket/shutdown.c | 5 +- sched/mqueue/mq_getattr.c | 20 +++--- sched/mqueue/mq_notify.c | 8 ++- sched/mqueue/mq_receive.c | 6 +- sched/mqueue/mq_send.c | 4 +- sched/mqueue/mq_setattr.c | 20 +++--- sched/mqueue/mq_timedreceive.c | 6 +- sched/mqueue/mq_timedsend.c | 4 +- 50 files changed, 335 insertions(+), 146 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index f521375dec..306eaa5ff9 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -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; } diff --git a/drivers/net/telnet.c b/drivers/net/telnet.c index d0a5d74bca..52f743edf7 100644 --- a/drivers/net/telnet.c +++ b/drivers/net/telnet.c @@ -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); diff --git a/fs/aio/aioc_contain.c b/fs/aio/aioc_contain.c index 3c788890f5..42cb5424a0 100644 --- a/fs/aio/aioc_contain.c +++ b/fs/aio/aioc_contain.c @@ -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, ¶m)); - aioc->aioc_prio = param.sched_priority; + DEBUGVERIFY(nxsched_get_param(aioc->aioc_pid, ¶m)); + 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(); diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index e035264dfb..12ad5007e1 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -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); } /**************************************************************************** diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c index 5d44e604f8..a6e92bb7a8 100644 --- a/fs/mmap/fs_mmap.c +++ b/fs/mmap/fs_mmap.c @@ -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; diff --git a/fs/notify/inotify.c b/fs/notify/inotify.c index 84f20853e3..5b22cfd8e3 100644 --- a/fs/notify/inotify.c +++ b/fs/notify/inotify.c @@ -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; } diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index acf8c39331..2c7f8b6a9b 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -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); diff --git a/fs/socket/socket.c b/fs/socket/socket.c index eb80a9ebc8..3675988e7a 100644 --- a/fs/socket/socket.c +++ b/fs/socket/socket.c @@ -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; } diff --git a/fs/vfs/fs_dup.c b/fs/vfs/fs_dup.c index 4736dab1d9..f9178b6531 100644 --- a/fs/vfs/fs_dup.c +++ b/fs/vfs/fs_dup.c @@ -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; diff --git a/fs/vfs/fs_epoll.c b/fs/vfs/fs_epoll.c index 5b880fc35d..cf612b0a0a 100644 --- a/fs/vfs/fs_epoll.c +++ b/fs/vfs/fs_epoll.c @@ -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; } diff --git a/fs/vfs/fs_fchstat.c b/fs/vfs/fs_fchstat.c index ddcf2af011..ff65818b6f 100644 --- a/fs/vfs/fs_fchstat.c +++ b/fs/vfs/fs_fchstat.c @@ -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 */ diff --git a/fs/vfs/fs_fcntl.c b/fs/vfs/fs_fcntl.c index c87417376b..44bdcd6652 100644 --- a/fs/vfs/fs_fcntl.c +++ b/fs/vfs/fs_fcntl.c @@ -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) diff --git a/fs/vfs/fs_fstat.c b/fs/vfs/fs_fstat.c index 08d7188792..a3cb38df7b 100644 --- a/fs/vfs/fs_fstat.c +++ b/fs/vfs/fs_fstat.c @@ -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; diff --git a/fs/vfs/fs_fstatfs.c b/fs/vfs/fs_fstatfs.c index ce010110cc..ab972598d6 100644 --- a/fs/vfs/fs_fstatfs.c +++ b/fs/vfs/fs_fstatfs.c @@ -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 */ diff --git a/fs/vfs/fs_fsync.c b/fs/vfs/fs_fsync.c index 6093c6710f..44a47fcb5a 100644 --- a/fs/vfs/fs_fsync.c +++ b/fs/vfs/fs_fsync.c @@ -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; diff --git a/fs/vfs/fs_ioctl.c b/fs/vfs/fs_ioctl.c index ecc3789583..2f9488c4c2 100644 --- a/fs/vfs/fs_ioctl.c +++ b/fs/vfs/fs_ioctl.c @@ -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; diff --git a/fs/vfs/fs_lseek.c b/fs/vfs/fs_lseek.c index 3bae28992e..847ae9140f 100644 --- a/fs/vfs/fs_lseek.c +++ b/fs/vfs/fs_lseek.c @@ -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; } /**************************************************************************** diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 09c3ae35f6..ba5f1a9920 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -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; } /**************************************************************************** diff --git a/fs/vfs/fs_pread.c b/fs/vfs/fs_pread.c index 7ab9c9314f..5333b7f325 100644 --- a/fs/vfs/fs_pread.c +++ b/fs/vfs/fs_pread.c @@ -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; diff --git a/fs/vfs/fs_pwrite.c b/fs/vfs/fs_pwrite.c index 75a31d7a21..cd75b5f79e 100644 --- a/fs/vfs/fs_pwrite.c +++ b/fs/vfs/fs_pwrite.c @@ -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; diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c index 0218158d67..edb5574419 100644 --- a/fs/vfs/fs_read.c +++ b/fs/vfs/fs_read.c @@ -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; } /**************************************************************************** diff --git a/fs/vfs/fs_sendfile.c b/fs/vfs/fs_sendfile.c index 93b7772bd8..afd2eb2b76 100644 --- a/fs/vfs/fs_sendfile.c +++ b/fs/vfs/fs_sendfile.c @@ -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; diff --git a/fs/vfs/fs_signalfd.c b/fs/vfs/fs_signalfd.c index 174b208c56..64f9cd61b3 100644 --- a/fs/vfs/fs_signalfd.c +++ b/fs/vfs/fs_signalfd.c @@ -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: diff --git a/fs/vfs/fs_syncfs.c b/fs/vfs/fs_syncfs.c index 12c328dc10..2403228986 100644 --- a/fs/vfs/fs_syncfs.c +++ b/fs/vfs/fs_syncfs.c @@ -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(); diff --git a/fs/vfs/fs_timerfd.c b/fs/vfs/fs_timerfd.c index 41b6d67214..3b550d16be 100644 --- a/fs/vfs/fs_timerfd.c +++ b/fs/vfs/fs_timerfd.c @@ -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: diff --git a/fs/vfs/fs_truncate.c b/fs/vfs/fs_truncate.c index 2f11c17ec9..827070774c 100644 --- a/fs/vfs/fs_truncate.c +++ b/fs/vfs/fs_truncate.c @@ -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; diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c index df3f203b1c..6849763a67 100644 --- a/fs/vfs/fs_write.c +++ b/fs/vfs/fs_write.c @@ -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; diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 6e600c3827..b52de68433 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -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 * diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 5c7daf4a29..a01e1e11f8 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -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 diff --git a/net/local/local_sendmsg.c b/net/local/local_sendmsg.c index 7fb4be29e2..0e8e67ff3f 100644 --- a/net/local/local_sendmsg.c +++ b/net/local/local_sendmsg.c @@ -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); diff --git a/net/socket/accept.c b/net/socket/accept.c index 60e52f2841..74463935f8 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -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(); diff --git a/net/socket/bind.c b/net/socket/bind.c index 23b9f9007b..80bbdbd4fb 100644 --- a/net/socket/bind.c +++ b/net/socket/bind.c @@ -32,6 +32,7 @@ #include #include +#include #include #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) diff --git a/net/socket/connect.c b/net/socket/connect.c index 0b7ae98bfa..5fa85a2ad8 100644 --- a/net/socket/connect.c +++ b/net/socket/connect.c @@ -35,6 +35,7 @@ #include #include +#include #include #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) diff --git a/net/socket/getpeername.c b/net/socket/getpeername.c index 0460a178af..d405560cf2 100644 --- a/net/socket/getpeername.c +++ b/net/socket/getpeername.c @@ -33,6 +33,7 @@ #include #include +#include #include #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) diff --git a/net/socket/getsockname.c b/net/socket/getsockname.c index 0a8e7c1aaf..edc2afb1c2 100644 --- a/net/socket/getsockname.c +++ b/net/socket/getsockname.c @@ -33,6 +33,7 @@ #include #include +#include #include #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) diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c index 790c019f87..d238023b4a 100644 --- a/net/socket/getsockopt.c +++ b/net/socket/getsockopt.c @@ -34,6 +34,8 @@ #include #include +#include + #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) diff --git a/net/socket/listen.c b/net/socket/listen.c index 480681c2b1..1ad095def7 100644 --- a/net/socket/listen.c +++ b/net/socket/listen.c @@ -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) diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c index 852aef7c79..0695499401 100644 --- a/net/socket/recvfrom.c +++ b/net/socket/recvfrom.c @@ -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 diff --git a/net/socket/recvmsg.c b/net/socket/recvmsg.c index 658f244e61..e4d880ed53 100644 --- a/net/socket/recvmsg.c +++ b/net/socket/recvmsg.c @@ -30,6 +30,7 @@ #include #include +#include #include #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) diff --git a/net/socket/sendmsg.c b/net/socket/sendmsg.c index 9a905df534..d22aaa1d1f 100644 --- a/net/socket/sendmsg.c +++ b/net/socket/sendmsg.c @@ -30,6 +30,7 @@ #include #include +#include #include #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) diff --git a/net/socket/sendto.c b/net/socket/sendto.c index 6f59de7a73..d83e5f5b55 100644 --- a/net/socket/sendto.c +++ b/net/socket/sendto.c @@ -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 diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c index 00ae203f87..23356658ec 100644 --- a/net/socket/setsockopt.c +++ b/net/socket/setsockopt.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -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) diff --git a/net/socket/shutdown.c b/net/socket/shutdown.c index 0947a0aaf1..f160b25156 100644 --- a/net/socket/shutdown.c +++ b/net/socket/shutdown.c @@ -29,6 +29,7 @@ #include #include +#include #include #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) diff --git a/sched/mqueue/mq_getattr.c b/sched/mqueue/mq_getattr.c index 3dc15a7bfe..09fce68af2 100644 --- a/sched/mqueue/mq_getattr.c +++ b/sched/mqueue/mq_getattr.c @@ -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; } diff --git a/sched/mqueue/mq_notify.c b/sched/mqueue/mq_notify.c index a218a9d702..eceba33b9d 100644 --- a/sched/mqueue/mq_notify.c +++ b/sched/mqueue/mq_notify.c @@ -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; diff --git a/sched/mqueue/mq_receive.c b/sched/mqueue/mq_receive.c index 1559ae9339..ef14880ec7 100644 --- a/sched/mqueue/mq_receive.c +++ b/sched/mqueue/mq_receive.c @@ -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; } /**************************************************************************** diff --git a/sched/mqueue/mq_send.c b/sched/mqueue/mq_send.c index 952467a3dc..fb20eab5ce 100644 --- a/sched/mqueue/mq_send.c +++ b/sched/mqueue/mq_send.c @@ -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; } /**************************************************************************** diff --git a/sched/mqueue/mq_setattr.c b/sched/mqueue/mq_setattr.c index 5017694d49..777a9c46f3 100644 --- a/sched/mqueue/mq_setattr.c +++ b/sched/mqueue/mq_setattr.c @@ -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; } diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c index bc3caa9906..08c242f7f8 100644 --- a/sched/mqueue/mq_timedreceive.c +++ b/sched/mqueue/mq_timedreceive.c @@ -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; } /**************************************************************************** diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c index 9ece7d3a9a..c8394ad9a6 100644 --- a/sched/mqueue/mq_timedsend.c +++ b/sched/mqueue/mq_timedsend.c @@ -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; } /****************************************************************************