Commit 1e63a88c authored by Dan Melnic's avatar Dan Melnic Committed by Facebook GitHub Bot

Add IoUringBackend support for openat, openat2, close, fallocate

Summary: Add IoUringBackend support for openat, openat2, close, fallocate #forcetdhashing

Reviewed By: kevin-vigor

Differential Revision: D26325604

fbshipit-source-id: dbeea468ffbb324dc8c7afc1dbde1e451f72e06d
parent e032bce6
......@@ -1246,6 +1246,41 @@ void IoUringBackend::queueFsync(int fd, FSyncFlags flags, FileOpCallback&& cb) {
submitImmediateIoSqe(*ioSqe);
}
void IoUringBackend::queueOpenat(
int dfd, const char* path, int flags, mode_t mode, FileOpCallback&& cb) {
auto* ioSqe = new FOpenAtIoSqe(this, dfd, path, flags, mode, std::move(cb));
ioSqe->backendCb_ = processFileOpCB;
incNumIoSqeInUse();
submitImmediateIoSqe(*ioSqe);
}
void IoUringBackend::queueOpenat2(
int dfd, const char* path, struct open_how* how, FileOpCallback&& cb) {
auto* ioSqe = new FOpenAt2IoSqe(this, dfd, path, how, std::move(cb));
ioSqe->backendCb_ = processFileOpCB;
incNumIoSqeInUse();
submitImmediateIoSqe(*ioSqe);
}
void IoUringBackend::queueClose(int fd, FileOpCallback&& cb) {
auto* ioSqe = new FCloseIoSqe(this, fd, std::move(cb));
ioSqe->backendCb_ = processFileOpCB;
incNumIoSqeInUse();
submitImmediateIoSqe(*ioSqe);
}
void IoUringBackend::queueFallocate(
int fd, int mode, off_t offset, off_t len, FileOpCallback&& cb) {
auto* ioSqe = new FAllocateIoSqe(this, fd, mode, offset, len, std::move(cb));
ioSqe->backendCb_ = processFileOpCB;
incNumIoSqeInUse();
submitImmediateIoSqe(*ioSqe);
}
void IoUringBackend::processFileOp(IoSqe* sqe, int64_t res) noexcept {
auto* ioSqe = reinterpret_cast<FileOpIoSqe*>(sqe);
// save the res
......
......@@ -211,6 +211,17 @@ class IoUringBackend : public EventBaseBackendBase {
void queueFsync(int fd, FileOpCallback&& cb);
void queueFdatasync(int fd, FileOpCallback&& cb);
void queueOpenat(
int dfd, const char* path, int flags, mode_t mode, FileOpCallback&& cb);
void queueOpenat2(
int dfd, const char* path, struct open_how* how, FileOpCallback&& cb);
void queueClose(int fd, FileOpCallback&& cb);
void queueFallocate(
int fd, int mode, off_t offset, off_t len, FileOpCallback&& cb);
protected:
enum class WaitForEventsMode { WAIT, DONT_WAIT };
......@@ -711,6 +722,87 @@ class IoUringBackend : public EventBaseBackendBase {
FSyncFlags flags_;
};
struct FOpenAtIoSqe : public FileOpIoSqe {
FOpenAtIoSqe(
IoUringBackend* backend,
int dfd,
const char* path,
int flags,
mode_t mode,
FileOpCallback&& cb)
: FileOpIoSqe(backend, dfd, std::move(cb)),
path_(path),
flags_(flags),
mode_(mode) {}
~FOpenAtIoSqe() override = default;
void processSubmit(struct io_uring_sqe* sqe) override {
::io_uring_prep_openat(sqe, fd_, path_.c_str(), flags_, mode_);
::io_uring_sqe_set_data(sqe, this);
}
std::string path_;
int flags_;
mode_t mode_;
};
struct FOpenAt2IoSqe : public FileOpIoSqe {
FOpenAt2IoSqe(
IoUringBackend* backend,
int dfd,
const char* path,
struct open_how* how,
FileOpCallback&& cb)
: FileOpIoSqe(backend, dfd, std::move(cb)), path_(path), how_(*how) {}
~FOpenAt2IoSqe() override = default;
void processSubmit(struct io_uring_sqe* sqe) override {
::io_uring_prep_openat2(sqe, fd_, path_.c_str(), &how_);
::io_uring_sqe_set_data(sqe, this);
}
std::string path_;
struct open_how how_;
};
struct FCloseIoSqe : public FileOpIoSqe {
using FileOpIoSqe::FileOpIoSqe;
~FCloseIoSqe() override = default;
void processSubmit(struct io_uring_sqe* sqe) override {
::io_uring_prep_close(sqe, fd_);
::io_uring_sqe_set_data(sqe, this);
}
};
struct FAllocateIoSqe : public FileOpIoSqe {
FAllocateIoSqe(
IoUringBackend* backend,
int fd,
int mode,
off_t offset,
off_t len,
FileOpCallback&& cb)
: FileOpIoSqe(backend, fd, std::move(cb)),
mode_(mode),
offset_(offset),
len_(len) {}
~FAllocateIoSqe() override = default;
void processSubmit(struct io_uring_sqe* sqe) override {
::io_uring_prep_fallocate(sqe, fd_, mode_, offset_, len_);
::io_uring_sqe_set_data(sqe, this);
}
int mode_;
off_t offset_;
off_t len_;
};
int getActiveEvents(WaitForEventsMode waitForEvents);
size_t submitList(IoSqeList& ioSqes, WaitForEventsMode waitForEvents);
int submitOne();
......
......@@ -28,6 +28,10 @@
#include <folly/io/async/test/EventBaseTestLib.h>
#include <folly/portability/GTest.h>
#ifndef RESOLVE_IN_ROOT
#define RESOLVE_IN_ROOT 0x10
#endif
// IoUringBackend specific tests
namespace {
class AlignedBuf {
......@@ -237,6 +241,18 @@ std::unique_ptr<folly::EventBase> getEventBase(
}
}
std::unique_ptr<folly::EventBase> getEventBase() {
static constexpr size_t kBackendCapacity = 32;
static constexpr size_t kBackendMaxSubmit = 16;
static constexpr size_t kBackendMaxGet = 8;
folly::PollIoBackend::Options options;
options.setCapacity(kBackendCapacity)
.setMaxSubmit(kBackendMaxSubmit)
.setMaxGet(kBackendMaxGet)
.setUseRegisteredFds(false);
return getEventBase(options);
}
void testEventFD(bool overflow, bool persist, bool asyncRead) {
static constexpr size_t kBackendCapacity = 16;
static constexpr size_t kBackendMaxSubmit = 8;
......@@ -503,6 +519,137 @@ TEST(IoUringBackend, SuccessCreateRetry) {
CHECK(bSuccess);
}
TEST(IoUringBackend, OpenAt) {
auto evbPtr = getEventBase();
SKIP_IF(!evbPtr) << "Backend not available";
auto* backendPtr = dynamic_cast<folly::IoUringBackend*>(evbPtr->getBackend());
CHECK(!!backendPtr);
auto dirPath = folly::fs::temp_directory_path();
auto path = folly::fs::unique_path();
auto filePath = dirPath / path;
int dfd = ::open(dirPath.string().c_str(), O_DIRECTORY | O_RDONLY, 0666);
CHECK_GE(dfd, 0);
SCOPE_EXIT {
::close(dfd);
::unlink(filePath.string().c_str());
};
folly::IoUringBackend::FileOpCallback openCb = [&](int res) {
evbPtr->terminateLoopSoon();
CHECK_GE(res, 0);
CHECK_EQ(0, ::close(res));
};
backendPtr->queueOpenat(
dfd,
path.string().c_str(),
O_RDWR | O_CREAT | O_EXCL,
0666,
std::move(openCb));
evbPtr->loopForever();
}
TEST(IoUringBackend, OpenAt2) {
auto evbPtr = getEventBase();
SKIP_IF(!evbPtr) << "Backend not available";
auto* backendPtr = dynamic_cast<folly::IoUringBackend*>(evbPtr->getBackend());
CHECK(!!backendPtr);
auto dirPath = folly::fs::temp_directory_path();
auto path = folly::fs::unique_path();
auto filePath = dirPath / path;
int dfd = ::open(dirPath.string().c_str(), O_DIRECTORY | O_RDONLY, 0666);
CHECK_GE(dfd, 0);
SCOPE_EXIT {
::close(dfd);
::unlink(filePath.string().c_str());
};
folly::IoUringBackend::FileOpCallback openCb = [&](int res) {
evbPtr->terminateLoopSoon();
CHECK_GE(res, 0);
CHECK_EQ(0, ::close(res));
};
struct open_how how = {};
how.flags = O_RDWR | O_CREAT | O_EXCL;
how.mode = 0666;
how.resolve = RESOLVE_IN_ROOT;
backendPtr->queueOpenat2(dfd, path.string().c_str(), &how, std::move(openCb));
}
TEST(IoUringBackend, Close) {
auto evbPtr = getEventBase();
SKIP_IF(!evbPtr) << "Backend not available";
auto* backendPtr = dynamic_cast<folly::IoUringBackend*>(evbPtr->getBackend());
CHECK(!!backendPtr);
auto path = folly::fs::temp_directory_path();
path /= folly::fs::unique_path();
int fd = ::open(path.string().c_str(), O_RDWR | O_CREAT | O_EXCL, 0666);
CHECK_GE(fd, 0);
SCOPE_EXIT {
if (fd >= 0) {
::close(fd);
}
::unlink(path.string().c_str());
};
folly::IoUringBackend::FileOpCallback closeCb = [&](int res) {
evbPtr->terminateLoopSoon();
CHECK_EQ(res, 0);
fd = -1;
};
backendPtr->queueClose(fd, std::move(closeCb));
evbPtr->loopForever();
CHECK_EQ(fd, -1);
}
TEST(IoUringBackend, Fallocate) {
auto evbPtr = getEventBase();
SKIP_IF(!evbPtr) << "Backend not available";
auto* backendPtr = dynamic_cast<folly::IoUringBackend*>(evbPtr->getBackend());
CHECK(!!backendPtr);
auto path = folly::fs::temp_directory_path();
path /= folly::fs::unique_path();
int fd = ::open(path.string().c_str(), O_RDWR | O_CREAT | O_EXCL, 0666);
CHECK_GE(fd, 0);
SCOPE_EXIT {
if (fd >= 0) {
::close(fd);
::unlink(path.string().c_str());
}
};
folly::IoUringBackend::FileOpCallback fallocateCb = [&](int res) {
CHECK_EQ(res, 0);
evbPtr->terminateLoopSoon();
};
backendPtr->queueFallocate(fd, 0, 0, 4096, std::move(fallocateCb));
evbPtr->loopForever();
}
TEST(IoUringBackend, AsyncUDPRecvmsgNoRegisterFd) {
testAsyncUDPRecvmsg(false);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment