staticint io_lock_external_ctx(struct io_ring_ctx *octx, unsignedint issue_flags)
{ /* * To ensure proper ordering between the two ctxs, we can only * attempt a trylock on the target. If that fails and we already have * the source ctx lock, punt to io-wq.
*/ if (!(issue_flags & IO_URING_F_UNLOCKED)) { if (!mutex_trylock(&octx->uring_lock)) return -EAGAIN; return 0;
}
mutex_lock(&octx->uring_lock); return 0;
}
if (msg->src_fd || msg->flags & ~IORING_MSG_RING_FLAGS_PASS) return -EINVAL; if (!(msg->flags & IORING_MSG_RING_FLAGS_PASS) && msg->dst_fd) return -EINVAL; if (target_ctx->flags & IORING_SETUP_R_DISABLED) return -EBADFD;
if (io_msg_need_remote(target_ctx)) return io_msg_data_remote(target_ctx, msg);
if (msg->flags & IORING_MSG_RING_FLAGS_PASS)
flags = msg->cqe_flags;
ret = -EOVERFLOW; if (target_ctx->flags & IORING_SETUP_IOPOLL) { if (unlikely(io_lock_external_ctx(target_ctx, issue_flags))) return -EAGAIN;
} if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, flags))
ret = 0; if (target_ctx->flags & IORING_SETUP_IOPOLL)
io_double_unlock_ctx(target_ctx); return ret;
}
if (msg->flags & IORING_MSG_RING_CQE_SKIP) goto out_unlock; /* * If this fails, the target still received the file descriptor but * wasn't notified of the fact. This means that if this request * completes with -EOVERFLOW, then the sender must ensure that a * later IORING_OP_MSG_RING delivers the message.
*/ if (!io_post_aux_cqe(target_ctx, msg->user_data, ret, 0))
ret = -EOVERFLOW;
out_unlock:
io_double_unlock_ctx(target_ctx); return ret;
}
if (msg->len) return -EINVAL; if (target_ctx == ctx) return -EINVAL; if (target_ctx->flags & IORING_SETUP_R_DISABLED) return -EBADFD; if (!msg->src_file) { int ret = io_msg_grab_file(req, issue_flags); if (unlikely(ret)) return ret;
}
if (io_msg_need_remote(target_ctx)) return io_msg_fd_remote(req); return io_msg_install_complete(req, issue_flags);
}
int io_msg_ring(struct io_kiocb *req, unsignedint issue_flags)
{ struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); int ret;
ret = -EBADFD; if (!io_is_uring_fops(req->file)) goto done;
switch (msg->cmd) { case IORING_MSG_DATA:
ret = io_msg_ring_data(req, issue_flags); break; case IORING_MSG_SEND_FD:
ret = io_msg_send_fd(req, issue_flags); break; default:
ret = -EINVAL; break;
}
done: if (ret < 0) { if (ret == -EAGAIN || ret == IOU_ISSUE_SKIP_COMPLETE) return ret;
req_set_fail(req);
}
io_req_set_res(req, ret, 0); return IOU_COMPLETE;
}
int io_uring_sync_msg_ring(struct io_uring_sqe *sqe)
{ struct io_msg io_msg = { }; int ret;
ret = __io_msg_ring_prep(&io_msg, sqe); if (unlikely(ret)) return ret;
/* * Only data sending supported, not IORING_MSG_SEND_FD as that one * doesn't make sense without a source ring to send files from.
*/ if (io_msg.cmd != IORING_MSG_DATA) return -EINVAL;
CLASS(fd, f)(sqe->fd); if (fd_empty(f)) return -EBADF; if (!io_is_uring_fops(fd_file(f))) return -EBADFD; return __io_msg_ring_data(fd_file(f)->private_data,
&io_msg, IO_URING_F_UNLOCKED);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.