liburing_cpp: Add wrapper API for PrepReadFixed()
Bug: 400674947
Test: liburing_cpp_tests
Change-Id: I678f18601472dcd0c76e4a5084020fe8e83927cf
Signed-off-by: Akilesh Kailash <akailash@google.com>
diff --git a/liburing_cpp/Android.bp b/liburing_cpp/Android.bp
index e17f080..8566bc2 100644
--- a/liburing_cpp/Android.bp
+++ b/liburing_cpp/Android.bp
@@ -1,4 +1,3 @@
-
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
@@ -9,31 +8,32 @@
}
cc_library {
- name: "liburing_cpp",
- host_supported: true,
- recovery_available: true,
- srcs: [
- "src/IoUring.cpp",
- "src/IoUringSQE.cpp",
- ],
- static_libs: [
- "liburing",
- ],
- export_include_dirs: [
- "include",
- ],
+ name: "liburing_cpp",
+ host_supported: true,
+ recovery_available: true,
+ ramdisk_available: true,
+ vendor_ramdisk_available: true,
+ srcs: [
+ "src/IoUring.cpp",
+ "src/IoUringSQE.cpp",
+ ],
+ static_libs: [
+ "liburing",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
}
-
cc_test_host {
- name: "liburing_cpp_tests",
- srcs: [
- "tests/BasicTests.cpp",
- "tests/main.cpp",
- ],
- static_libs: [
- "libgtest",
- "liburing",
- "liburing_cpp",
- ],
+ name: "liburing_cpp_tests",
+ srcs: [
+ "tests/BasicTests.cpp",
+ "tests/main.cpp",
+ ],
+ static_libs: [
+ "libgtest",
+ "liburing",
+ "liburing_cpp",
+ ],
}
diff --git a/liburing_cpp/include/liburing_cpp/IoUring.h b/liburing_cpp/include/liburing_cpp/IoUring.h
index 09ed5cc..b382630 100644
--- a/liburing_cpp/include/liburing_cpp/IoUring.h
+++ b/liburing_cpp/include/liburing_cpp/IoUring.h
@@ -53,6 +53,12 @@
// Register a set of file descriptors to kernel.
virtual Errno RegisterFiles(const int* files, size_t files_size) = 0;
virtual Errno UnregisterFiles() = 0;
+
+ // Prepare read to a registered buffer. This does not submit the operation
+ // to the kernel. For that, call |IoUringInterface::Submit()|
+ virtual IoUringSQE PrepReadFixed(
+ int fd, void* buf, unsigned nbytes, uint64_t offset, int buf_index) = 0;
+
// Append a submission entry into this io_uring. This does not submit the
// operation to the kernel. For that, call |IoUringInterface::Submit()|
virtual IoUringSQE PrepRead(int fd, void *buf, unsigned nbytes,
diff --git a/liburing_cpp/src/IoUring.cpp b/liburing_cpp/src/IoUring.cpp
index cf10272..8589220 100644
--- a/liburing_cpp/src/IoUring.cpp
+++ b/liburing_cpp/src/IoUring.cpp
@@ -82,6 +82,19 @@
return ret;
}
+ IoUringSQE PrepReadFixed(int fd,
+ void* buf,
+ unsigned nbytes,
+ uint64_t offset,
+ int buf_index) override {
+ auto sqe = io_uring_get_sqe(&ring);
+ if (sqe == nullptr) {
+ return IoUringSQE{nullptr};
+ }
+ io_uring_prep_read_fixed(sqe, fd, buf, nbytes, offset, buf_index);
+ return IoUringSQE{static_cast<void*>(sqe)};
+ }
+
IoUringSQE PrepRead(int fd, void* buf, unsigned nbytes,
uint64_t offset) override {
auto sqe = io_uring_get_sqe(&ring);
diff --git a/liburing_cpp/tests/BasicTests.cpp b/liburing_cpp/tests/BasicTests.cpp
index 81288f6..680fb64 100644
--- a/liburing_cpp/tests/BasicTests.cpp
+++ b/liburing_cpp/tests/BasicTests.cpp
@@ -191,4 +191,51 @@
for (int i = 0; i < data.size(); ++i) {
ASSERT_EQ(data[i], i % 256);
}
-}
\ No newline at end of file
+}
+
+TEST_F(IoUringTest, ExtentReadFixedBuffers) {
+ const int fd = fileno(fp);
+ ASSERT_NO_FATAL_FAILURE(WriteTestData(fd, kBlockSize * 3, kBlockSize));
+ ASSERT_NO_FATAL_FAILURE(WriteTestData(fd, kBlockSize * 5, kBlockSize));
+ ASSERT_NO_FATAL_FAILURE(WriteTestData(fd, kBlockSize * 8, kBlockSize));
+ ASSERT_NO_FATAL_FAILURE(WriteTestData(fd, kBlockSize * 13, kBlockSize));
+ fsync(fd);
+
+ std::vector<unsigned char> data;
+ data.resize(kBlockSize * 4);
+ std::unique_ptr<struct iovec[]> vecs = std::make_unique<struct iovec[]>(4);
+ for (int i = 0; i < 4; i++) {
+ vecs[i].iov_base = data.data() + i * kBlockSize;
+ vecs[i].iov_len = kBlockSize;
+ }
+
+ ASSERT_TRUE(ring->RegisterBuffers(vecs.get(), 4).IsOk());
+
+ ASSERT_TRUE(
+ ring->PrepReadFixed(fd, data.data(), kBlockSize, 3 * kBlockSize, 0)
+ .IsOk());
+ ASSERT_TRUE(
+ ring->PrepReadFixed(
+ fd, data.data() + kBlockSize, kBlockSize, 5 * kBlockSize, 1)
+ .IsOk());
+ ASSERT_TRUE(
+ ring->PrepReadFixed(
+ fd, data.data() + kBlockSize * 2, kBlockSize, 8 * kBlockSize, 2)
+ .IsOk());
+ ASSERT_TRUE(
+ ring->PrepReadFixed(
+ fd, data.data() + kBlockSize * 3, kBlockSize, 13 * kBlockSize, 3)
+ .IsOk());
+ ring->SubmitAndWait(4);
+ const auto cqes = ring->PopCQE(4);
+ if (cqes.IsErr()) {
+ FAIL() << cqes.GetError().ErrMsg();
+ return;
+ }
+ for (const auto& cqe : cqes.GetResult()) {
+ ASSERT_GT(cqe.res, 0);
+ }
+ for (int i = 0; i < data.size(); ++i) {
+ ASSERT_EQ(data[i], i % 256);
+ }
+}