diff --git a/kernel/src/fs/path/mount.rs b/kernel/src/fs/path/mount.rs index 861528c5f..fd0b131db 100644 --- a/kernel/src/fs/path/mount.rs +++ b/kernel/src/fs/path/mount.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 +use hashbrown::HashMap; + use crate::{ fs::{ path::dentry::{Dentry, DentryKey, Dentry_}, @@ -8,28 +10,28 @@ use crate::{ prelude::*, }; -/// The MountNode can form a mount tree to maintain the mount information. +/// The `MountNode` is used to form a mount tree to maintain the mount information. pub struct MountNode { - /// Root Dentry_. + /// Root dentry. root_dentry: Arc, - /// Mountpoint Dentry_. A mount node can be mounted on one dentry of another mount node, + /// Mountpoint dentry. A mount node can be mounted on one dentry of another mount node, /// which makes the mount being the child of the mount node. - mountpoint_dentry: RwLock>>, + mountpoint_dentry: RwMutex>>, /// The associated FS. fs: Arc, /// The parent mount node. - parent: RwLock>>, + parent: RwMutex>>, /// Child mount nodes which are mounted on one dentry of self. - children: Mutex>>, + children: RwMutex>>, /// Reference to self. this: Weak, } impl MountNode { - /// Create a root mount node with an associated FS. + /// Creates a root mount node with an associated FS. /// - /// The root mount node is not mounted on other mount nodes(which means it has no - /// parent). The root inode of the fs will form the root dentryinner of it. + /// The root mount node is not mounted on other mount nodes (which means it has no + /// parent). The root inode of the fs will form the inner root dentry. /// /// It is allowed to create a mount node even if the fs has been provided to another /// mount node. It is the fs's responsibility to ensure the data consistency. @@ -48,15 +50,15 @@ impl MountNode { fn new(fs: Arc, parent_mount: Option>) -> Arc { Arc::new_cyclic(|weak_self| Self { root_dentry: Dentry_::new_root(fs.root_inode()), - mountpoint_dentry: RwLock::new(None), - parent: RwLock::new(parent_mount), - children: Mutex::new(BTreeMap::new()), + mountpoint_dentry: RwMutex::new(None), + parent: RwMutex::new(parent_mount), + children: RwMutex::new(HashMap::new()), fs, this: weak_self.clone(), }) } - /// Mount an fs on the mountpoint, it will create a new child mount node. + /// Mounts a fs on the mountpoint, it will create a new child mount node. /// /// If the given mountpoint has already been mounted, then its mounted child mount /// node will be updated. @@ -77,11 +79,11 @@ impl MountNode { let key = mountpoint.key(); let child_mount = Self::new(fs, Some(Arc::downgrade(mountpoint.mount_node()))); - self.children.lock().insert(key, child_mount.clone()); + self.children.write().insert(key, child_mount.clone()); Ok(child_mount) } - /// Unmount a child mount node from the mountpoint and return it. + /// Unmounts a child mount node from the mountpoint and returns it. /// /// The mountpoint should belong to this mount node, or an error is returned. pub fn unmount(&self, mountpoint: &Dentry) -> Result> { @@ -91,28 +93,28 @@ impl MountNode { let child_mount = self .children - .lock() + .write() .remove(&mountpoint.key()) .ok_or_else(|| Error::with_message(Errno::ENOENT, "can not find child mount"))?; Ok(child_mount) } - /// Clone a mount node with the an root `Dentry_`. + /// Clones a mount node with the an root `Dentry_`. /// /// The new mount node will have the same fs as the original one and /// have no parent and children. We should set the parent and children manually. fn clone_mount_node(&self, root_dentry: &Arc) -> Arc { Arc::new_cyclic(|weak_self| Self { root_dentry: root_dentry.clone(), - mountpoint_dentry: RwLock::new(None), - parent: RwLock::new(None), - children: Mutex::new(BTreeMap::new()), + mountpoint_dentry: RwMutex::new(None), + parent: RwMutex::new(None), + children: RwMutex::new(HashMap::new()), fs: self.fs.clone(), this: weak_self.clone(), }) } - /// Clone a mount tree starting from the specified root `Dentry_`. + /// Clones a mount tree starting from the specified root `Dentry_`. /// /// The new mount tree will replicate the structure of the original tree. /// The new tree is a separate entity rooted at the given `Dentry_`, @@ -134,7 +136,7 @@ impl MountNode { while let Some(old_mount) = stack.pop() { let new_parent_mount = new_stack.pop().unwrap().clone(); - let old_children = old_mount.children.lock(); + let old_children = old_mount.children.read(); for old_child_mount in old_children.values() { let mountpoint_dentry = old_child_mount.mountpoint_dentry().unwrap(); if !mountpoint_dentry.is_descendant_of(old_mount.root_dentry()) { @@ -145,7 +147,7 @@ impl MountNode { let key = mountpoint_dentry.key(); new_parent_mount .children - .lock() + .write() .insert(key, new_child_mount.clone()); new_child_mount.set_parent(&new_parent_mount); new_child_mount @@ -157,30 +159,30 @@ impl MountNode { new_root_mount.clone() } - /// Detach the mount node from the parent mount node. + /// Detaches the mount node from the parent mount node. fn detach_mount_node(&self) { if let Some(parent) = self.parent() { let parent = parent.upgrade().unwrap(); parent .children - .lock() + .write() .remove(&self.mountpoint_dentry().unwrap().key()); } } - /// Attach the mount node to the mountpoint. + /// Attaches the mount node to the mountpoint. fn attach_mount_node(&self, mountpoint: &Arc) { let key = mountpoint.key(); mountpoint .mount_node() .children - .lock() + .write() .insert(key, self.this()); self.set_parent(mountpoint.mount_node()); mountpoint.set_mountpoint(self.this()); } - /// Graft the mount node tree to the mountpoint. + /// Grafts the mount node tree to the mountpoint. pub fn graft_mount_node_tree(&self, mountpoint: &Arc) -> Result<()> { if mountpoint.type_() != InodeType::Dir { return_errno!(Errno::ENOTDIR); @@ -190,28 +192,28 @@ impl MountNode { Ok(()) } - /// Try to get a child mount node from the mountpoint. + /// Gets a child mount node from the mountpoint if any. pub fn get(&self, mountpoint: &Dentry) -> Option> { if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) { return None; } - self.children.lock().get(&mountpoint.key()).cloned() + self.children.read().get(&mountpoint.key()).cloned() } - /// Get the root `Dentry_` of this mount node. + /// Gets the root `Dentry_` of this mount node. pub fn root_dentry(&self) -> &Arc { &self.root_dentry } - /// Try to get the mountpoint `Dentry_` of this mount node. + /// Gets the mountpoint `Dentry_` of this mount node if any. pub fn mountpoint_dentry(&self) -> Option> { self.mountpoint_dentry.read().clone() } - /// Set the mountpoint. + /// Sets the mountpoint. /// /// In some cases we may need to reset the mountpoint of - /// the created MountNode, such as move mount. + /// the created `MountNode`, such as move mount. pub fn set_mountpoint_dentry(&self, inner: &Arc) { let mut mountpoint_dentry = self.mountpoint_dentry.write(); *mountpoint_dentry = Some(inner.clone()); @@ -219,7 +221,7 @@ impl MountNode { /// Flushes all pending filesystem metadata and cached file data to the device. pub fn sync(&self) -> Result<()> { - let children = self.children.lock(); + let children = self.children.read(); for child in children.values() { child.sync()?; } @@ -229,12 +231,12 @@ impl MountNode { Ok(()) } - /// Try to get the parent mount node. + /// Gets the parent mount node if any. pub fn parent(&self) -> Option> { self.parent.read().as_ref().cloned() } - /// Set the parent. + /// Sets the parent mount node. /// /// In some cases we may need to reset the parent of /// the created MountNode, such as move mount. @@ -243,12 +245,11 @@ impl MountNode { *parent = Some(Arc::downgrade(mount_node)); } - /// Get strong reference to self. fn this(&self) -> Arc { self.this.upgrade().unwrap() } - /// Get the associated fs. + /// Gets the associated fs. pub fn fs(&self) -> &Arc { &self.fs }