rpmsgblk: bind block inode to ept when create ept

A segmentfault might happen when read/write/unlink ops called without an open
ops called because it bind ept's ops in rpmsgblk_open_handler.

proxy> rm /dev/ram1
segmentfault

proxy> ls /dev/ram1
segmentfault

Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
liaoao 2023-10-09 21:09:00 +08:00 committed by Xiang Xiao
parent 57de6484e9
commit 27f672d55a
4 changed files with 60 additions and 49 deletions

View File

@ -65,6 +65,7 @@ endif
ifeq ($(CONFIG_BLK_RPMSG_SERVER),y)
CSRCS += rpmsgblk_server.c
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)fs$(DELIM)inode
endif
# Include build support

View File

@ -31,6 +31,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/rptun/openamp.h>
#include "inode.h"
#include "rpmsgblk.h"
/****************************************************************************
@ -119,23 +120,19 @@ static int rpmsgblk_open_handler(FAR struct rpmsg_endpoint *ept,
FAR struct rpmsgblk_server_s *server = ept->priv;
FAR struct rpmsgblk_open_s *msg = data;
if (server->blknode != NULL)
if (server->bops->open != NULL)
{
msg->header.result = -EBUSY;
goto out;
msg->header.result = server->bops->open(server->blknode);
if (msg->header.result < 0)
{
ferr("block device open failed, ret=%d\n", msg->header.result);
}
}
else
{
msg->header.result = 0;
}
msg->header.result = open_blockdriver(&ept->name[RPMSGBLK_NAME_PREFIX_LEN],
0, &server->blknode);
if (msg->header.result < 0)
{
ferr("block device open failed, ret=%d\n", msg->header.result);
goto out;
}
server->bops = server->blknode->u.i_bops;
out:
return rpmsg_send(ept, msg, sizeof(*msg));
}
@ -150,17 +147,19 @@ static int rpmsgblk_close_handler(FAR struct rpmsg_endpoint *ept,
FAR struct rpmsgblk_server_s *server = ept->priv;
FAR struct rpmsgblk_close_s *msg = data;
msg->header.result = close_blockdriver(server->blknode);
if (msg->header.result < 0)
if (server->bops->close != NULL)
{
ferr("block device close failed, ret=%d\n", msg->header.result);
goto out;
msg->header.result = server->bops->close(server->blknode);
if (msg->header.result < 0)
{
ferr("block device close failed, ret=%d\n", msg->header.result);
}
}
else
{
msg->header.result = 0;
}
server->bops = NULL;
server->blknode = NULL;
out:
return rpmsg_send(ept, msg, sizeof(*msg));
}
@ -375,7 +374,18 @@ static void rpmsgblk_ns_bind(FAR struct rpmsg_device *rdev,
return;
}
ret = find_blockdriver(&name[RPMSGBLK_NAME_PREFIX_LEN], 0,
&server->blknode);
if (ret < 0)
{
ferr("ERROR: Failed to find %s block driver\n",
&name[RPMSGBLK_NAME_PREFIX_LEN]);
kmm_free(server);
return;
}
server->ept.priv = server;
server->bops = server->blknode->u.i_bops;
ret = rpmsg_create_ept(&server->ept, rdev, name,
RPMSG_ADDR_ANY, dest,
@ -383,6 +393,7 @@ static void rpmsgblk_ns_bind(FAR struct rpmsg_device *rdev,
if (ret < 0)
{
ferr("endpoint create failed, ret=%d\n", ret);
inode_release(server->blknode);
kmm_free(server);
}
}
@ -396,6 +407,7 @@ static void rpmsgblk_ns_unbind(FAR struct rpmsg_endpoint *ept)
FAR struct rpmsgblk_server_s *server = ept->priv;
rpmsg_destroy_ept(&server->ept);
inode_release(server->blknode);
kmm_free(server);
}

View File

@ -48,33 +48,6 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: find_blockdriver
*
* Description:
* Return the inode of the block driver specified by 'pathname'
*
* Input Parameters:
* pathname - The full path to the block driver to be located
* mountflags - If MS_RDONLY is not set, then driver must support write
* operations (see include/sys/mount.h)
* ppinode - Address of the location to return the inode reference
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* ENOENT - No block driver of this name is registered
* ENOTBLK - The inode associated with the pathname is not a block driver
* EACCESS - The MS_RDONLY option was not set but this driver does not
* support write access
*
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
int find_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode);
#endif
/****************************************************************************
* Name: register_partition_with_inode
*

View File

@ -1199,6 +1199,31 @@ int open_blockdriver(FAR const char *pathname, int mountflags,
int close_blockdriver(FAR struct inode *inode);
/****************************************************************************
* Name: find_blockdriver
*
* Description:
* Return the inode of the block driver specified by 'pathname'
*
* Input Parameters:
* pathname - The full path to the block driver to be located
* mountflags - If MS_RDONLY is not set, then driver must support write
* operations (see include/sys/mount.h)
* ppinode - Address of the location to return the inode reference
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* ENOENT - No block driver of this name is registered
* ENOTBLK - The inode associated with the pathname is not a block driver
* EACCESS - The MS_RDONLY option was not set but this driver does not
* support write access
*
****************************************************************************/
int find_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode);
/****************************************************************************
* Name: find_mtddriver
*