The Pedigree Project 0.1
Ext2File-allocation.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "pedigree/kernel/LockGuard.h"
3#include "pedigree/kernel/syscallError.h"
4
5#include "Ext2File.h"
6#include "Ext2Filesystem.h"
7
8bool Ext2File::allocateFileRange(size_t offset, size_t length) {
9 LockGuard<Mutex> guard(m_State->writebackLock);
10 if (m_State->quotaFile) {
11 SYSCALL_ERROR(NotEnoughPermissions);
12 return false;
13 }
14 if (!m_State->allocationValid) {
15 SYSCALL_ERROR(IoError);
16 return false;
17 }
18 {
19#if THREADS || defined(STANDALONE_MUTEXES)
20 LockGuard<Mutex> allocation(m_pExt2Fs->m_WriteLock);
21#endif
22 // The allocator's legacy zero result conflates bitmap I/O failure and full
23 // storage. Preload the bitmaps so a failed read retains its specific error.
24 for (size_t group = 0; group < m_pExt2Fs->m_nGroupDescriptors; ++group) {
25 if (!m_pExt2Fs->ensureFreeBlockBitmapLoaded(group))
26 return false;
27 }
28 }
29 const size_t blockSize = m_pExt2Fs->m_BlockSize;
30 const size_t end = offset + length;
31 const size_t count = end / blockSize + (end % blockSize != 0);
32 if (count > m_Blocks.count()) {
33 if (!m_Blocks.tryReserve(count)) {
34 SYSCALL_ERROR(OutOfMemory);
35 return false;
36 }
37 // Preserve holes before the requested range. ensureWritableRange allocates
38 // and zeroes data before attaching each direct or indirect mapping.
39 while (m_Blocks.count() < count)
40 m_Blocks.pushBack(0);
41 }
42 const bool success = ensureWritableRange(offset, length);
43 if (!useFillCache()) {
44 // A native-block read may still have indexed the shared sparse zero block.
45 LockGuard<Mutex> index(cacheState().indexLock);
46 cacheState().data.clear();
47 }
48 return success;
49}
virtual bool useFillCache() const override
Definition Ext2File.cc:89
virtual bool allocateFileRange(size_t offset, size_t length) override
size_t m_nGroupDescriptors
void pushBack(const T &value)
Definition Vector.h:275
size_t count() const
Definition Vector.h:270