8#include "pedigree/kernel/LockGuard.h"
9#include "pedigree/kernel/syscallError.h"
11#include "FatFilesystem.h"
16 : m_Filesystem(filesystem), m_File(file), m_Size(size) {}
20 m_Filesystem.publishSize(&m_File, m_Size);
21 m_File.m_MetadataDirty =
true;
23 m_File.m_TrimPending =
true;
32bool FatFilesystem::prepareFileShrink(
FatFile* file,
size_t size,
36 SYSCALL_ERROR(ReadOnlyFilesystem);
39 uint32_t count = 0, last = 0;
40 if (!
m_BlockSize || size >= file->getSize() || !chainExtent(file, count, last) ||
41 uint64_t(count) * m_BlockSize < file->getSize()) {
42 SYSCALL_ERROR(IoError);
45 if (!isNodeUnlinked(file)) {
48 SYSCALL_ERROR(IoError);
55 SYSCALL_ERROR(OutOfMemory);
58 prepared = pedigree_std::move(plan);
62bool FatFilesystem::trimFileAllocation(
FatFile* file) {
63 if (!file->m_TrimPending)
65 bool succeeded =
true;
66 while (file->m_RetiredClusters.
count()) {
67 const uint32_t cluster = file->m_RetiredClusters[file->m_RetiredClusters.
count() - 1];
70 SYSCALL_ERROR(IoError);
75 file->m_RetiredClusters.
popBack();
76 succeeded = staged && succeeded;
78 if (!syncFat() || !succeeded) {
79 SYSCALL_ERROR(IoError);
82 uint32_t count = 0, last = 0;
83 if (!chainExtent(file, count, last)) {
84 SYSCALL_ERROR(IoError);
87 const size_t size = file->getSize();
90 file->m_TrimPending =
false;
93 uint32_t retained = file->getInode();
94 for (
size_t i = 1; i < keep; ++i)
97 if (!file->m_RetiredClusters.tryReserve(count - keep)) {
98 SYSCALL_ERROR(OutOfMemory);
101 uint32_t cluster = retired;
102 for (
size_t i = keep; i < count; ++i) {
103 file->m_RetiredClusters.
pushBack(cluster);
113 file->m_RetiredClusters.
clear();
114 SYSCALL_ERROR(IoError);
117 return trimFileAllocation(file);
120void FatFilesystem::truncate(
File* file) {
124bool FatFilesystem::truncateFile(
File* file) {
128void FatFilesystem::extend(
File* file,
size_t size) {
130 if (file->getSize() >= size)
133 SYSCALL_ERROR(ReadOnlyFilesystem);
136 if (size > UINT32_MAX) {
137 SYSCALL_ERROR(FileTooLarge);
140 if (!syncFat() || !ensureCapacity(file, size) || !zeroRange(file, file->getSize(), size) ||
141 !updateFileMetadata(file, size)) {
142 SYSCALL_ERROR(IoError);
145 publishSize(file, size);
uint32_t eofValue() const
Dir * getDirectoryEntry(uint32_t clus, uint32_t offset) const
uint32_t getClusterEntry(uint32_t cluster, bool bLock=true)
bool setClusterEntry(uint32_t cluster, uint32_t value, bool bLock=true, bool persist=true)
static UniquePointer< T > adopt(T *pointer)
void pushBack(const T &value)
void clear(bool freeMem=false)