summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
authorGravatar comex2023-07-01 15:01:11 -0700
committerGravatar comex2023-07-01 15:01:11 -0700
commit98685d48e3cb9f25f6919f004ec62cadf33afad2 (patch)
tree9df2ce7f57370641589bfae7196c77b090bcbe0f /src/core/file_sys
parentPR feedback + constification (diff)
parentUpdate translations (2023-07-01) (#10972) (diff)
downloadyuzu-98685d48e3cb9f25f6919f004ec62cadf33afad2.tar.gz
yuzu-98685d48e3cb9f25f6919f004ec62cadf33afad2.tar.xz
yuzu-98685d48e3cb9f25f6919f004ec62cadf33afad2.zip
Merge remote-tracking branch 'origin/master' into ssl
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/patch_manager.cpp9
-rw-r--r--src/core/file_sys/vfs_concat.cpp14
-rw-r--r--src/core/file_sys/vfs_real.cpp101
-rw-r--r--src/core/file_sys/vfs_real.h22
4 files changed, 95 insertions, 51 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 4e61d4335..d3286b352 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -153,7 +153,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
153 const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); 153 const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
154 154
155 std::vector<VirtualDir> patch_dirs = {sdmc_load_dir}; 155 std::vector<VirtualDir> patch_dirs = {sdmc_load_dir};
156 if (load_dir != nullptr && load_dir->GetSize() > 0) { 156 if (load_dir != nullptr) {
157 const auto load_patch_dirs = load_dir->GetSubdirectories(); 157 const auto load_patch_dirs = load_dir->GetSubdirectories();
158 patch_dirs.insert(patch_dirs.end(), load_patch_dirs.begin(), load_patch_dirs.end()); 158 patch_dirs.insert(patch_dirs.end(), load_patch_dirs.begin(), load_patch_dirs.end());
159 } 159 }
@@ -354,8 +354,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
354 const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); 354 const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
355 const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); 355 const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
356 if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || 356 if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
357 ((load_dir == nullptr || load_dir->GetSize() <= 0) && 357 (load_dir == nullptr && sdmc_load_dir == nullptr)) {
358 (sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) {
359 return; 358 return;
360 } 359 }
361 360
@@ -496,7 +495,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
496 495
497 // General Mods (LayeredFS and IPS) 496 // General Mods (LayeredFS and IPS)
498 const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id); 497 const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id);
499 if (mod_dir != nullptr && mod_dir->GetSize() > 0) { 498 if (mod_dir != nullptr) {
500 for (const auto& mod : mod_dir->GetSubdirectories()) { 499 for (const auto& mod : mod_dir->GetSubdirectories()) {
501 std::string types; 500 std::string types;
502 501
@@ -540,7 +539,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
540 539
541 // SDMC mod directory (RomFS LayeredFS) 540 // SDMC mod directory (RomFS LayeredFS)
542 const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); 541 const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
543 if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0) { 542 if (sdmc_mod_dir != nullptr) {
544 std::string types; 543 std::string types;
545 if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"))) { 544 if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"))) {
546 AppendCommaIfNotEmpty(types, "LayeredExeFS"); 545 AppendCommaIfNotEmpty(types, "LayeredExeFS");
diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp
index 853b893a1..311a59e5f 100644
--- a/src/core/file_sys/vfs_concat.cpp
+++ b/src/core/file_sys/vfs_concat.cpp
@@ -150,23 +150,29 @@ std::size_t ConcatenatedVfsFile::Read(u8* data, std::size_t length, std::size_t
150 while (cur_length > 0 && it != concatenation_map.end()) { 150 while (cur_length > 0 && it != concatenation_map.end()) {
151 // Check if we can read the file at this position. 151 // Check if we can read the file at this position.
152 const auto& file = it->file; 152 const auto& file = it->file;
153 const u64 file_offset = it->offset; 153 const u64 map_offset = it->offset;
154 const u64 file_size = file->GetSize(); 154 const u64 file_size = file->GetSize();
155 155
156 if (cur_offset >= file_offset + file_size) { 156 if (cur_offset > map_offset + file_size) {
157 // Entirely out of bounds read. 157 // Entirely out of bounds read.
158 break; 158 break;
159 } 159 }
160 160
161 // Read the file at this position. 161 // Read the file at this position.
162 const u64 intended_read_size = std::min<u64>(cur_length, file_size); 162 const u64 file_seek = cur_offset - map_offset;
163 const u64 intended_read_size = std::min<u64>(cur_length, file_size - file_seek);
163 const u64 actual_read_size = 164 const u64 actual_read_size =
164 file->Read(data + (cur_offset - offset), intended_read_size, cur_offset - file_offset); 165 file->Read(data + (cur_offset - offset), intended_read_size, file_seek);
165 166
166 // Update tracking. 167 // Update tracking.
167 cur_offset += actual_read_size; 168 cur_offset += actual_read_size;
168 cur_length -= actual_read_size; 169 cur_length -= actual_read_size;
169 it++; 170 it++;
171
172 // If we encountered a short read, we're done.
173 if (actual_read_size < intended_read_size) {
174 break;
175 }
170 } 176 }
171 177
172 return cur_offset - offset; 178 return cur_offset - offset;
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 7a15d8438..b0515ec05 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -10,6 +10,7 @@
10#include "common/fs/fs.h" 10#include "common/fs/fs.h"
11#include "common/fs/path_util.h" 11#include "common/fs/path_util.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "core/file_sys/vfs.h"
13#include "core/file_sys/vfs_real.h" 14#include "core/file_sys/vfs_real.h"
14 15
15// For FileTimeStampRaw 16// For FileTimeStampRaw
@@ -72,8 +73,10 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
72 return VfsEntryType::File; 73 return VfsEntryType::File;
73} 74}
74 75
75VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { 76VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
77 Mode perms) {
76 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 78 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
79 std::scoped_lock lk{list_lock};
77 80
78 if (auto it = cache.find(path); it != cache.end()) { 81 if (auto it = cache.find(path); it != cache.end()) {
79 if (auto file = it->second.lock(); file) { 82 if (auto file = it->second.lock(); file) {
@@ -81,23 +84,30 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
81 } 84 }
82 } 85 }
83 86
84 if (!FS::Exists(path) || !FS::IsFile(path)) { 87 if (!size && !FS::IsFile(path)) {
85 return nullptr; 88 return nullptr;
86 } 89 }
87 90
88 auto reference = std::make_unique<FileReference>(); 91 auto reference = std::make_unique<FileReference>();
89 this->InsertReferenceIntoList(*reference); 92 this->InsertReferenceIntoListLocked(*reference);
90 93
91 auto file = 94 auto file = std::shared_ptr<RealVfsFile>(
92 std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, std::move(reference), path, perms)); 95 new RealVfsFile(*this, std::move(reference), path, perms, size));
93 cache[path] = file; 96 cache[path] = file;
94 97
95 return file; 98 return file;
96} 99}
97 100
101VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
102 return OpenFileFromEntry(path_, {}, perms);
103}
104
98VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { 105VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) {
99 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 106 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
100 cache.erase(path); 107 {
108 std::scoped_lock lk{list_lock};
109 cache.erase(path);
110 }
101 111
102 // Current usages of CreateFile expect to delete the contents of an existing file. 112 // Current usages of CreateFile expect to delete the contents of an existing file.
103 if (FS::IsFile(path)) { 113 if (FS::IsFile(path)) {
@@ -127,8 +137,11 @@ VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_
127VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { 137VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) {
128 const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); 138 const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault);
129 const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); 139 const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault);
130 cache.erase(old_path); 140 {
131 cache.erase(new_path); 141 std::scoped_lock lk{list_lock};
142 cache.erase(old_path);
143 cache.erase(new_path);
144 }
132 if (!FS::RenameFile(old_path, new_path)) { 145 if (!FS::RenameFile(old_path, new_path)) {
133 return nullptr; 146 return nullptr;
134 } 147 }
@@ -137,7 +150,10 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_
137 150
138bool RealVfsFilesystem::DeleteFile(std::string_view path_) { 151bool RealVfsFilesystem::DeleteFile(std::string_view path_) {
139 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 152 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
140 cache.erase(path); 153 {
154 std::scoped_lock lk{list_lock};
155 cache.erase(path);
156 }
141 return FS::RemoveFile(path); 157 return FS::RemoveFile(path);
142} 158}
143 159
@@ -176,14 +192,17 @@ bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) {
176 return FS::RemoveDirRecursively(path); 192 return FS::RemoveDirRecursively(path);
177} 193}
178 194
179void RealVfsFilesystem::RefreshReference(const std::string& path, Mode perms, 195std::unique_lock<std::mutex> RealVfsFilesystem::RefreshReference(const std::string& path,
180 FileReference& reference) { 196 Mode perms,
197 FileReference& reference) {
198 std::unique_lock lk{list_lock};
199
181 // Temporarily remove from list. 200 // Temporarily remove from list.
182 this->RemoveReferenceFromList(reference); 201 this->RemoveReferenceFromListLocked(reference);
183 202
184 // Restore file if needed. 203 // Restore file if needed.
185 if (!reference.file) { 204 if (!reference.file) {
186 this->EvictSingleReference(); 205 this->EvictSingleReferenceLocked();
187 206
188 reference.file = 207 reference.file =
189 FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile); 208 FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile);
@@ -193,12 +212,16 @@ void RealVfsFilesystem::RefreshReference(const std::string& path, Mode perms,
193 } 212 }
194 213
195 // Reinsert into list. 214 // Reinsert into list.
196 this->InsertReferenceIntoList(reference); 215 this->InsertReferenceIntoListLocked(reference);
216
217 return lk;
197} 218}
198 219
199void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference) { 220void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference) {
221 std::scoped_lock lk{list_lock};
222
200 // Remove from list. 223 // Remove from list.
201 this->RemoveReferenceFromList(*reference); 224 this->RemoveReferenceFromListLocked(*reference);
202 225
203 // Close the file. 226 // Close the file.
204 if (reference->file) { 227 if (reference->file) {
@@ -207,14 +230,14 @@ void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference
207 } 230 }
208} 231}
209 232
210void RealVfsFilesystem::EvictSingleReference() { 233void RealVfsFilesystem::EvictSingleReferenceLocked() {
211 if (num_open_files < MaxOpenFiles || open_references.empty()) { 234 if (num_open_files < MaxOpenFiles || open_references.empty()) {
212 return; 235 return;
213 } 236 }
214 237
215 // Get and remove from list. 238 // Get and remove from list.
216 auto& reference = open_references.back(); 239 auto& reference = open_references.back();
217 this->RemoveReferenceFromList(reference); 240 this->RemoveReferenceFromListLocked(reference);
218 241
219 // Close the file. 242 // Close the file.
220 if (reference.file) { 243 if (reference.file) {
@@ -223,10 +246,10 @@ void RealVfsFilesystem::EvictSingleReference() {
223 } 246 }
224 247
225 // Reinsert into closed list. 248 // Reinsert into closed list.
226 this->InsertReferenceIntoList(reference); 249 this->InsertReferenceIntoListLocked(reference);
227} 250}
228 251
229void RealVfsFilesystem::InsertReferenceIntoList(FileReference& reference) { 252void RealVfsFilesystem::InsertReferenceIntoListLocked(FileReference& reference) {
230 if (reference.file) { 253 if (reference.file) {
231 open_references.push_front(reference); 254 open_references.push_front(reference);
232 } else { 255 } else {
@@ -234,7 +257,7 @@ void RealVfsFilesystem::InsertReferenceIntoList(FileReference& reference) {
234 } 257 }
235} 258}
236 259
237void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) { 260void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference) {
238 if (reference.file) { 261 if (reference.file) {
239 open_references.erase(open_references.iterator_to(reference)); 262 open_references.erase(open_references.iterator_to(reference));
240 } else { 263 } else {
@@ -243,10 +266,10 @@ void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) {
243} 266}
244 267
245RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, 268RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
246 const std::string& path_, Mode perms_) 269 const std::string& path_, Mode perms_, std::optional<u64> size_)
247 : base(base_), reference(std::move(reference_)), path(path_), 270 : base(base_), reference(std::move(reference_)), path(path_),
248 parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)), 271 parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)),
249 perms(perms_) {} 272 size(size_), perms(perms_) {}
250 273
251RealVfsFile::~RealVfsFile() { 274RealVfsFile::~RealVfsFile() {
252 base.DropReference(std::move(reference)); 275 base.DropReference(std::move(reference));
@@ -257,12 +280,15 @@ std::string RealVfsFile::GetName() const {
257} 280}
258 281
259std::size_t RealVfsFile::GetSize() const { 282std::size_t RealVfsFile::GetSize() const {
260 base.RefreshReference(path, perms, *reference); 283 if (size) {
261 return reference->file ? reference->file->GetSize() : 0; 284 return *size;
285 }
286 return FS::GetSize(path);
262} 287}
263 288
264bool RealVfsFile::Resize(std::size_t new_size) { 289bool RealVfsFile::Resize(std::size_t new_size) {
265 base.RefreshReference(path, perms, *reference); 290 size.reset();
291 auto lk = base.RefreshReference(path, perms, *reference);
266 return reference->file ? reference->file->SetSize(new_size) : false; 292 return reference->file ? reference->file->SetSize(new_size) : false;
267} 293}
268 294
@@ -279,7 +305,7 @@ bool RealVfsFile::IsReadable() const {
279} 305}
280 306
281std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { 307std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const {
282 base.RefreshReference(path, perms, *reference); 308 auto lk = base.RefreshReference(path, perms, *reference);
283 if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) { 309 if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) {
284 return 0; 310 return 0;
285 } 311 }
@@ -287,7 +313,8 @@ std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset)
287} 313}
288 314
289std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { 315std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) {
290 base.RefreshReference(path, perms, *reference); 316 size.reset();
317 auto lk = base.RefreshReference(path, perms, *reference);
291 if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) { 318 if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) {
292 return 0; 319 return 0;
293 } 320 }
@@ -309,10 +336,11 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
309 336
310 std::vector<VirtualFile> out; 337 std::vector<VirtualFile> out;
311 338
312 const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { 339 const FS::DirEntryCallable callback = [this,
313 const auto full_path_string = FS::PathToUTF8String(full_path); 340 &out](const std::filesystem::directory_entry& entry) {
341 const auto full_path_string = FS::PathToUTF8String(entry.path());
314 342
315 out.emplace_back(base.OpenFile(full_path_string, perms)); 343 out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms));
316 344
317 return true; 345 return true;
318 }; 346 };
@@ -330,8 +358,9 @@ std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDi
330 358
331 std::vector<VirtualDir> out; 359 std::vector<VirtualDir> out;
332 360
333 const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { 361 const FS::DirEntryCallable callback = [this,
334 const auto full_path_string = FS::PathToUTF8String(full_path); 362 &out](const std::filesystem::directory_entry& entry) {
363 const auto full_path_string = FS::PathToUTF8String(entry.path());
335 364
336 out.emplace_back(base.OpenDirectory(full_path_string, perms)); 365 out.emplace_back(base.OpenDirectory(full_path_string, perms));
337 366
@@ -483,12 +512,10 @@ std::map<std::string, VfsEntryType, std::less<>> RealVfsDirectory::GetEntries()
483 512
484 std::map<std::string, VfsEntryType, std::less<>> out; 513 std::map<std::string, VfsEntryType, std::less<>> out;
485 514
486 const FS::DirEntryCallable callback = [&out](const std::filesystem::path& full_path) { 515 const FS::DirEntryCallable callback = [&out](const std::filesystem::directory_entry& entry) {
487 const auto filename = FS::PathToUTF8String(full_path.filename()); 516 const auto filename = FS::PathToUTF8String(entry.path().filename());
488
489 out.insert_or_assign(filename, 517 out.insert_or_assign(filename,
490 FS::IsDir(full_path) ? VfsEntryType::Directory : VfsEntryType::File); 518 entry.is_directory() ? VfsEntryType::Directory : VfsEntryType::File);
491
492 return true; 519 return true;
493 }; 520 };
494 521
diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h
index d8c900e33..26ea7df62 100644
--- a/src/core/file_sys/vfs_real.h
+++ b/src/core/file_sys/vfs_real.h
@@ -4,6 +4,8 @@
4#pragma once 4#pragma once
5 5
6#include <map> 6#include <map>
7#include <mutex>
8#include <optional>
7#include <string_view> 9#include <string_view>
8#include "common/intrusive_list.h" 10#include "common/intrusive_list.h"
9#include "core/file_sys/mode.h" 11#include "core/file_sys/mode.h"
@@ -20,6 +22,8 @@ struct FileReference : public Common::IntrusiveListBaseNode<FileReference> {
20}; 22};
21 23
22class RealVfsFile; 24class RealVfsFile;
25class RealVfsDirectory;
26
23class RealVfsFilesystem : public VfsFilesystem { 27class RealVfsFilesystem : public VfsFilesystem {
24public: 28public:
25 RealVfsFilesystem(); 29 RealVfsFilesystem();
@@ -45,17 +49,24 @@ private:
45 std::map<std::string, std::weak_ptr<VfsFile>, std::less<>> cache; 49 std::map<std::string, std::weak_ptr<VfsFile>, std::less<>> cache;
46 ReferenceListType open_references; 50 ReferenceListType open_references;
47 ReferenceListType closed_references; 51 ReferenceListType closed_references;
52 std::mutex list_lock;
48 size_t num_open_files{}; 53 size_t num_open_files{};
49 54
50private: 55private:
51 friend class RealVfsFile; 56 friend class RealVfsFile;
52 void RefreshReference(const std::string& path, Mode perms, FileReference& reference); 57 std::unique_lock<std::mutex> RefreshReference(const std::string& path, Mode perms,
58 FileReference& reference);
53 void DropReference(std::unique_ptr<FileReference>&& reference); 59 void DropReference(std::unique_ptr<FileReference>&& reference);
54 void EvictSingleReference();
55 60
56private: 61private:
57 void InsertReferenceIntoList(FileReference& reference); 62 friend class RealVfsDirectory;
58 void RemoveReferenceFromList(FileReference& reference); 63 VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
64 Mode perms = Mode::Read);
65
66private:
67 void EvictSingleReferenceLocked();
68 void InsertReferenceIntoListLocked(FileReference& reference);
69 void RemoveReferenceFromListLocked(FileReference& reference);
59}; 70};
60 71
61// An implementation of VfsFile that represents a file on the user's computer. 72// An implementation of VfsFile that represents a file on the user's computer.
@@ -78,13 +89,14 @@ public:
78 89
79private: 90private:
80 RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference, 91 RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
81 const std::string& path, Mode perms = Mode::Read); 92 const std::string& path, Mode perms = Mode::Read, std::optional<u64> size = {});
82 93
83 RealVfsFilesystem& base; 94 RealVfsFilesystem& base;
84 std::unique_ptr<FileReference> reference; 95 std::unique_ptr<FileReference> reference;
85 std::string path; 96 std::string path;
86 std::string parent_path; 97 std::string parent_path;
87 std::vector<std::string> path_components; 98 std::vector<std::string> path_components;
99 std::optional<u64> size;
88 Mode perms; 100 Mode perms;
89}; 101};
90 102