nop.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kernel.h>
  3. #include <linux/errno.h>
  4. #include <linux/fs.h>
  5. #include <linux/file.h>
  6. #include <linux/io_uring.h>
  7. #include <uapi/linux/io_uring.h>
  8. #include "io_uring.h"
  9. #include "rsrc.h"
  10. #include "nop.h"
  11. struct io_nop {
  12. /* NOTE: kiocb has the file as the first member, so don't do it here */
  13. struct file *file;
  14. int result;
  15. int fd;
  16. unsigned int flags;
  17. __u64 extra1;
  18. __u64 extra2;
  19. };
  20. #define NOP_FLAGS (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \
  21. IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE | \
  22. IORING_NOP_TW | IORING_NOP_CQE32)
  23. int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  24. {
  25. struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop);
  26. nop->flags = READ_ONCE(sqe->nop_flags);
  27. if (nop->flags & ~NOP_FLAGS)
  28. return -EINVAL;
  29. if (nop->flags & IORING_NOP_INJECT_RESULT)
  30. nop->result = READ_ONCE(sqe->len);
  31. else
  32. nop->result = 0;
  33. if (nop->flags & IORING_NOP_FILE)
  34. nop->fd = READ_ONCE(sqe->fd);
  35. else
  36. nop->fd = -1;
  37. if (nop->flags & IORING_NOP_FIXED_BUFFER)
  38. req->buf_index = READ_ONCE(sqe->buf_index);
  39. if (nop->flags & IORING_NOP_CQE32) {
  40. struct io_ring_ctx *ctx = req->ctx;
  41. if (!(ctx->flags & (IORING_SETUP_CQE32|IORING_SETUP_CQE_MIXED)))
  42. return -EINVAL;
  43. nop->extra1 = READ_ONCE(sqe->off);
  44. nop->extra2 = READ_ONCE(sqe->addr);
  45. }
  46. return 0;
  47. }
  48. int io_nop(struct io_kiocb *req, unsigned int issue_flags)
  49. {
  50. struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop);
  51. int ret = nop->result;
  52. if (nop->flags & IORING_NOP_FILE) {
  53. if (nop->flags & IORING_NOP_FIXED_FILE) {
  54. req->file = io_file_get_fixed(req, nop->fd, issue_flags);
  55. req->flags |= REQ_F_FIXED_FILE;
  56. } else {
  57. req->file = io_file_get_normal(req, nop->fd);
  58. }
  59. if (!req->file) {
  60. ret = -EBADF;
  61. goto done;
  62. }
  63. }
  64. if (nop->flags & IORING_NOP_FIXED_BUFFER) {
  65. if (!io_find_buf_node(req, issue_flags))
  66. ret = -EFAULT;
  67. }
  68. done:
  69. if (ret < 0)
  70. req_set_fail(req);
  71. if (nop->flags & IORING_NOP_CQE32)
  72. io_req_set_res32(req, nop->result, 0, nop->extra1, nop->extra2);
  73. else
  74. io_req_set_res(req, nop->result, 0);
  75. if (nop->flags & IORING_NOP_TW) {
  76. req->io_task_work.func = io_req_task_complete;
  77. io_req_task_work_add(req);
  78. return IOU_ISSUE_SKIP_COMPLETE;
  79. }
  80. return IOU_COMPLETE;
  81. }