From 081c2337b7e4d68ac3341aa5d0e033be93d473b1 Mon Sep 17 00:00:00 2001 From: liamHowatt Date: Tue, 30 Dec 2025 14:05:46 +0000 Subject: [PATCH] fs/userfs: keep lock while reading iobuffer Fix a race on userfs_state_s iobuffer. 1. Task 1 takes the mutex and does a userfs operation. 2. A higher priority task 2 blocks on the mutex. 3. Task 1 releases the mutex when finished. The iobuffer response has not been processed by task 1 yet, but task 2 is higher priority and control switches to it. 4. Task 2 does a userfs operation and releases the mutex. The iobuffer now contains task 2's response. 5. Control returns to task 1 for it to check the iobuffer response. It contains task 2's response, not its own. Fix it by releasing the mutex only after the exclusive iobuffer usage lifecycle is complete. Signed-off-by: liamHowatt --- fs/userfs/fs_userfs.c | 236 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 190 insertions(+), 46 deletions(-) diff --git a/fs/userfs/fs_userfs.c b/fs/userfs/fs_userfs.c index 8386cc8b623..bc820bd0ff2 100644 --- a/fs/userfs/fs_userfs.c +++ b/fs/userfs/fs_userfs.c @@ -259,17 +259,18 @@ static int userfs_open(FAR struct file *filep, FAR const char *relpath, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_open_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -279,11 +280,16 @@ static int userfs_open(FAR struct file *filep, FAR const char *relpath, if (resp->resp != USERFS_RESP_OPEN) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } filep->f_priv = resp->openinfo; - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -333,17 +339,18 @@ static int userfs_close(FAR struct file *filep) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_close_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -351,6 +358,7 @@ static int userfs_close(FAR struct file *filep) if (resp->resp != USERFS_RESP_CLOSE) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -359,7 +367,11 @@ static int userfs_close(FAR struct file *filep) filep->f_priv = NULL; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -375,6 +387,7 @@ static ssize_t userfs_read(FAR struct file *filep, char *buffer, ssize_t nsent; ssize_t nrecvd; int respsize; + ssize_t nread; int ret; finfo("Read %zu bytes from offset %jd\n", buflen, (intmax_t)filep->f_pos); @@ -414,17 +427,18 @@ static ssize_t userfs_read(FAR struct file *filep, char *buffer, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd < SIZEOF_USERFS_READ_RESPONSE_S(0)) { ferr("ERROR: Response too small: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -432,12 +446,14 @@ static ssize_t userfs_read(FAR struct file *filep, char *buffer, if (resp->resp != USERFS_RESP_READ) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } if (resp->nread > buflen) { ferr("ERROR: Response size too large: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -445,13 +461,18 @@ static ssize_t userfs_read(FAR struct file *filep, char *buffer, if (respsize != nrecvd) { ferr("ERROR: Incorrect response size: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } /* Copy the received data to the user buffer */ memcpy(buffer, resp->rddata, resp->nread); - return resp->nread; + nread = resp->nread; + + nxmutex_unlock(&priv->lock); + + return nread; } /**************************************************************************** @@ -466,6 +487,7 @@ static ssize_t userfs_write(FAR struct file *filep, FAR const char *buffer, FAR struct userfs_write_response_s *resp; ssize_t nsent; ssize_t nrecvd; + ssize_t nwritten; int ret; finfo("Write %zu bytes to offset %jd\n", buflen, (intmax_t)filep->f_pos); @@ -515,17 +537,18 @@ static ssize_t userfs_write(FAR struct file *filep, FAR const char *buffer, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_write_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -533,10 +556,15 @@ static ssize_t userfs_write(FAR struct file *filep, FAR const char *buffer, if (resp->resp != USERFS_RESP_WRITE) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->nwritten; + nwritten = resp->nwritten; + + nxmutex_unlock(&priv->lock); + + return nwritten; } /**************************************************************************** @@ -550,6 +578,7 @@ static off_t userfs_seek(FAR struct file *filep, off_t offset, int whence) FAR struct userfs_seek_response_s *resp; ssize_t nsent; ssize_t nrecvd; + off_t off_ret; int ret; finfo("Offset %lu bytes to whence=%d\n", (unsigned long)offset, whence); @@ -590,17 +619,18 @@ static off_t userfs_seek(FAR struct file *filep, off_t offset, int whence) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_seek_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -608,10 +638,15 @@ static off_t userfs_seek(FAR struct file *filep, off_t offset, int whence) if (resp->resp != USERFS_RESP_SEEK) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + off_ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return off_ret; } /**************************************************************************** @@ -665,17 +700,18 @@ static int userfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_ioctl_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -683,10 +719,15 @@ static int userfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) if (resp->resp != USERFS_RESP_IOCTL) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -736,17 +777,18 @@ static int userfs_sync(FAR struct file *filep) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_sync_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -754,10 +796,15 @@ static int userfs_sync(FAR struct file *filep) if (resp->resp != USERFS_RESP_SYNC) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -813,17 +860,18 @@ static int userfs_dup(FAR const struct file *oldp, FAR struct file *newp) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_dup_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -831,11 +879,16 @@ static int userfs_dup(FAR const struct file *oldp, FAR struct file *newp) if (resp->resp != USERFS_RESP_DUP) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } newp->f_priv = resp->openinfo; - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -890,17 +943,18 @@ static int userfs_fstat(FAR const struct file *filep, FAR struct stat *buf) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_fstat_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -908,6 +962,7 @@ static int userfs_fstat(FAR const struct file *filep, FAR struct stat *buf) if (resp->resp != USERFS_RESP_FSTAT) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -915,7 +970,11 @@ static int userfs_fstat(FAR const struct file *filep, FAR struct stat *buf) DEBUGASSERT(buf != NULL); memcpy(buf, &resp->buf, sizeof(struct stat)); - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -973,17 +1032,18 @@ static int userfs_fchstat(FAR const struct file *filep, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %zd\n", nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_fchstat_response_s)) { ferr("ERROR: Response size incorrect: %zd\n", nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -991,10 +1051,15 @@ static int userfs_fchstat(FAR const struct file *filep, if (resp->resp != USERFS_RESP_FCHSTAT) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1049,17 +1114,18 @@ static int userfs_truncate(FAR struct file *filep, off_t length) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_truncate_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1067,12 +1133,17 @@ static int userfs_truncate(FAR struct file *filep, off_t length) if (resp->resp != USERFS_RESP_FSTAT) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } /* Return the result of truncate operation */ - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1140,17 +1211,18 @@ static int userfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_opendir_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1158,6 +1230,7 @@ static int userfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, if (resp->resp != USERFS_RESP_OPENDIR) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1167,12 +1240,17 @@ static int userfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, udir = fs_heap_zalloc(sizeof(struct userfs_dir_s)); if (udir == NULL) { + nxmutex_unlock(&priv->lock); return -ENOMEM; } udir->dir = resp->dir; *dir = (FAR struct fs_dirent_s *)udir; - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1228,17 +1306,18 @@ static int userfs_closedir(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_closedir_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1246,11 +1325,16 @@ static int userfs_closedir(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_CLOSEDIR) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } fs_heap_free(udir); - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1306,17 +1390,18 @@ static int userfs_readdir(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_readdir_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1324,6 +1409,7 @@ static int userfs_readdir(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_READDIR) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1331,7 +1417,11 @@ static int userfs_readdir(FAR struct inode *mountpt, DEBUGASSERT(dir != NULL); memcpy(entry, &resp->entry, sizeof(struct dirent)); - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1386,17 +1476,18 @@ static int userfs_rewinddir(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_rewinddir_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1404,10 +1495,15 @@ static int userfs_rewinddir(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_REWINDDIR) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1548,17 +1644,18 @@ static int userfs_unbind(FAR void *handle, FAR struct inode **blkdriver, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_destroy_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1566,6 +1663,7 @@ static int userfs_unbind(FAR void *handle, FAR struct inode **blkdriver, if (resp->resp != USERFS_RESP_DESTROY) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1573,9 +1671,13 @@ static int userfs_unbind(FAR void *handle, FAR struct inode **blkdriver, if (resp->ret < 0) { - return resp->ret; + ret = resp->ret; + nxmutex_unlock(&priv->lock); + return ret; } + nxmutex_unlock(&priv->lock); + /* Free resources and return success */ psock_close(&priv->psock); @@ -1633,17 +1735,18 @@ static int userfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf) nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_statfs_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1651,6 +1754,7 @@ static int userfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf) if (resp->resp != USERFS_RESP_STATFS) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1658,7 +1762,11 @@ static int userfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf) DEBUGASSERT(buf != NULL); memcpy(buf, &resp->buf, sizeof(struct statfs)); - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1723,17 +1831,18 @@ static int userfs_unlink(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_unlink_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1741,10 +1850,15 @@ static int userfs_unlink(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_UNLINK) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1810,17 +1924,18 @@ static int userfs_mkdir(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_mkdir_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1828,10 +1943,15 @@ static int userfs_mkdir(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_MKDIR) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1896,17 +2016,18 @@ static int userfs_rmdir(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_rmdir_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -1914,10 +2035,15 @@ static int userfs_rmdir(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_RMDIR) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -1988,17 +2114,18 @@ static int userfs_rename(FAR struct inode *mountpt, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_rename_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -2006,10 +2133,15 @@ static int userfs_rename(FAR struct inode *mountpt, if (resp->resp != USERFS_RESP_RENAME) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -2074,17 +2206,18 @@ static int userfs_stat(FAR struct inode *mountpt, FAR const char *relpath, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %d\n", (int)nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_stat_response_s)) { ferr("ERROR: Response size incorrect: %u\n", (unsigned int)nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -2092,6 +2225,7 @@ static int userfs_stat(FAR struct inode *mountpt, FAR const char *relpath, if (resp->resp != USERFS_RESP_STAT) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -2099,7 +2233,11 @@ static int userfs_stat(FAR struct inode *mountpt, FAR const char *relpath, DEBUGASSERT(buf != NULL); memcpy(buf, &resp->buf, sizeof(struct stat)); - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /**************************************************************************** @@ -2166,17 +2304,18 @@ static int userfs_chstat(FAR struct inode *mountpt, FAR const char *relpath, nrecvd = psock_recvfrom(&priv->psock, priv->iobuffer, IOBUFFER_SIZE(priv), 0, NULL, NULL); - nxmutex_unlock(&priv->lock); if (nrecvd < 0) { ferr("ERROR: psock_recvfrom failed: %zd\n", nrecvd); + nxmutex_unlock(&priv->lock); return (int)nrecvd; } if (nrecvd != sizeof(struct userfs_chstat_response_s)) { ferr("ERROR: Response size incorrect: %zd\n", nrecvd); + nxmutex_unlock(&priv->lock); return -EIO; } @@ -2184,10 +2323,15 @@ static int userfs_chstat(FAR struct inode *mountpt, FAR const char *relpath, if (resp->resp != USERFS_RESP_STAT) { ferr("ERROR: Incorrect response: %u\n", resp->resp); + nxmutex_unlock(&priv->lock); return -EIO; } - return resp->ret; + ret = resp->ret; + + nxmutex_unlock(&priv->lock); + + return ret; } /****************************************************************************