| 747 | } |
| 748 | |
| 749 | static int test_io_link(const char *file) |
| 750 | { |
| 751 | const int nr_links = 100; |
| 752 | const int link_len = 100; |
| 753 | const int nr_sqes = nr_links * link_len; |
| 754 | struct io_uring_sqe *sqe; |
| 755 | struct io_uring_cqe *cqe; |
| 756 | struct io_uring ring; |
| 757 | int i, j, fd, ret; |
| 758 | |
| 759 | fd = open(file, O_WRONLY); |
| 760 | if (fd < 0) { |
| 761 | if (errno == EPERM || errno == EACCES) |
| 762 | return 0; |
| 763 | perror("file open"); |
| 764 | goto err; |
| 765 | } |
| 766 | |
| 767 | ret = io_uring_queue_init(nr_sqes, &ring, 0); |
| 768 | if (ret) { |
| 769 | fprintf(stderr, "ring create failed: %d\n", ret); |
| 770 | goto err; |
| 771 | } |
| 772 | |
| 773 | for (i = 0; i < nr_links; ++i) { |
| 774 | for (j = 0; j < link_len; ++j) { |
| 775 | sqe = io_uring_get_sqe(&ring); |
| 776 | if (!sqe) { |
| 777 | fprintf(stderr, "sqe get failed\n"); |
| 778 | goto err; |
| 779 | } |
| 780 | io_uring_prep_writev(sqe, fd, &vecs[0], 1, 0); |
| 781 | sqe->flags |= IOSQE_ASYNC; |
| 782 | if (j != link_len - 1) |
| 783 | sqe->flags |= IOSQE_IO_LINK; |
| 784 | } |
| 785 | } |
| 786 | |
| 787 | ret = io_uring_submit(&ring); |
| 788 | if (ret != nr_sqes) { |
| 789 | ret = io_uring_peek_cqe(&ring, &cqe); |
| 790 | if (!ret && cqe->res == -EINVAL) { |
| 791 | fprintf(stdout, "IOSQE_ASYNC not supported, skipped\n"); |
| 792 | goto out; |
| 793 | } |
| 794 | fprintf(stderr, "submit got %d, wanted %d\n", ret, nr_sqes); |
| 795 | goto err; |
| 796 | } |
| 797 | |
| 798 | for (i = 0; i < nr_sqes; i++) { |
| 799 | ret = io_uring_wait_cqe(&ring, &cqe); |
| 800 | if (ret) { |
| 801 | fprintf(stderr, "wait_cqe=%d\n", ret); |
| 802 | goto err; |
| 803 | } |
| 804 | if (cqe->res == -EINVAL) { |
| 805 | if (!warned) { |
| 806 | fprintf(stdout, "Non-vectored IO not " |
no test coverage detected