Run IO over ublk block device */
| 1071 | |
| 1072 | /* Run IO over ublk block device */ |
| 1073 | static int test_io(struct io_ctx *ctx) |
| 1074 | { |
| 1075 | struct io_uring ring; |
| 1076 | int ret, ring_flags = 0; |
| 1077 | char buf[256]; |
| 1078 | int fd = -1; |
| 1079 | off_t offset = 0; |
| 1080 | unsigned long long bytes; |
| 1081 | int open_flags = O_DIRECT; |
| 1082 | struct iovec *vecs = t_create_buffers(BUFFERS, BS); |
| 1083 | |
| 1084 | ret = t_create_ring(BUFFERS, &ring, ring_flags); |
| 1085 | if (ret == T_SETUP_SKIP) |
| 1086 | return 0; |
| 1087 | if (ret != T_SETUP_OK) { |
| 1088 | fprintf(stderr, "ring create failed: %d\n", ret); |
| 1089 | return 1; |
| 1090 | } |
| 1091 | |
| 1092 | snprintf(buf, sizeof(buf), "%s%d", UBLKB_DEV, ctx->dev_id); |
| 1093 | |
| 1094 | if (ctx->write) |
| 1095 | open_flags |= O_WRONLY; |
| 1096 | else |
| 1097 | open_flags |= O_RDONLY; |
| 1098 | fd = open(buf, open_flags); |
| 1099 | if (fd < 0) { |
| 1100 | if (errno == EINVAL) |
| 1101 | return 0; |
| 1102 | return 1; |
| 1103 | } |
| 1104 | |
| 1105 | if (ioctl(fd, BLKGETSIZE64, &bytes) != 0) |
| 1106 | return 1; |
| 1107 | |
| 1108 | ret = t_register_buffers(&ring, vecs, BUFFERS); |
| 1109 | if (ret == T_SETUP_SKIP) |
| 1110 | return 0; |
| 1111 | if (ret != T_SETUP_OK) { |
| 1112 | fprintf(stderr, "buffer reg failed: %d\n", ret); |
| 1113 | return 1; |
| 1114 | } |
| 1115 | |
| 1116 | for (offset = 0; offset < bytes; offset += BS * BUFFERS) { |
| 1117 | ret = __test_io(&ring, fd, ctx->write, ctx->seq, vecs, BS, |
| 1118 | offset); |
| 1119 | if (ret != T_SETUP_OK) { |
| 1120 | fprintf(stderr, "/dev/ublkb%d read failed: offset %lu ret %d\n", |
| 1121 | ctx->dev_id, (unsigned long) offset, ret); |
| 1122 | break; |
| 1123 | } |
| 1124 | } |
| 1125 | |
| 1126 | close(fd); |
| 1127 | io_uring_unregister_buffers(&ring); |
| 1128 | io_uring_queue_exit(&ring); |
| 1129 | |
| 1130 | return ret; |
no test coverage detected