rpmsgfs:Support cross-core access using file locks on the same file

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
This commit is contained in:
chenrun1 2024-05-13 20:21:18 +08:00 committed by Xiang Xiao
parent b9fde453ce
commit a1e3444df0
4 changed files with 73 additions and 23 deletions

View File

@ -27,6 +27,7 @@
#include <string.h>
#include <stdio.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/ioctl.h>
@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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)