static int io_recvmsg_prep(struct io_kiocb *req,
			   const struct io_uring_sqe *sqe)
{
	struct io_sr_msg *sr = &req->sr_msg;
	struct io_async_ctx *io = req->io;
	int ret;

	if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
		return -EINVAL;

	sr->msg_flags = READ_ONCE(sqe->msg_flags);
	sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
	sr->len = READ_ONCE(sqe->len);
	sr->bgid = READ_ONCE(sqe->buf_group);

#ifdef CONFIG_COMPAT
	if (req->ctx->compat)
		sr->msg_flags |= MSG_CMSG_COMPAT;
#endif

	if (!io || req->opcode == IORING_OP_RECV)
		return 0;
	/* iovec is already imported */
	if (req->flags & REQ_F_NEED_CLEANUP)
		return 0;

	ret = io_recvmsg_copy_hdr(req, &io->msg);
	if (!ret)
		req->flags |= REQ_F_NEED_CLEANUP;
	return ret;
}
static int io_recvmsg_prep(struct io_kiocb *req,
			   const struct io_uring_sqe *sqe)
{
	struct io_sr_msg *sr = &req->sr_msg;
	struct io_async_ctx *io = req->io;
	int ret;

	if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
		return -EINVAL;

	sr->msg_flags = READ_ONCE(sqe->msg_flags);
	sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
	sr->len = READ_ONCE(sqe->len);
	sr->bgid = READ_ONCE(sqe->buf_group);

#ifdef CONFIG_COMPAT
	if (req->ctx->compat)
		sr->msg_flags |= MSG_CMSG_COMPAT;
#endif

	if (!io || req->opcode == IORING_OP_RECV)
		return 0;
	 
	if (req->flags & REQ_F_NEED_CLEANUP)
		return 0;

	ret = io_recvmsg_copy_hdr(req, &io->msg);
	if (!ret)
		req->flags |= REQ_F_NEED_CLEANUP;
	return ret;
}