Skip to content

Commit

Permalink
Adding support of the rename syscall to the IoUringBackend
Browse files Browse the repository at this point in the history
Summary: Make it possible to use the rename syscall within the IoUringBackend.

Reviewed By: yfeldblum

Differential Revision: D66766510

fbshipit-source-id: 29c7e2845c4e8e6ccb9b050a20c62a64a729af71
  • Loading branch information
Skory authored and facebook-github-bot committed Dec 5, 2024
1 parent 949a211 commit 30b63c1
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
8 changes: 8 additions & 0 deletions folly/io/async/IoUringBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,14 @@ void IoUringBackend::queueStatx(
submitImmediateIoSqe(*ioSqe);
}

void IoUringBackend::queueRename(
const char* oldPath, const char* newPath, FileOpCallback&& cb) {
auto* ioSqe = new FRenameIoSqe(this, oldPath, newPath, std::move(cb));
ioSqe->backendCb_ = processFileOpCB;

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));
Expand Down
23 changes: 23 additions & 0 deletions folly/io/async/IoUringBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ class IoUringBackend : public EventBaseBackendBase {
struct statx* statxbuf,
FileOpCallback&& cb);

void queueRename(
const char* oldPath, const char* newPath, FileOpCallback&& cb);

void queueFallocate(
int fd, int mode, off_t offset, off_t len, FileOpCallback&& cb);

Expand Down Expand Up @@ -936,6 +939,26 @@ class IoUringBackend : public EventBaseBackendBase {
struct statx* statxbuf_;
};

struct FRenameIoSqe : public FileOpIoSqe {
FRenameIoSqe(
IoUringBackend* backend,
const char* oldPath,
const char* newPath,
FileOpCallback&& cb)
: FileOpIoSqe(backend, -1, std::move(cb)),
oldPath_(oldPath),
newPath_(newPath) {}

void processSubmit(struct io_uring_sqe* sqe) noexcept override {
::io_uring_prep_rename(sqe, oldPath_, newPath_);
::io_uring_sqe_set_data(sqe, this);
}

const char* oldPath_;
const char* newPath_;
int flags_;
};

struct FAllocateIoSqe : public FileOpIoSqe {
FAllocateIoSqe(
IoUringBackend* backend,
Expand Down
106 changes: 106 additions & 0 deletions folly/io/async/test/IoUringBackendTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,112 @@ TEST(IoUringBackend, OpenAtAbsolutePath) {
evbPtr->loopForever();
}

TEST(IoUringBackend, Rename) {
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 oldName = folly::fs::unique_path();
auto newName = folly::fs::unique_path();
auto oldPath = dirPath / oldName;
auto newPath = dirPath / newName;

int fd = folly::fileops::open(
oldPath.string().c_str(), O_CREAT | O_WRONLY | O_TRUNC);
CHECK_GE(fd, 0);

SCOPE_EXIT {
folly::fileops::close(fd);
::unlink(oldPath.string().c_str());
::unlink(newPath.string().c_str());
};

folly::IoUringBackend::FileOpCallback renameCb = [&](int res) {
evbPtr->terminateLoopSoon();
CHECK_GE(res, 0);
EXPECT_TRUE(folly::fs::exists(newPath));
EXPECT_FALSE(folly::fs::exists(oldPath));
};

backendPtr->queueRename(
oldPath.string().c_str(), newPath.string().c_str(), std::move(renameCb));

evbPtr->loopForever();
}

TEST(IoUringBackend, RenameDstExists) {
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 oldName = folly::fs::unique_path();
auto newName = folly::fs::unique_path();
auto oldPath = dirPath / oldName;
auto newPath = dirPath / newName;

{
int oldFd = folly::fileops::open(
oldPath.string().c_str(), O_CREAT | O_WRONLY | O_TRUNC);
CHECK_GE(oldFd, 0);
folly::fileops::close(oldFd);
}

SCOPE_EXIT {
::unlink(oldPath.string().c_str());
};

{
int newFd = folly::fileops::open(
newPath.string().c_str(), O_CREAT | O_WRONLY | O_TRUNC);
CHECK_GE(newFd, 0);
folly::fileops::close(newFd);
}

folly::IoUringBackend::FileOpCallback renameCb = [&](int res) {
evbPtr->terminateLoopSoon();
CHECK_GE(res, 0);
EXPECT_TRUE(folly::fs::exists(newPath));
EXPECT_FALSE(folly::fs::exists(oldPath));
};

backendPtr->queueRename(
oldPath.string().c_str(), newPath.string().c_str(), std::move(renameCb));

evbPtr->loopForever();
}

TEST(IoUringBackend, RenameSrcDoesntExist) {
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 oldName = folly::fs::unique_path();
auto newName = folly::fs::unique_path();
auto oldPath = dirPath / oldName;
auto newPath = dirPath / newName;

folly::IoUringBackend::FileOpCallback renameCb = [&](int res) {
evbPtr->terminateLoopSoon();
CHECK_LT(res, 0);
EXPECT_FALSE(folly::fs::exists(newPath));
EXPECT_FALSE(folly::fs::exists(oldPath));
};

backendPtr->queueRename(
oldPath.string().c_str(), newPath.string().c_str(), std::move(renameCb));

evbPtr->loopForever();
}

TEST(IoUringBackend, Statx) {
auto evbPtr = getEventBase();
SKIP_IF(!evbPtr) << "Backend not available";
Expand Down

0 comments on commit 30b63c1

Please sign in to comment.