The Pedigree Project 0.1
VFS-mount-view.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "pedigree/kernel/syscallError.h"
3#include "pedigree/kernel/utilities/Pointers.h"
4
5#include "MountView.h"
6
7VFS::NamespaceMutation::NamespaceMutation(VFS& vfs) : m_Vfs(vfs), m_Lock(vfs.m_PathMutationLock) {
8 __atomic_add_fetch(&m_Vfs.m_PathGeneration, 1, __ATOMIC_ACQ_REL);
9}
10VFS::NamespaceMutation::~NamespaceMutation() {
11 __atomic_add_fetch(&m_Vfs.m_PathGeneration, 1, __ATOMIC_RELEASE);
12}
13uint64_t VFS::NamespaceMutation::generation() const {
14 return m_Vfs.namespaceGeneration();
15}
16uint64_t VFS::namespaceGeneration() const {
17 return __atomic_load_n(&m_PathGeneration, __ATOMIC_ACQUIRE);
18}
19VfsMountView* VFS::mountView() const {
20 return __atomic_load_n(&m_MountView, __ATOMIC_ACQUIRE);
21}
23 auto* view = mountView();
24 if (!view)
25 return true;
26 if (!view->shutdown(ownedBackings))
27 return false;
28 __atomic_store_n(&m_MountView, static_cast<VfsMountView*>(nullptr), __ATOMIC_RELEASE);
29 delete view;
30 return true;
31}
32bool VFS::initialiseMountView() {
33 if (mountView())
34 return true;
36 if (!view || !view.get()->initialise(getRootFilesystem()))
37 return false;
38 FilesystemContextOwner bootstrap;
39 if (!view.get()->createBootContext(bootstrap))
40 return false;
41 auto context = bootstrap.reference();
43 Vector<FilesystemPathRef> importedPoints;
44 getMounts(mounts);
45 if (!importedPoints.tryReserve(mounts.count())) {
46 SYSCALL_ERROR(OutOfMemory);
47 return false;
48 }
50 options.requireDirectory = true;
51 options.crossFinalMount = false;
52 for (const auto& mount : mounts) {
53 if (!mount.path.length() || mount.path == "/")
54 continue;
55 Filesystem* backing = getFilesystemAt(mount.path);
57 if (!backing ||
58 !view.get()->resolve(context, FilesystemPathRef(), mount.path, options, point) ||
59 !view.get()->attach(context, point, backing))
60 return false;
61 importedPoints.pushBack(pedigree_std::move(point));
62 }
63 bootstrap.reset();
64 context.reset();
65 {
66 NamespaceMutation writer(*this);
67 if (m_MountView) {
68 SYSCALL_ERROR(DeviceBusy);
69 return false;
70 }
71 // Once imported, mount edges have one authority; stale raw reparses must
72 // not survive backing retirement or offer a second lookup namespace.
73 for (const auto& point : importedPoints)
74 Directory::fromFile(point->node())->setReparsePoint(nullptr);
75 __atomic_store_n(&m_MountView, view.releaseOwnership(), __ATOMIC_RELEASE);
76 }
77 return true;
78}
static UniquePointer< T > adopt(T *pointer)
Definition Pointers.h:101
Definition VFS.h:58
Filesystem * getFilesystemAt(const String &path) const
Definition VFS.cc:771
bool mount(Disk *pDisk, String &stableName, Filesystem **pMountedFs=nullptr)
Definition VFS.cc:418
void getMounts(Vector< MountSnapshot > &mounts) const
Definition VFS.cc:782
bool shutdownMountView(Vector< Filesystem * > &ownedBackings)
Filesystem * getRootFilesystem() const
Definition VFS.cc:670
uint64_t namespaceGeneration() const
A vector / dynamic array.
Definition Vector.h:33
void pushBack(const T &value)
Definition Vector.h:275
size_t count() const
Definition Vector.h:270