()
| 124 | #[cfg(feature = "mm")] |
| 125 | #[test] |
| 126 | fn io_uring_buf_ring_can_be_registered() { |
| 127 | const ENTRIES: usize = 8; |
| 128 | const BGID: u16 = 42; |
| 129 | |
| 130 | let mut params = io_uring_params::default(); |
| 131 | let ring_fd = unsafe { io_uring_setup(4, &mut params).unwrap() }; |
| 132 | |
| 133 | // Test that the kernel version supports IORING_REGISTER_PBUF_RING. If it |
| 134 | // doesn't, the kernel will return EINVAL. Not setting a `ring_addr` on |
| 135 | // `io_uring_buf_reg` will return `EFAULT`. |
| 136 | if let Err(e) = register_buf_ring(ring_fd.as_fd(), &io_uring_buf_reg::default()) { |
| 137 | if e == Errno::INVAL { |
| 138 | // Skip the test, as the current kernel version doesn't support what we need to |
| 139 | // test. |
| 140 | return; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | let buf_ring_size = ENTRIES * std::mem::size_of::<io_uring_buf>(); |
| 145 | |
| 146 | let br_ptr = unsafe { |
| 147 | rustix::mm::mmap_anonymous( |
| 148 | ptr::null_mut(), |
| 149 | buf_ring_size, |
| 150 | ProtFlags::READ | ProtFlags::WRITE, |
| 151 | MapFlags::PRIVATE, |
| 152 | ) |
| 153 | } |
| 154 | .unwrap() |
| 155 | .cast::<io_uring_buf_ring>(); |
| 156 | |
| 157 | let br = unsafe { br_ptr.as_mut() }.expect("A valid io_uring_buf_ring struct"); |
| 158 | |
| 159 | let mut reg = io_uring_buf_reg::default(); |
| 160 | reg.ring_addr = br_ptr.cast::<c_void>().into(); |
| 161 | reg.ring_entries = ENTRIES as u32; |
| 162 | reg.bgid = BGID; |
| 163 | reg.flags = 0; |
| 164 | |
| 165 | assert_eq!(register_buf_ring(ring_fd, ®), Ok(())); |
| 166 | |
| 167 | let tail = unsafe { br.tail_or_bufs.tail.as_mut() }; |
| 168 | tail.tail = 0; |
| 169 | let bufs = unsafe { br.tail_or_bufs.bufs.as_mut().bufs.as_mut_slice(ENTRIES) }; |
| 170 | |
| 171 | assert_eq!(bufs[0].bid, 0); |
| 172 | bufs[7].bid = 7; |
| 173 | assert_eq!(bufs[7].bid, 7); |
| 174 | } |
nothing calls this directly
no test coverage detected