The Pedigree Project 0.1
swap-syscalls.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "pedigree/kernel/process/TerminationDeferral.h"
3#include "pedigree/kernel/syscallError.h"
4
5#include <fcntl.h>
6
7#include "DevFs-block.h"
8#include "file-handle-syscalls.h"
10#include "swap-syscalls.h"
11
12namespace {
13int operate(const char* path, unsigned flags, bool enable) {
14 TerminationDeferral lifetime;
15 if (!posix_effective_root()) {
16 SYSCALL_ERROR(NotEnoughPermissions);
17 return -1;
18 }
19 if (flags & ~0x7ffffU) {
20 SYSCALL_ERROR(InvalidArgument);
21 return -1;
22 }
23 if (flags) {
24 SYSCALL_ERROR(OperationNotSupported);
25 return -1;
26 }
27 SwapStatus status;
28 {
29 PosixHandleTarget target;
30 if (!target.resolve(AT_FDCWD, path, true, false))
31 return -1;
32 if (!target.file->isBlockDevice()) {
33 SYSCALL_ERROR(NotABlockDevice);
34 return -1;
35 }
36 const uint64_t number = target.file->deviceNumber();
37 if (!PosixBlock::valid(number, PosixBlock::PhysicalMajor)) {
38 if (PosixBlock::valid(number, PosixBlock::MountedMajor))
39 SYSCALL_ERROR(DeviceBusy);
40 else
41 SYSCALL_ERROR(OperationNotSupported);
42 return -1;
43 }
44 const uint32_t endpoint = PosixBlock::minor(number);
45 auto& manager = MemoryMapManager::instance();
46 status = enable ? manager.activateSwap(endpoint) : manager.deactivateSwap(endpoint);
47 }
48 switch (status) {
49 case SwapStatus::Success:
50 syscallError(0);
51 return 0;
52 case SwapStatus::Unsupported:
53 SYSCALL_ERROR(OperationNotSupported);
54 break;
55 case SwapStatus::Busy:
56 SYSCALL_ERROR(DeviceBusy);
57 break;
58 case SwapStatus::NoMemory:
59 SYSCALL_ERROR(OutOfMemory);
60 break;
61 case SwapStatus::IoError:
62 SYSCALL_ERROR(IoError);
63 break;
64 default:
65 SYSCALL_ERROR(InvalidArgument);
66 break;
67 }
68 return -1;
69}
70} // namespace
71int posix_swapon(const char* path, int flags) {
72 return operate(path, static_cast<unsigned>(flags), true);
73}
74int posix_swapoff(const char* path) {
75 return operate(path, 0, false);
76}
Memory-mapped file interface.
static MemoryMapManager & instance()