| 496 | } |
| 497 | |
| 498 | static int ublk_queue_io_cmd(struct ublk_queue *q, |
| 499 | struct ublk_io *io, unsigned tag) |
| 500 | { |
| 501 | struct ublksrv_io_cmd *cmd; |
| 502 | struct io_uring_sqe *sqe; |
| 503 | unsigned int cmd_op = 0; |
| 504 | __u64 user_data; |
| 505 | |
| 506 | /* only freed io can be issued */ |
| 507 | if (!(io->flags & UBLKSRV_IO_FREE)) |
| 508 | return 0; |
| 509 | |
| 510 | /* we issue because we need either fetching or committing */ |
| 511 | if (!(io->flags & |
| 512 | (UBLKSRV_NEED_FETCH_RQ | UBLKSRV_NEED_COMMIT_RQ_COMP))) |
| 513 | return 0; |
| 514 | |
| 515 | if (io->flags & UBLKSRV_NEED_COMMIT_RQ_COMP) |
| 516 | cmd_op = UBLK_U_IO_COMMIT_AND_FETCH_REQ; |
| 517 | else if (io->flags & UBLKSRV_NEED_FETCH_RQ) |
| 518 | cmd_op = UBLK_U_IO_FETCH_REQ; |
| 519 | |
| 520 | sqe = io_uring_get_sqe(&q->ring); |
| 521 | if (!sqe) { |
| 522 | ublk_err("%s: run out of sqe %d, tag %d\n", |
| 523 | __func__, q->q_id, tag); |
| 524 | return -1; |
| 525 | } |
| 526 | |
| 527 | cmd = (struct ublksrv_io_cmd *)ublk_get_sqe_cmd(sqe); |
| 528 | |
| 529 | if (cmd_op == UBLK_U_IO_COMMIT_AND_FETCH_REQ) |
| 530 | cmd->result = io->result; |
| 531 | |
| 532 | /* These fields should be written once, never change */ |
| 533 | ublk_set_sqe_cmd_op(sqe, cmd_op); |
| 534 | sqe->fd = 0; /* dev->fds[0] */ |
| 535 | sqe->opcode = IORING_OP_URING_CMD; |
| 536 | sqe->flags = IOSQE_FIXED_FILE; |
| 537 | sqe->rw_flags = 0; |
| 538 | cmd->tag = tag; |
| 539 | cmd->addr = (__u64) (uintptr_t) io->buf_addr; |
| 540 | cmd->q_id = q->q_id; |
| 541 | |
| 542 | user_data = build_user_data(tag, _IOC_NR(cmd_op), 0, 0); |
| 543 | io_uring_sqe_set_data64(sqe, user_data); |
| 544 | |
| 545 | io->flags = 0; |
| 546 | |
| 547 | q->cmd_inflight += 1; |
| 548 | |
| 549 | ublk_dbg(UBLK_DBG_IO_CMD, "%s: (qid %d tag %u cmd_op %u) iof %x stopping %d\n", |
| 550 | __func__, q->q_id, tag, cmd_op, |
| 551 | io->flags, !!(q->state & UBLKSRV_QUEUE_STOPPING)); |
| 552 | return 1; |
| 553 | } |
| 554 | |
| 555 | static int ublk_complete_io(struct ublk_queue *q, |
no test coverage detected