MOS Source Code
Loading...
Searching...
No Matches
mount.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4
7
8#include <mos/hashmap.hpp>
9#include <mos/shared_ptr.hpp>
10#include <mos_stdlib.hpp>
11
12#define VFS_MOUNTPOINT_MAP_SIZE 256
15
23{
24 MOS_ASSERT(dentry);
25 MOS_ASSERT_X(dentry->name.empty(), "mounted root should not have a name");
26
27 if (dentry == root_dentry)
28 return dentry; // the root dentry is its own mountpoint
29
30 dentry_t *parent = dentry_parent(*dentry);
31 if (parent == NULL)
32 {
33 // root for some other fs trees
34 return NULL;
35 }
36
37 tree_foreach_child(dentry_t, child, parent)
38 {
39 if (child->is_mountpoint)
40 {
41 const auto mount = dentry_get_mount(child);
42 if (mount->root == dentry)
43 return child;
44 }
45 }
46
47 return NULL; // not found, possibly just have been unmounted
48}
49
51{
52 if (!dentry->is_mountpoint)
53 {
54 mos_warn("dentry is not a mountpoint");
55 return NULL;
56 }
57
58 const auto pmount = vfs_mountpoint_map.get(dentry);
59 if (!pmount)
60 {
61 mos_warn("mountpoint not found");
62 return NULL;
63 }
64
65 // otherwise the mountpoint must match the dentry
66 MOS_ASSERT((*pmount)->mountpoint == dentry);
67 return *pmount;
68}
69
70bool dentry_mount(dentry_t *mountpoint, dentry_t *root, filesystem_t *fs)
71{
72 MOS_ASSERT_X(root->name.empty(), "mountpoint already has a name");
73 MOS_ASSERT_X(dentry_parent(*root) == NULL, "mountpoint already has a parent");
74
75 dentry_ref(root);
76
77 tree_node(root)->parent = NULL;
78 if (dentry_parent(*mountpoint))
79 tree_node(root)->parent = tree_node(dentry_parent(*mountpoint));
80
81 mountpoint->is_mountpoint = true;
82
83 auto mount = mos::make_shared<mount_t>();
86 mount->root = root;
87 mount->superblock = root->inode->superblock;
88 mount->mountpoint = mountpoint;
89 mount->fs = fs;
90 vfs_mountpoint_map.insert(mountpoint, std::move(mount));
91 return true;
92}
93
94// remove root from the mount tree
96{
97 const auto mount = dentry_get_mount(dentry_root_get_mountpoint(root));
98 if (!mount)
99 return NULL;
100
101 dentry_t *mountpoint = mount->mountpoint;
102
103 vfs_mountpoint_map.remove(mount->mountpoint);
105 // delete mount; // TODO: verify if mount is correctly deleted
106 MOS_ASSERT(mount.use_count() == 1);
107 mountpoint->is_mountpoint = false;
108 return mountpoint;
109}
#define MOS_ASSERT_X(cond, msg,...)
Definition assert.hpp:15
#define MOS_ASSERT(cond)
Definition assert.hpp:14
#define mos_warn(fmt,...)
Definition assert.hpp:23
bool empty() const
Definition string.hpp:235
dentry_t * dentry_unmount(dentry_t *root)
Unmount a filesystem at the mountpoint.
Definition mount.cpp:95
bool dentry_mount(dentry_t *mountpoint, dentry_t *root, filesystem_t *fs)
Mount a filesystem at a mountpoint.
Definition mount.cpp:70
should_inline dentry_t * dentry_parent(const dentry_t &dentry)
Definition dentry.hpp:67
dentry_t * dentry_ref(dentry_t *dentry)
Increment the reference count of a dentry.
MOSAPI void linked_list_init(list_node_t *head_node)
Initialise a circular double linked list.
Definition list.cpp:15
MOSAPI void list_node_append(list_node_t *head, list_node_t *item)
Definition list.cpp:68
#define list_node(element)
Get the ‘list_node’ of a list element. This is exactly the reverse of ‘list_entry’ above.
Definition list.hpp:74
list_node_t list_head
A linked list head.
Definition list.hpp:23
MOSAPI void list_node_remove(list_node_t *link)
Definition list.cpp:26
dentry_t * root_dentry
Definition vfs.cpp:35
dentry_t * dentry_root_get_mountpoint(dentry_t *dentry)
Given a mounted root dentry, return the mountpoint dentry that points to it.
Definition mount.cpp:22
static mos::HashMap< const dentry_t *, ptr< mount_t > > vfs_mountpoint_map
Definition mount.cpp:13
ptr< mount_t > dentry_get_mount(const dentry_t *dentry)
Definition mount.cpp:50
list_head vfs_mountpoint_list
Definition mount.cpp:14
shared_ptr< T > make_shared(Args &&...args)
#define NULL
Definition pb_syshdr.h:46
mos::shared_ptr< T > ptr
superblock_t * superblock
mos::string name
bool is_mountpoint
inode_t * inode
superblock_t * superblock
#define tree_node(element)
Definition tree.hpp:29
#define tree_foreach_child(t, v, h)
Definition tree.hpp:36