fixed-buf-merge.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Test fixed buffer merging/skipping
  5. *
  6. * Taken from: https://github.com/axboe/liburing/issues/994
  7. *
  8. */
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <fcntl.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include "liburing.h"
  15. #include "helpers.h"
  16. int main(int argc, char *argv[])
  17. {
  18. int ret, i, fd, initial_offset = 4096, num_requests = 3;
  19. struct io_uring ring;
  20. struct io_uring_sqe *sqe;
  21. struct io_uring_cqe *cqe;
  22. struct iovec iov;
  23. char *buffer, *to_free;
  24. unsigned head;
  25. char filename[64];
  26. ret = io_uring_queue_init(4, &ring, 0);
  27. if (ret) {
  28. fprintf(stderr, "queue_init: %d\n", ret);
  29. return T_EXIT_FAIL;
  30. }
  31. sprintf(filename, ".fixed-buf-%d", getpid());
  32. t_create_file(filename, 4 * 4096);
  33. fd = open(filename, O_RDONLY | O_DIRECT, 0644);
  34. if (fd < 0) {
  35. if (errno == EINVAL) {
  36. unlink(filename);
  37. return T_EXIT_SKIP;
  38. }
  39. perror("open");
  40. goto err_unlink;
  41. }
  42. to_free = buffer = aligned_alloc(4096, 128 * 4096);
  43. if (!buffer) {
  44. perror("aligned_alloc");
  45. goto err_unlink;
  46. }
  47. /* Register buffer */
  48. iov.iov_base = buffer;
  49. iov.iov_len = 128 * 4096;
  50. ret = io_uring_register_buffers(&ring, &iov, 1);
  51. if (ret) {
  52. fprintf(stderr, "buf register: %d\n", ret);
  53. goto err_unlink;
  54. }
  55. /* Prepare read requests */
  56. buffer += initial_offset;
  57. for (i = 0; i < num_requests; i++) {
  58. sqe = io_uring_get_sqe(&ring);
  59. io_uring_prep_read_fixed(sqe, fd, buffer, 4096, 4096 * i, 0);
  60. buffer += 4096;
  61. }
  62. /* Submit requests and reap completions */
  63. ret = io_uring_submit_and_wait(&ring, num_requests);
  64. if (ret != num_requests) {
  65. fprintf(stderr, "Submit and wait: %d\n", ret);
  66. goto err_unlink;
  67. }
  68. i = 0;
  69. io_uring_for_each_cqe(&ring, head, cqe) {
  70. if (cqe->res != 4096) {
  71. fprintf(stderr, "cqe: %d\n", cqe->res);
  72. goto err_unlink;
  73. }
  74. i++;
  75. }
  76. if (i != num_requests) {
  77. fprintf(stderr, "Got %d completions\n", i);
  78. goto err_unlink;
  79. }
  80. io_uring_cq_advance(&ring, i);
  81. io_uring_queue_exit(&ring);
  82. close(fd);
  83. free(to_free);
  84. unlink(filename);
  85. return T_EXIT_PASS;
  86. err_unlink:
  87. unlink(filename);
  88. return T_EXIT_FAIL;
  89. }