1use alloc::collections::BTreeMap;
10use alloc::string::{String, ToString};
11use alloc::vec::Vec;
12use alloc::sync::{Arc, Weak};
13use alloc::format;
14use core::sync::atomic::{AtomicU64, Ordering};
15use spin::RwLock;
16
17use super::core::{VfsEntry, FileSystemOperations};
18use super::manager::{VfsManager, PathResolutionOptions};
19use crate::fs::{FileSystemError, FileSystemErrorKind};
20
21pub type VfsResult<T> = Result<T, FileSystemError>;
22pub type VfsEntryRef = Arc<VfsEntry>;
23pub type VfsEntryWeakRef = Weak<VfsEntry>;
24
25
26fn vfs_error(kind: FileSystemErrorKind, message: &str) -> FileSystemError {
28 FileSystemError::new(kind, message)
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
33pub struct MountId(u64);
34
35impl MountId {
36 fn new() -> Self {
37 static COUNTER: AtomicU64 = AtomicU64::new(1);
38 Self(COUNTER.fetch_add(1, Ordering::Relaxed))
39 }
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
44pub struct VfsManagerId(u64);
45
46impl VfsManagerId {
47 pub fn new() -> Self {
48 static COUNTER: AtomicU64 = AtomicU64::new(1);
49 Self(COUNTER.fetch_add(1, Ordering::Relaxed))
50 }
51}
52
53#[derive(Debug, Clone)]
55pub enum MountType {
56 Regular,
58 Bind,
60 Overlay {
62 layers: Vec<VfsEntryRef>,
64 },
65}
66
67#[derive(Debug, Clone, Default)]
69pub struct MountOptionsV2 {
70 pub readonly: bool,
71 pub flags: u32,
72}
73
74#[derive(Debug)]
76pub struct MountPoint {
77 pub id: MountId,
79 pub mount_type: MountType,
81 pub path: String,
83 pub root: VfsEntryRef,
85 pub parent: Option<Weak<MountPoint>>,
87 pub parent_entry: Option<VfsEntryRef>,
89 pub children: Arc<RwLock<BTreeMap<u64, Arc<MountPoint>>>>,
91}
92
93impl MountPoint {
94 pub fn new_regular(path: String, root: VfsEntryRef) -> Arc<Self> {
96 Arc::new(Self {
97 id: MountId::new(),
98 mount_type: MountType::Regular,
99 path,
100 root,
101 parent: None,
102 parent_entry: None,
103 children: Arc::new(RwLock::new(BTreeMap::new())),
104 })
105 }
106
107 pub fn new_bind(path: String, source: VfsEntryRef) -> Arc<Self> {
109 Arc::new(Self {
110 id: MountId::new(),
111 mount_type: MountType::Bind,
112 path,
113 root: source,
114 parent: None,
115 parent_entry: None,
116 children: Arc::new(RwLock::new(BTreeMap::new())),
117 })
118 }
119
120 pub fn new_overlay(path: String, layers: Vec<VfsEntryRef>) -> VfsResult<Arc<Self>> {
122 if layers.is_empty() {
123 return Err(vfs_error(FileSystemErrorKind::InvalidPath, "Overlay mount requires at least one layer"));
124 }
125
126 let root = layers[0].clone();
128
129 Ok(Arc::new(Self {
130 id: MountId::new(),
131 mount_type: MountType::Overlay {
132 layers: layers.clone(),
133 },
134 path,
135 root,
136 parent: None,
137 parent_entry: None,
138 children: Arc::new(RwLock::new(BTreeMap::new())),
139 }))
140 }
141
142 pub fn get_parent(&self) -> Option<Arc<MountPoint>> {
144 self.parent.as_ref().and_then(|weak| weak.upgrade())
145 }
146
147 pub fn is_root_mount(&self) -> bool {
149 self.parent.is_none()
150 }
151
152 pub fn get_child(&self, entry: &VfsEntryRef) -> Option<Arc<MountPoint>> {
154 let key = entry.node().id();
155 self.children.read().get(&key).cloned()
156 }
157
158 pub fn add_child(self: &Arc<Self>, entry: &VfsEntryRef, child: Arc<MountPoint>) -> VfsResult<()> {
160 let mut_child: *const MountPoint = Arc::as_ptr(&child);
162 unsafe {
163 let mut_child = mut_child as *mut MountPoint;
164 (*mut_child).parent = Some(Arc::downgrade(self));
165 (*mut_child).parent_entry = Some(entry.clone());
166 }
167 let key = entry.node().id();
168 self.children.write().insert(key, child);
169 Ok(())
170 }
171
172 pub fn remove_child(&self, entry: &VfsEntryRef) -> Option<Arc<MountPoint>> {
174 let key = entry.node().id();
175 self.children.write().remove(&key)
176 }
177
178 pub fn list_children(&self) -> Vec<u64> {
180 self.children.read().keys().cloned().collect()
181 }
182
183 pub fn is_bind_mount(&self) -> bool {
185 matches!(self.mount_type, MountType::Bind { .. })
186 }
187
188 pub fn get_bind_source(&self) -> Option<VfsEntryRef> {
190 match &self.mount_type {
191 MountType::Bind { .. } => Some(self.root.clone()),
192 _ => None,
193 }
194 }
195
196 pub fn get_cross_vfs_info(&self) -> Option<(Weak<VfsManager>, &str, u64)> {
198 match &self.mount_type {
199 MountType::Bind { .. } => {
200 None
201 }
202 _ => None,
203 }
204 }
205}
206
207#[derive(Debug)]
209pub struct MountTree {
210 pub root_mount: RwLock<Arc<MountPoint>>,
212}
213
214impl MountTree {
215 pub fn new(root_entry: VfsEntryRef) -> Self {
217 let root_mount = MountPoint::new_regular("/".to_string(), root_entry);
218 let root_id = root_mount.id;
219
220 let mut mounts = BTreeMap::new();
221 mounts.insert(root_id, Arc::downgrade(&root_mount));
222
223 Self {
224 root_mount: RwLock::new(root_mount.clone()),
225 }
226 }
227
228 pub fn bind_mount(
235 &self,
236 source_entry: VfsEntryRef,
237 target_entry: VfsEntryRef,
238 target_mount_point: Arc<MountPoint>,
239 ) -> VfsResult<MountId> {
240 let bind_mount = MountPoint::new_bind(target_entry.name().clone(), source_entry);
242 let mount_id = bind_mount.id;
243
244 target_mount_point.add_child(&target_entry, bind_mount.clone())?;
246
247 Ok(mount_id)
248 }
249
250 pub fn mount(
252 &self,
253 target_entry: VfsEntryRef,
254 target_mount_point: Arc<MountPoint>,
255 filesystem: Arc<dyn FileSystemOperations>,
256 ) -> VfsResult<MountId> {
257 let new_fs_root_node = filesystem.root_node();
259
260 let new_fs_root_entry = VfsEntry::new(None, "/".to_string(), new_fs_root_node);
262
263 let new_mount = MountPoint::new_regular(target_entry.name().clone(), new_fs_root_entry);
265 let mount_id = new_mount.id;
266
267 target_mount_point.add_child(&target_entry, new_mount.clone())?;
269
270 Ok(mount_id)
271 }
272
273 pub fn replace_root(&self, new_root: Arc<MountPoint>) {
275 *self.root_mount.write() = new_root.clone();
276 }
277
278 pub fn is_mount_point(&self, entry_to_check: &VfsEntryRef, mount_point_to_check: &Arc<MountPoint>) -> bool {
287 let children = mount_point_to_check.children.read();
308 children.contains_key(&entry_to_check.node().id())
309 }
310
311 pub fn is_bind_source(&self, entry_to_check: &VfsEntryRef) -> bool {
313 let node_to_check = entry_to_check.node();
314 let node_id = node_to_check.id();
315
316 let fs_ptr_to_check = match node_to_check.filesystem().and_then(|w| w.upgrade()) {
317 Some(fs) => Arc::as_ptr(&fs) as *const (),
318 None => return false,
319 };
320
321 false
322 }
323
324 pub fn is_entry_used_in_mount(&self, entry_to_check: &VfsEntryRef, mount_point_to_check: &Arc<MountPoint>) -> bool {
326 self.is_mount_point(entry_to_check, mount_point_to_check)
328 }
329
330 pub fn unmount(&self, entry: &VfsEntryRef, parent_mount_point: &Arc<MountPoint>) -> VfsResult<Arc<MountPoint>> {
332 let removed_mount = parent_mount_point.remove_child(&entry);
333 match removed_mount {
334 Some(mount) => Ok(mount),
335 None => Err(vfs_error(FileSystemErrorKind::NotFound, "Mount point not found for unmount")),
336 }
337 }
338
339 pub fn resolve_path(&self, path: &str) -> VfsResult<(VfsEntryRef, Arc<MountPoint>)> {
341 self.resolve_path_internal(path, false, &PathResolutionOptions { no_follow: false })
342 }
343
344 pub fn resolve_mount_point(&self, path: &str) -> VfsResult<(VfsEntryRef, Arc<MountPoint>)> {
347 self.resolve_path_internal(path, true, &PathResolutionOptions { no_follow: false })
348 }
349
350 pub fn resolve_path_with_options(&self, path: &str, options: &PathResolutionOptions) -> VfsResult<(VfsEntryRef, Arc<MountPoint>)> {
352 self.resolve_path_internal(path, false, options)
353 }
354
355 pub fn resolve_mount_point_with_options(&self, path: &str, options: &PathResolutionOptions) -> VfsResult<(VfsEntryRef, Arc<MountPoint>)> {
357 self.resolve_path_internal(path, true, options)
358 }
359
360 fn resolve_path_internal(&self, path: &str, resolve_mount: bool, options: &PathResolutionOptions) -> VfsResult<(VfsEntryRef, Arc<MountPoint>)> {
361 if path.is_empty() || path == "/" {
362 return Ok((self.root_mount.read().root.clone(), self.root_mount.read().clone()));
363 }
364
365 let components = self.parse_path(path);
366 let mut current_mount = self.root_mount.read().clone();
367 let mut current_entry = current_mount.root.clone();
368
369 let mut resolved_path = String::new();
370 for (i, component) in components.iter().enumerate() {
371 let is_final_component = i == components.len() - 1;
372
373 if component == ".." {
374 let is_at_mount_root = current_entry.node().id() == current_mount.root.node().id();
376
377 if is_at_mount_root {
378 let parent_info = current_mount.get_parent().zip(current_mount.parent_entry.clone());
379 match parent_info {
380 Some((parent_mount, parent_entry)) => {
381 current_mount = parent_mount;
382 current_entry = self.resolve_component(parent_entry, &"..")?;
383 },
384 None => {
385 }
387 }
388 } else {
389 current_entry = self.resolve_component(current_entry, &component)?;
390 }
391 } else {
392 let should_follow_symlinks = if is_final_component {
394 !options.no_follow
396 } else {
397 true
399 };
400
401 if should_follow_symlinks {
402 current_entry = self.resolve_component(current_entry, &component)?;
404 } else {
405 current_entry = self.resolve_component_no_symlink(current_entry, &component)?;
407 }
408
409 if resolve_mount && is_final_component {
411 if let Some(_child_mount) = current_mount.get_child(¤t_entry) {
412 return Ok((current_entry, current_mount));
413 }
414 } else {
415 if let Some(child_mount) = current_mount.get_child(¤t_entry) {
416 current_mount = child_mount;
417 current_entry = current_mount.root.clone();
418 }
419 }
420 }
421
422 resolved_path.push('/');
423 resolved_path.push_str(&component);
424 }
425
426 Ok((current_entry, current_mount))
427 }
428
429 fn resolve_component_no_symlink(&self, entry: VfsEntryRef, component: &str) -> VfsResult<VfsEntryRef> {
431 if component == "." {
433 return Ok(entry);
434 }
435
436 let component_string = component.to_string();
438 if let Some(cached_child) = entry.get_child(&component_string) {
439 return Ok(cached_child);
440 }
441
442 let parent_node = entry.node();
444 debug_assert!(parent_node.filesystem().is_some(), "resolve_component_no_symlink: parent_node.filesystem() is None");
445 let filesystem = parent_node.filesystem()
446 .and_then(|w| w.upgrade())
447 .ok_or_else(|| vfs_error(FileSystemErrorKind::NotSupported, "No filesystem reference"))?;
448
449 let child_node = filesystem.lookup(&parent_node, &component_string)
451 .map_err(|e| vfs_error(e.kind, &e.message))?;
452
453 let child_entry = VfsEntry::new(
455 Some(Arc::downgrade(&entry)),
456 component_string.clone(),
457 child_node,
458 );
459
460 entry.add_child(component_string, child_entry.clone());
462
463 Ok(child_entry)
464 }
465
466 pub fn parse_path(&self, path: &str) -> Vec<String> {
470 path.split('/')
471 .filter(|s| !s.is_empty() && *s != ".")
472 .map(|s| s.to_string())
473 .collect()
474 }
475
476 fn get_mount_path(&self, mount: &Arc<MountPoint>) -> String {
478 if mount.is_root_mount() {
479 return "/".to_string();
480 }
481
482 let mut components = Vec::new();
483 let mut current = Some(mount.clone());
484
485 while let Some(mount) = current {
486 if !mount.is_root_mount() {
487 components.push(mount.path.clone());
488 current = mount.get_parent();
489 } else {
490 break;
491 }
492 }
493
494 components.reverse();
495 if components.is_empty() {
496 "/".to_string()
497 } else {
498 format!("/{}", components.join("/"))
499 }
500 }
501
502 fn resolve_component(&self, entry: VfsEntryRef, component: &str) -> VfsResult<VfsEntryRef> {
504 self.resolve_component_with_depth(entry, component, 0)
505 }
506
507 fn resolve_component_with_depth(&self, entry: VfsEntryRef, component: &str, symlink_depth: u32) -> VfsResult<VfsEntryRef> {
509 const MAX_SYMLINK_DEPTH: u32 = 32; if symlink_depth > MAX_SYMLINK_DEPTH {
512 return Err(vfs_error(FileSystemErrorKind::InvalidPath, "Too many symbolic links"));
513 }
514
515 if component == "." {
517 return Ok(entry);
518 }
519
520 let component_string = component.to_string();
522 if let Some(cached_child) = entry.get_child(&component_string) {
523 if cached_child.node().is_symlink()? {
525 let link_target = cached_child.node().read_link()
526 .map_err(|e| vfs_error(e.kind, &e.message))?;
527 return self.resolve_symlink_target_with_depth(&entry, &link_target, symlink_depth + 1);
528 }
529 return Ok(cached_child);
530 }
531
532 let parent_node = entry.node();
534 debug_assert!(parent_node.filesystem().is_some(), "resolve_component: parent_node.filesystem() is None");
535 let filesystem = parent_node.filesystem()
536 .and_then(|w| w.upgrade())
537 .ok_or_else(|| vfs_error(FileSystemErrorKind::NotSupported, "No filesystem reference"))?;
538 let child_node = filesystem.lookup(&parent_node, &component_string)
540 .map_err(|e| vfs_error(e.kind, &e.message))?;
541
542 if child_node.is_symlink()? {
544 let link_target = child_node.read_link()
546 .map_err(|e| vfs_error(e.kind, &e.message))?;
547
548 return self.resolve_symlink_target_with_depth(&entry, &link_target, symlink_depth + 1);
550 }
551
552 let child_entry = VfsEntry::new(
554 Some(Arc::downgrade(&entry)),
555 component_string.clone(),
556 child_node,
557 );
558
559 entry.add_child(component_string, child_entry.clone());
561
562 Ok(child_entry)
563 }
564
565 fn resolve_symlink_target(&self, base_entry: &VfsEntryRef, target: &str) -> VfsResult<VfsEntryRef> {
567 self.resolve_symlink_target_with_depth(base_entry, target, 0)
568 }
569
570 fn resolve_symlink_target_with_depth(&self, base_entry: &VfsEntryRef, target: &str, symlink_depth: u32) -> VfsResult<VfsEntryRef> {
572 const MAX_SYMLINK_DEPTH: u32 = 32; if symlink_depth > MAX_SYMLINK_DEPTH {
575 return Err(vfs_error(FileSystemErrorKind::InvalidPath, "Too many symbolic links"));
576 }
577
578 if target.starts_with('/') {
579 let (resolved_entry, _mount) = self.resolve_path_internal(target, false, &PathResolutionOptions { no_follow: false })?;
581 Ok(resolved_entry)
582 } else {
583 let components = self.parse_path(target);
585 let mut current_entry = base_entry.clone();
586
587 for component in components {
588 current_entry = self.resolve_component_with_depth(current_entry, &component, symlink_depth)?;
589 }
590
591 Ok(current_entry)
592 }
593 }
594
595 }