| 325 | } |
| 326 | |
| 327 | int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring, |
| 328 | struct io_uring_params *p, void *buf, |
| 329 | size_t buf_size) |
| 330 | { |
| 331 | int fd, ret = 0; |
| 332 | unsigned *sq_array; |
| 333 | unsigned sq_entries, index; |
| 334 | |
| 335 | memset(ring, 0, sizeof(*ring)); |
| 336 | |
| 337 | /* |
| 338 | * The kernel does this check already, but checking it here allows us |
| 339 | * to avoid handling it below. |
| 340 | */ |
| 341 | if (p->flags & IORING_SETUP_REGISTERED_FD_ONLY |
| 342 | && !(p->flags & IORING_SETUP_NO_MMAP)) |
| 343 | return -EINVAL; |
| 344 | |
| 345 | if (p->flags & IORING_SETUP_NO_MMAP) { |
| 346 | ret = io_uring_alloc_huge(entries, p, &ring->sq, &ring->cq, |
| 347 | buf, buf_size); |
| 348 | if (ret < 0) |
| 349 | return ret; |
| 350 | if (buf) |
| 351 | ring->int_flags |= INT_FLAG_APP_MEM; |
| 352 | } |
| 353 | |
| 354 | fd = __sys_io_uring_setup(entries, p); |
| 355 | if (fd < 0) { |
| 356 | if ((p->flags & IORING_SETUP_NO_MMAP) && |
| 357 | !(ring->int_flags & INT_FLAG_APP_MEM)) { |
| 358 | __sys_munmap(ring->sq.sqes, ring->sq.sqes_sz); |
| 359 | io_uring_unmap_rings(&ring->sq, &ring->cq); |
| 360 | } |
| 361 | return fd; |
| 362 | } |
| 363 | |
| 364 | if (!(p->flags & IORING_SETUP_NO_MMAP)) { |
| 365 | ret = io_uring_queue_mmap(fd, p, ring); |
| 366 | if (ret) { |
| 367 | __sys_close(fd); |
| 368 | return ret; |
| 369 | } |
| 370 | } else { |
| 371 | io_uring_setup_ring_pointers(p, &ring->sq, &ring->cq); |
| 372 | } |
| 373 | |
| 374 | /* |
| 375 | * Directly map SQ slots to SQEs |
| 376 | */ |
| 377 | sq_entries = ring->sq.ring_entries; |
| 378 | |
| 379 | if (!(p->flags & IORING_SETUP_NO_SQARRAY)) { |
| 380 | sq_array = ring->sq.array; |
| 381 | for (index = 0; index < sq_entries; index++) |
| 382 | sq_array[index] = index; |
| 383 | } |
| 384 | ring->features = p->features; |
no test coverage detected