2#include "pedigree/kernel/process/Process.h"
3#include "pedigree/kernel/process/TerminationDeferral.h"
4#include "pedigree/kernel/process/Thread.h"
5#include "pedigree/kernel/processor/Processor.h"
6#include "pedigree/kernel/processor/ProcessorInformation.h"
7#include "pedigree/kernel/syscallError.h"
11#include "FileDescriptor.h"
12#include "PosixSubsystem.h"
13#include "file-sync-syscalls.h"
14#include "modules/system/vfs/File.h"
17constexpr uint64_t MaximumPosition = 0x7fffffffffffffffULL;
18constexpr size_t PrefetchWindow = 2 * 1024 * 1024;
19constexpr int AdviceNormal = 0, AdviceWillNeed = 3, AdviceNoReuse = 5;
24 if (!subsystem || !subsystem->acquireFileDescriptor(fd, descriptor) ||
26 SYSCALL_ERROR(BadFileDescriptor);
32int finishSync(
Thread* thread,
bool succeeded) {
35 SYSCALL_ERROR(IoError);
42int prefetch(
File* file, uint64_t offset, uint64_t length,
bool throughEof) {
46 const uint64_t size = file->getSize();
49 uint64_t count = size - offset;
50 if (!throughEof && length < count)
52 if (count > PrefetchWindow)
53 count = PrefetchWindow;
55 const uint64_t read = file->
read(offset, count, 0);
56 return finishSync(thread, read == count);
60int posix_fdatasync(
int fd) {
63 if (!acquireSyncDescriptor(fd, descriptor))
65 File* file = descriptor->getFile();
67 SYSCALL_ERROR(InvalidArgument);
73 return finishSync(thread, file->
sync());
76int posix_readahead(
int fd, off_t offset,
size_t count) {
79 if (!acquireSyncDescriptor(fd, descriptor))
82 if (access != O_RDONLY && access != O_RDWR) {
83 SYSCALL_ERROR(BadFileDescriptor);
86 File* file = descriptor->getFile();
88 SYSCALL_ERROR(InvalidArgument);
92 return prefetch(file, offset, count, !count);
95int posix_fadvise64(
int fd, off_t offset, off_t length,
int advice) {
98 if (!acquireSyncDescriptor(fd, descriptor))
100 File* file = descriptor->getFile();
102 SYSCALL_ERROR(IllegalSeek);
106 advice < AdviceNormal || advice > AdviceNoReuse) {
107 SYSCALL_ERROR(InvalidArgument);
110 if (advice != AdviceWillNeed) {
111 SYSCALL_ERROR(OperationNotSupported);
114 return prefetch(file, offset, length, !length);
117int posix_sync_file_range(
int fd, off_t offset, off_t length,
unsigned flags) {
120 if (!acquireSyncDescriptor(fd, descriptor))
122 constexpr unsigned ValidFlags = 1 | 2 | 4;
123 if ((flags & ~ValidFlags) || offset < 0 || length < 0 ||
124 static_cast<uint64_t
>(length) > MaximumPosition -
static_cast<uint64_t
>(offset)) {
125 SYSCALL_ERROR(InvalidArgument);
128 File* file = descriptor->getFile();
130 SYSCALL_ERROR(IllegalSeek);
138 return finishSync(thread, file->
syncRange(offset, length));
int getStatusFlags() const
Get current status flags.
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
bool supportsRegularFileOperations()
bool syncRange(size_t offset, size_t length)
virtual bool isDirectory()
virtual bool isFifo() const
virtual bool isPipe() const
static ProcessorInformation & information()
void setErrno(size_t err)
Process * getParent() const