| 70 | } |
| 71 | |
| 72 | static int __test_io(const char *file, struct io_uring *ring, int tc, int read, |
| 73 | int sqthread, int fixed, int nonvec, int async, int linked) |
| 74 | { |
| 75 | struct io_uring_sqe *sqe; |
| 76 | struct io_uring_cqe *cqe; |
| 77 | struct nvme_uring_cmd *cmd; |
| 78 | int open_flags; |
| 79 | int do_fixed; |
| 80 | int i, ret, fd = -1, use_fd = -1, submit_count = 0; |
| 81 | off_t offset; |
| 82 | __u64 slba; |
| 83 | __u32 nlb; |
| 84 | |
| 85 | if (read) |
| 86 | open_flags = O_RDONLY; |
| 87 | else |
| 88 | open_flags = O_WRONLY; |
| 89 | |
| 90 | if (fixed) { |
| 91 | ret = t_register_buffers(ring, backing_vec, 1); |
| 92 | if (ret == T_SETUP_SKIP) |
| 93 | return 0; |
| 94 | if (ret != T_SETUP_OK) { |
| 95 | fprintf(stderr, "buffer reg failed: %d\n", ret); |
| 96 | goto err; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | fd = open(file, open_flags); |
| 101 | if (fd < 0) { |
| 102 | if (errno == EACCES || errno == EPERM) |
| 103 | return T_EXIT_SKIP; |
| 104 | perror("file open"); |
| 105 | goto err; |
| 106 | } |
| 107 | |
| 108 | if (sqthread) { |
| 109 | ret = io_uring_register_files(ring, &fd, 1); |
| 110 | if (ret) { |
| 111 | fprintf(stderr, "file reg failed: %d\n", ret); |
| 112 | goto err; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | if (!read) |
| 117 | fill_pattern(tc); |
| 118 | |
| 119 | offset = 0; |
| 120 | for (i = 0; i < BUFFERS; i++) { |
| 121 | unsigned int iovcnt = 1; |
| 122 | size_t total_len; |
| 123 | |
| 124 | if (linked) { |
| 125 | sqe = io_uring_get_sqe(ring); |
| 126 | io_uring_prep_nop(sqe); |
| 127 | if (async) |
| 128 | sqe->flags |= IOSQE_ASYNC; |
| 129 | sqe->flags |= IOSQE_IO_LINK; |