From a1e3444df0ad93d31cbcad672694399de2e255a4 Mon Sep 17 00:00:00 2001 From: chenrun1 Date: Mon, 13 May 2024 20:21:18 +0800 Subject: [PATCH] rpmsgfs:Support cross-core access using file locks on the same file Signed-off-by: chenrun1 --- fs/rpmsgfs/rpmsgfs_client.c | 54 ++++++++++++++++++++++++------------- fs/rpmsgfs/rpmsgfs_server.c | 14 ++++++++-- fs/vfs/fs_fcntl.c | 18 ++++++++++--- include/nuttx/fs/ioctl.h | 10 +++++++ 4 files changed, 73 insertions(+), 23 deletions(-) diff --git a/fs/rpmsgfs/rpmsgfs_client.c b/fs/rpmsgfs/rpmsgfs_client.c index df285ce40e..c4b9c82d48 100644 --- a/fs/rpmsgfs/rpmsgfs_client.c +++ b/fs/rpmsgfs/rpmsgfs_client.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -392,6 +393,10 @@ static ssize_t rpmsgfs_ioctl_arglen(int cmd) case FIONWRITE: case FIONREAD: return sizeof(int); + case FIOC_SETLK: + case FIOC_GETLK: + case FIOC_SETLKW: + return sizeof(struct flock); default: return -ENOTTY; } @@ -576,6 +581,7 @@ int rpmsgfs_client_ioctl(FAR void *handle, int fd, FAR struct rpmsgfs_ioctl_s *msg; uint32_t space; size_t len; + int ret; if (arglen < 0) { @@ -583,27 +589,39 @@ int rpmsgfs_client_ioctl(FAR void *handle, int fd, } len = sizeof(*msg) + arglen; - msg = rpmsgfs_get_tx_payload_buffer(priv, &space); - if (msg == NULL) + + while (1) { - return -ENOMEM; + msg = rpmsgfs_get_tx_payload_buffer(priv, &space); + if (msg == NULL) + { + return -ENOMEM; + } + + DEBUGASSERT(len <= space); + + msg->fd = fd; + msg->request = request == FIOC_SETLKW ? FIOC_SETLK : request; + msg->arg = arg; + msg->arglen = arglen; + + if (arglen > 0) + { + memcpy(msg->buf, (FAR void *)(uintptr_t)arg, arglen); + } + + ret = rpmsgfs_send_recv(handle, RPMSGFS_IOCTL, false, + (FAR struct rpmsgfs_header_s *)msg, len, + arglen > 0 ? (FAR void *)arg : NULL); + if (request != FIOC_SETLKW || ret != -EAGAIN) + { + break; + } + + usleep(20000); } - DEBUGASSERT(len <= space); - - msg->fd = fd; - msg->request = request; - msg->arg = arg; - msg->arglen = arglen; - - if (arglen > 0) - { - memcpy(msg->buf, (FAR void *)(uintptr_t)arg, arglen); - } - - return rpmsgfs_send_recv(handle, RPMSGFS_IOCTL, false, - (FAR struct rpmsgfs_header_s *)msg, len, - arglen > 0 ? (FAR void *)arg : NULL); + return ret; } void rpmsgfs_client_sync(FAR void *handle, int fd) diff --git a/fs/rpmsgfs/rpmsgfs_server.c b/fs/rpmsgfs/rpmsgfs_server.c index 775b1452f3..ce402d397b 100644 --- a/fs/rpmsgfs/rpmsgfs_server.c +++ b/fs/rpmsgfs/rpmsgfs_server.c @@ -479,8 +479,18 @@ static int rpmsgfs_ioctl_handler(FAR struct rpmsg_endpoint *ept, filep = rpmsgfs_get_file(priv, msg->fd); if (filep != NULL) { - ret = file_ioctl(filep, msg->request, msg->arglen > 0 ? - (unsigned long)msg->buf : msg->arg); + unsigned long arg; + + arg = msg->arglen > 0 ? (unsigned long)msg->buf : msg->arg; + switch (msg->request) + { + case FIOC_SETLK: + case FIOC_GETLK: + ret = file_fcntl(filep, msg->request, arg); + break; + default: + ret = file_ioctl(filep, msg->request, arg); + } } msg->header.result = ret; diff --git a/fs/vfs/fs_fcntl.c b/fs/vfs/fs_fcntl.c index 925a605e89..e81fde69ba 100644 --- a/fs/vfs/fs_fcntl.c +++ b/fs/vfs/fs_fcntl.c @@ -198,7 +198,11 @@ static int file_vfcntl(FAR struct file *filep, int cmd, va_list ap) { FAR struct flock *flock = va_arg(ap, FAR struct flock *); - ret = file_getlk(filep, flock); + ret = file_ioctl(filep, FIOC_GETLK, flock); + if (ret < 0) + { + ret = file_getlk(filep, flock); + } } break; @@ -215,7 +219,11 @@ static int file_vfcntl(FAR struct file *filep, int cmd, va_list ap) { FAR struct flock *flock = va_arg(ap, FAR struct flock *); - ret = file_setlk(filep, flock, true); + ret = file_ioctl(filep, FIOC_SETLK, flock); + if (ret < 0) + { + ret = file_setlk(filep, flock, true); + } } break; @@ -231,7 +239,11 @@ static int file_vfcntl(FAR struct file *filep, int cmd, va_list ap) { FAR struct flock *flock = va_arg(ap, FAR struct flock *); - ret = file_setlk(filep, flock, false); + ret = file_ioctl(filep, FIOC_SETLKW, flock); + if (ret < 0) + { + ret = file_setlk(filep, flock, false); + } } break; diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index e2aed08481..7e5a6951ab 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -213,6 +213,16 @@ */ #endif +#define FIOC_SETLK _FIOC(0x0012) /* IN: Pointer to flock + * OUT: None + */ +#define FIOC_GETLK _FIOC(0x0013) /* IN: Pointer to flock + * OUT: None + */ +#define FIOC_SETLKW _FIOC(0x0014) /* IN: Pointer to flock + * OUT: None + */ + /* NuttX file system ioctl definitions **************************************/ #define _DIOCVALID(c) (_IOC_TYPE(c)==_DIOCBASE)