The Pedigree Project 0.1
FatFilesystem-writeback.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "pedigree/kernel/machine/Disk.h"
3#include "pedigree/kernel/syscallError.h"
4
5#include "FatFilesystem.h"
6
7bool FatFilesystem::writeCachedPages(FatFile::State& state, const Cache::WritebackPage* pages,
8 size_t count) {
10 if (!tryAcquireOperation(operation)) {
11 return false;
12 }
14 if (state.retiring)
15 return true;
17 return false;
18 // Size is sampled inside the allocation lock: delayed writeback must never
19 // grow a file that was truncated after these pages were queued.
20 FatFile file(state);
21 Disk::WriteBuffer requests[Disk::MaxWriteBuffers];
22 size_t pending = 0;
23 bool succeeded = true;
24 auto drain = [&] {
25 if (pending)
26 succeeded = m_pDisk->writeFromBatch(requests, pending) && succeeded;
27 pending = 0;
28 };
29 for (size_t i = 0; i < count; ++i) {
30 const uint64_t location = pages[i].key;
31 if (location >= state.size)
32 continue;
33 size_t remaining =
34 pedigree_std::min(size_t(file.getBlockSize()), size_t(state.size - location));
35 uint32_t cluster = fileClusterAt(&file, location / m_BlockSize);
36 size_t offset = location % m_BlockSize;
37 uintptr_t source = pages[i].location;
38 while (remaining) {
39 if (cluster < 2 || cluster >= m_ClusterCount + 2 || isEof(cluster)) {
40 succeeded = false;
41 break;
42 }
43 const size_t length = pedigree_std::min(size_t(m_BlockSize - offset), remaining);
44 requests[pending++] = {
45 uint64_t(getSectorNumber(cluster)) * m_Superblock.BPB_BytsPerSec + offset,
46 reinterpret_cast<void*>(source), length, false};
47 if (pending == Disk::MaxWriteBuffers)
48 drain();
49 source += length;
50 remaining -= length;
51 offset = 0;
52 if (remaining)
53 cluster = getClusterEntry(cluster);
54 }
55 }
56 drain();
57 const bool durable = m_pDisk->syncData();
58 if (!succeeded || !durable) {
59 SYSCALL_ERROR(IoError);
60 return false;
61 }
62 return true;
63}
virtual MUST_USE_RESULT bool writeFromBatch(WriteBuffer *buffers, size_t count)
Definition Disk.cc:285
virtual MUST_USE_RESULT bool syncData()
Definition Disk.cc:299
uint32_t m_ClusterCount
Mutex m_FileMutationLock
uint32_t m_BlockSize
bool isEof(uint32_t cluster) const
uint32_t getClusterEntry(uint32_t cluster, bool bLock=true)
uint32_t getSectorNumber(uint32_t cluster) const
Superblock m_Superblock
Disk * m_pDisk
Definition Filesystem.h:188
bool m_bReadOnly
Definition Filesystem.h:186