* Test read that will not complete, with a linked timeout behind it that * has errors in the SQE */
| 300 | * has errors in the SQE |
| 301 | */ |
| 302 | static int test_single_link_timeout_error(struct io_uring *ring) |
| 303 | { |
| 304 | struct __kernel_timespec ts; |
| 305 | struct io_uring_cqe *cqe; |
| 306 | struct io_uring_sqe *sqe; |
| 307 | int fds[2], ret, i; |
| 308 | struct iovec iov; |
| 309 | char buffer[128]; |
| 310 | |
| 311 | if (pipe(fds)) { |
| 312 | perror("pipe"); |
| 313 | return 1; |
| 314 | } |
| 315 | |
| 316 | sqe = io_uring_get_sqe(ring); |
| 317 | if (!sqe) { |
| 318 | printf("get sqe failed\n"); |
| 319 | goto err; |
| 320 | } |
| 321 | |
| 322 | iov.iov_base = buffer; |
| 323 | iov.iov_len = sizeof(buffer); |
| 324 | io_uring_prep_readv(sqe, fds[0], &iov, 1, 0); |
| 325 | sqe->flags |= IOSQE_IO_LINK; |
| 326 | sqe->user_data = 1; |
| 327 | |
| 328 | sqe = io_uring_get_sqe(ring); |
| 329 | if (!sqe) { |
| 330 | printf("get sqe failed\n"); |
| 331 | goto err; |
| 332 | } |
| 333 | |
| 334 | ts.tv_sec = 1; |
| 335 | ts.tv_nsec = 0; |
| 336 | io_uring_prep_link_timeout(sqe, &ts, 0); |
| 337 | /* set invalid field, it'll get failed */ |
| 338 | sqe->ioprio = 89; |
| 339 | sqe->user_data = 2; |
| 340 | |
| 341 | ret = io_uring_submit(ring); |
| 342 | if (ret != 2) { |
| 343 | printf("sqe submit failed: %d\n", ret); |
| 344 | goto err; |
| 345 | } |
| 346 | |
| 347 | for (i = 0; i < 2; i++) { |
| 348 | ret = io_uring_wait_cqe(ring, &cqe); |
| 349 | if (ret < 0) { |
| 350 | printf("wait completion %d\n", ret); |
| 351 | goto err; |
| 352 | } |
| 353 | switch (cqe->user_data) { |
| 354 | case 1: |
| 355 | if (cqe->res != -ECANCELED) { |
| 356 | fprintf(stderr, "Read got %d, wanted -ECANCELED\n", |
| 357 | cqe->res); |
| 358 | goto err; |
| 359 | } |
no test coverage detected