Skip to content

Commit

Permalink
[orbis-kernel] implement unlink, nmount/unmount nullfs
Browse files Browse the repository at this point in the history
  • Loading branch information
DHrpcs3 committed Nov 11, 2023
1 parent 5a7d4de commit afc865c
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 22 deletions.
5 changes: 5 additions & 0 deletions orbis-kernel/include/orbis/thread/ProcessOps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct Module;
struct timespec;
struct File;
struct MemoryProtection;
struct IoVec;

struct ProcessOps {
SysResult (*mmap)(Thread *thread, caddr_t addr, size_t len, sint prot,
Expand Down Expand Up @@ -40,6 +41,7 @@ struct ProcessOps {
Ref<File> *file);
SysResult (*shm_open)(Thread *thread, const char *path, sint flags, sint mode,
Ref<File> *file);
SysResult (*unlink)(Thread *thread, ptr<const char> path);
SysResult (*mkdir)(Thread *thread, ptr<const char> path, sint mode);
SysResult (*rmdir)(Thread *thread, ptr<const char> path);
SysResult (*rename)(Thread *thread, ptr<const char> from, ptr<const char> to);
Expand Down Expand Up @@ -70,6 +72,9 @@ struct ProcessOps {
SysResult (*thr_wake)(Thread *thread, slong id);
SysResult (*thr_set_name)(Thread *thread, slong id, ptr<const char> name);

SysResult (*unmount)(Thread *thread, ptr<char> path, sint flags);
SysResult (*nmount)(Thread *thread, ptr<IoVec> iovp, uint iovcnt, sint flags);

SysResult (*fork)(Thread *thread, slong status);
SysResult (*execve)(Thread *thread, ptr<char> fname, ptr<ptr<char>> argv,
ptr<ptr<char>> envv);
Expand Down
3 changes: 3 additions & 0 deletions orbis-kernel/src/sys/sys_vfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ orbis::SysResult orbis::sys_undelete(Thread *thread, ptr<char> path) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_unlink(Thread *thread, ptr<char> path) {
if (auto unlink = thread->tproc->ops->unlink) {
return unlink(thread, path);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_unlinkat(Thread *thread, sint fd, ptr<char> path,
Expand Down
24 changes: 10 additions & 14 deletions orbis-kernel/src/sys/sys_vfs_mount.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
#include "sys/sysproto.hpp"
#include "uio.hpp"
#include "utils/Logs.hpp"

orbis::SysResult orbis::sys_mount(Thread *thread, ptr<char> type,
ptr<char> path, sint flags, caddr_t data) {
return ErrorCode::NOSYS;
}

orbis::SysResult orbis::sys_unmount(Thread *thread, ptr<char> path,
sint flags) {
if (auto unmount = thread->tproc->ops->unmount) {
return unmount(thread, path, flags);
}

return ErrorCode::NOSYS;
}

orbis::SysResult orbis::sys_nmount(Thread *thread, ptr<IoVec> iovp, uint iovcnt,
sint flags) {
ORBIS_LOG_ERROR(__FUNCTION__, iovp, iovcnt, flags);

for (auto it = iovp; it < iovp + iovcnt; it += 2) {
IoVec a{}, b{};
uread(a, it);
uread(b, it + 1);

std::string aSv((char *)a.base, a.len);
std::string bSv((char *)b.base, b.len);

std::fprintf(stderr, "%s: '%s':'%s'\n", __FUNCTION__, aSv.c_str(), bSv.c_str());
if (auto nmount = thread->tproc->ops->nmount) {
return nmount(thread, iovp, iovcnt, flags);
}
return {};

return ErrorCode::NOSYS;
}
30 changes: 29 additions & 1 deletion rpcsx-os/io-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ struct HostFsDevice : IoDevice {
orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) override;
orbis::ErrorCode unlink(const char *path, bool recursive,
orbis::Thread *thread) override;
orbis::ErrorCode createSymlink(const char *target, const char *linkPath,
orbis::Thread *thread) override;
orbis::ErrorCode mkdir(const char *path, int mode,
orbis::Thread *thread) override;
orbis::ErrorCode rmdir(const char *path, orbis::Thread *thread) override;
Expand Down Expand Up @@ -291,7 +295,8 @@ static orbis::ErrorCode host_write(orbis::File *file, orbis::Uio *uio,
vec.push_back({.iov_base = entry.base, .iov_len = entry.len});
}

ssize_t cnt = ::pwritev(hostFile->hostFd, vec.data(), vec.size(), uio->offset);
ssize_t cnt =
::pwritev(hostFile->hostFd, vec.data(), vec.size(), uio->offset);

if (cnt < 0) {
for (auto io : vec) {
Expand Down Expand Up @@ -538,6 +543,29 @@ orbis::ErrorCode HostFsDevice::open(orbis::Ref<orbis::File> *file,
return {};
}

orbis::ErrorCode HostFsDevice::unlink(const char *path, bool recursive,
orbis::Thread *thread) {
std::error_code ec;

if (recursive) {
std::filesystem::remove_all(hostPath + "/" + path, ec);
} else {
std::filesystem::remove(hostPath + "/" + path, ec);
}

return convertErrorCode(ec);
}

orbis::ErrorCode HostFsDevice::createSymlink(const char *linkPath,
const char *target,
orbis::Thread *thread) {
std::error_code ec;
std::filesystem::create_symlink(
std::filesystem::absolute(hostPath + "/" + linkPath),
hostPath + "/" + target, ec);
return convertErrorCode(ec);
}

orbis::ErrorCode HostFsDevice::mkdir(const char *path, int mode,
orbis::Thread *thread) {
std::error_code ec;
Expand Down
13 changes: 10 additions & 3 deletions rpcsx-os/io-device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,23 @@ struct IoDevice : orbis::RcBase {
virtual orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) = 0;
virtual orbis::ErrorCode unlink(const char *path, orbis::Thread *thread) {
virtual orbis::ErrorCode unlink(const char *path, bool recursive,
orbis::Thread *thread) {
return orbis::ErrorCode::NOTSUP;
}
virtual orbis::ErrorCode mkdir(const char *path, int mode, orbis::Thread *thread) {
virtual orbis::ErrorCode createSymlink(const char *target, const char *linkPath,
orbis::Thread *thread) {
return orbis::ErrorCode::NOTSUP;
}
virtual orbis::ErrorCode mkdir(const char *path, int mode,
orbis::Thread *thread) {
return orbis::ErrorCode::NOTSUP;
}
virtual orbis::ErrorCode rmdir(const char *path, orbis::Thread *thread) {
return orbis::ErrorCode::NOTSUP;
}
virtual orbis::ErrorCode rename(const char *from, const char *to, orbis::Thread *thread) {
virtual orbis::ErrorCode rename(const char *from, const char *to,
orbis::Thread *thread) {
return orbis::ErrorCode::NOTSUP;
}
};
Expand Down
55 changes: 53 additions & 2 deletions rpcsx-os/ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "orbis/module/ModuleHandle.hpp"
#include "orbis/thread/Process.hpp"
#include "orbis/thread/Thread.hpp"
#include "orbis/uio.hpp"
#include "orbis/umtx.hpp"
#include "orbis/utils/Logs.hpp"
#include "orbis/utils/Rc.hpp"
Expand All @@ -30,6 +31,7 @@
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <sys/prctl.h>
#include <thread>
#include <unistd.h>
Expand Down Expand Up @@ -287,7 +289,9 @@ orbis::SysResult shm_open(orbis::Thread *thread, const char *path,
auto dev = static_cast<IoDevice *>(orbis::g_context.shmDevice.get());
return dev->open(file, path, flags, mode, thread);
}

orbis::SysResult unlink(orbis::Thread *thread, orbis::ptr<const char> path) {
return rx::vfs::unlink(path, thread);
}
orbis::SysResult mkdir(Thread *thread, ptr<const char> path, sint mode) {
ORBIS_LOG_TODO(__FUNCTION__, path, mode);
return rx::vfs::mkdir(path, mode, thread);
Expand Down Expand Up @@ -337,7 +341,7 @@ orbis::SysResult socket(orbis::Thread *thread, orbis::ptr<const char> name,

orbis::SysResult shm_unlink(orbis::Thread *thread, const char *path) {
auto dev = static_cast<IoDevice *>(orbis::g_context.shmDevice.get());
return dev->unlink(path, thread);
return dev->unlink(path, false, thread);
}

orbis::SysResult dynlib_get_obj_member(orbis::Thread *thread,
Expand Down Expand Up @@ -572,6 +576,50 @@ SysResult thr_set_name(orbis::Thread *thread, orbis::slong id,
ORBIS_LOG_WARNING(__FUNCTION__, name, id, thread->tid);
return {};
}

orbis::SysResult unmount(orbis::Thread *thread, orbis::ptr<char> path,
orbis::sint flags) {
// TODO: support other that nullfs
return rx::vfs::unlink(path, thread);
}
orbis::SysResult nmount(orbis::Thread *thread, orbis::ptr<orbis::IoVec> iovp,
orbis::uint iovcnt, orbis::sint flags) {
ORBIS_LOG_ERROR(__FUNCTION__, iovp, iovcnt, flags);

std::string_view fstype;
std::string_view fspath;
std::string_view target;

for (auto it = iovp; it < iovp + iovcnt; it += 2) {
IoVec a;
IoVec b;
ORBIS_RET_ON_ERROR(uread(a, it));
ORBIS_RET_ON_ERROR(uread(b, it + 1));

std::string_view key((char *)a.base, a.len - 1);
std::string_view value((char *)b.base, b.len - 1);

if (key == "fstype") {
fstype = value;
} else if (key == "fspath") {
fspath = value;
} else if (key == "target") {
target = value;
}

std::fprintf(stderr, "%s: '%s':'%s'\n", __FUNCTION__, key.data(),
value.data());
}

if (fstype == "nullfs") {
ORBIS_RET_ON_ERROR(rx::vfs::unlink(fspath, thread));
return rx::vfs::createSymlink(target, fspath, thread);
}

// TODO
return {};
}

orbis::SysResult exit(orbis::Thread *thread, orbis::sint status) {
std::printf("Requested exit with status %d\n", status);
std::exit(status);
Expand Down Expand Up @@ -794,6 +842,7 @@ ProcessOps rx::procOpsTable = {
.query_memory_protection = query_memory_protection,
.open = open,
.shm_open = shm_open,
.unlink = unlink,
.mkdir = mkdir,
.rmdir = rmdir,
.rename = rename,
Expand All @@ -815,6 +864,8 @@ ProcessOps rx::procOpsTable = {
.thr_suspend = thr_suspend,
.thr_wake = thr_wake,
.thr_set_name = thr_set_name,
.unmount = unmount,
.nmount = nmount,
.fork = fork,
.execve = execve,
.exit = exit,
Expand Down
45 changes: 44 additions & 1 deletion rpcsx-os/vfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ struct DevFs : IoDevice {
devPath.remove_prefix(pos + 1);

if (auto it = devices.find(deviceName); it != devices.end()) {
return it->second->open(file, std::string(devPath).c_str(), flags, mode, thread);
return it->second->open(file, std::string(devPath).c_str(), flags, mode,
thread);
}
} else {
if (auto it = devices.find(devPath); it != devices.end()) {
Expand Down Expand Up @@ -170,3 +171,45 @@ orbis::SysResult rx::vfs::rename(std::string_view from, std::string_view to,

return fromDevice->rename(fromDevPath.c_str(), toDevPath.c_str(), thread);
}

orbis::ErrorCode rx::vfs::unlink(std::string_view path, orbis::Thread *thread) {
auto [device, devPath] = get(path);
if (device == nullptr) {
return orbis::ErrorCode::NOENT;
}

return device->unlink(devPath.c_str(), false, thread);
}

orbis::ErrorCode rx::vfs::unlinkAll(std::string_view path,
orbis::Thread *thread) {
auto [device, devPath] = get(path);
if (device == nullptr) {
return orbis::ErrorCode::NOENT;
}

return device->unlink(devPath.c_str(), true, thread);
}

orbis::ErrorCode rx::vfs::createSymlink(std::string_view target,
std::string_view linkPath,
orbis::Thread *thread) {
auto [fromDevice, fromDevPath] = get(target);
if (fromDevice == nullptr) {
return orbis::ErrorCode::NOENT;
}

auto [targetDevice, toDevPath] = get(linkPath);
if (targetDevice == nullptr) {
return orbis::ErrorCode::NOENT;
}

if (fromDevice != targetDevice) {
std::fprintf(stderr, "cross fs operation: %s -> %s\n",
std::string(target).c_str(), std::string(linkPath).c_str());
std::abort();
}

return fromDevice->createSymlink(fromDevPath.c_str(), toDevPath.c_str(),
thread);
}
8 changes: 7 additions & 1 deletion rpcsx-os/vfs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ orbis::SysResult open(std::string_view path, int flags, int mode,
orbis::Ref<orbis::File> *file, orbis::Thread *thread);
orbis::SysResult mkdir(std::string_view path, int mode, orbis::Thread *thread);
orbis::SysResult rmdir(std::string_view path, orbis::Thread *thread);
orbis::SysResult rename(std::string_view from, std::string_view to, orbis::Thread *thread);
orbis::SysResult rename(std::string_view from, std::string_view to,
orbis::Thread *thread);
orbis::ErrorCode unlink(std::string_view path, orbis::Thread *thread);
orbis::ErrorCode unlinkAll(std::string_view path, orbis::Thread *thread);
orbis::ErrorCode createSymlink(std::string_view target,
std::string_view linkPath,
orbis::Thread *thread);
} // namespace rx::vfs

0 comments on commit afc865c

Please sign in to comment.