mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-03 07:10:08 +01:00
[orbis-kernel] implement unlink, nmount/unmount nullfs
This commit is contained in:
parent
5a7d4dee1e
commit
afc865cc69
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -30,6 +31,7 @@
|
|||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sys/prctl.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
|
@ -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);
|
||||
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue