xref: /DragonOS/kernel/src/filesystem/vfs/utils.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
11074eb34SSamuel Dai use core::cmp::Ordering;
2*bd70d2d1SLoGin use core::fmt::{self, Debug};
31074eb34SSamuel Dai use core::hash::Hash;
41074eb34SSamuel Dai 
59b0abe6dSLoGin use alloc::{string::String, sync::Arc};
691e9d4abSLoGin use system_error::SystemError;
79b0abe6dSLoGin 
891e9d4abSLoGin use crate::process::ProcessControlBlock;
99b0abe6dSLoGin 
109b0abe6dSLoGin use super::{fcntl::AtFlags, FileType, IndexNode, ROOT_INODE};
119b0abe6dSLoGin 
12004e86ffSlogin /// @brief 切分路径字符串,返回最左侧那一级的目录名和剩余的部分。
13004e86ffSlogin ///
14004e86ffSlogin /// 举例:对于 /123/456/789/   本函数返回的第一个值为123, 第二个值为456/789
15bf4a4899SLoGin #[allow(dead_code)]
split_path(path: &str) -> (&str, Option<&str>)16004e86ffSlogin pub fn split_path(path: &str) -> (&str, Option<&str>) {
17004e86ffSlogin     let mut path_split: core::str::SplitN<&str> = path.trim_matches('/').splitn(2, "/");
18004e86ffSlogin     let comp = path_split.next().unwrap_or("");
19004e86ffSlogin     let rest_opt = path_split.next();
20004e86ffSlogin 
21004e86ffSlogin     return (comp, rest_opt);
22004e86ffSlogin }
23004e86ffSlogin 
24004e86ffSlogin /// @brief 切分路径字符串,返回最右侧那一级的目录名和剩余的部分。
25004e86ffSlogin ///
26004e86ffSlogin /// 举例:对于 /123/456/789/   本函数返回的第一个值为789, 第二个值为123/456
rsplit_path(path: &str) -> (&str, Option<&str>)27004e86ffSlogin pub fn rsplit_path(path: &str) -> (&str, Option<&str>) {
28004e86ffSlogin     let mut path_split: core::str::RSplitN<&str> = path.trim_matches('/').rsplitn(2, "/");
29004e86ffSlogin     let comp = path_split.next().unwrap_or("");
30004e86ffSlogin     let rest_opt = path_split.next();
31004e86ffSlogin 
32004e86ffSlogin     return (comp, rest_opt);
33004e86ffSlogin }
349b0abe6dSLoGin 
359b0abe6dSLoGin /// 根据dirfd和path,计算接下来开始lookup的inode和剩余的path
369b0abe6dSLoGin ///
379b0abe6dSLoGin /// ## 返回值
389b0abe6dSLoGin ///
39bf4a4899SLoGin /// 返回值为(需要执行lookup的inode, 剩余的path)
user_path_at( pcb: &Arc<ProcessControlBlock>, dirfd: i32, path: &str, ) -> Result<(Arc<dyn IndexNode>, String), SystemError>409b0abe6dSLoGin pub fn user_path_at(
419b0abe6dSLoGin     pcb: &Arc<ProcessControlBlock>,
429b0abe6dSLoGin     dirfd: i32,
430fb515b0SLoGin     path: &str,
449b0abe6dSLoGin ) -> Result<(Arc<dyn IndexNode>, String), SystemError> {
459b0abe6dSLoGin     let mut inode = ROOT_INODE();
460fb515b0SLoGin     let ret_path;
479b0abe6dSLoGin     // 如果path不是绝对路径,则需要拼接
489b0abe6dSLoGin     if path.as_bytes()[0] != b'/' {
499b0abe6dSLoGin         // 如果dirfd不是AT_FDCWD,则需要检查dirfd是否是目录
509b0abe6dSLoGin         if dirfd != AtFlags::AT_FDCWD.bits() {
519b0abe6dSLoGin             let binding = pcb.fd_table();
529b0abe6dSLoGin             let fd_table_guard = binding.read();
539b0abe6dSLoGin             let file = fd_table_guard
549b0abe6dSLoGin                 .get_file_by_fd(dirfd)
559b0abe6dSLoGin                 .ok_or(SystemError::EBADF)?;
569b0abe6dSLoGin 
579b0abe6dSLoGin             // drop guard 以避免无法调度的问题
589b0abe6dSLoGin             drop(fd_table_guard);
599b0abe6dSLoGin 
609b0abe6dSLoGin             // 如果dirfd不是目录,则返回错误码ENOTDIR
61dfe53cf0SGnoCiYeH             if file.file_type() != FileType::Dir {
629b0abe6dSLoGin                 return Err(SystemError::ENOTDIR);
639b0abe6dSLoGin             }
649b0abe6dSLoGin 
65dfe53cf0SGnoCiYeH             inode = file.inode();
660fb515b0SLoGin             ret_path = String::from(path);
679b0abe6dSLoGin         } else {
689b0abe6dSLoGin             let mut cwd = pcb.basic().cwd();
699b0abe6dSLoGin             cwd.push('/');
700fb515b0SLoGin             cwd.push_str(path);
710fb515b0SLoGin             ret_path = cwd;
729b0abe6dSLoGin         }
730fb515b0SLoGin     } else {
740fb515b0SLoGin         ret_path = String::from(path);
759b0abe6dSLoGin     }
769b0abe6dSLoGin 
770fb515b0SLoGin     return Ok((inode, ret_path));
789b0abe6dSLoGin }
791074eb34SSamuel Dai 
801074eb34SSamuel Dai /// Directory Name
811074eb34SSamuel Dai /// 可以用来作为原地提取目录名及比较的
821074eb34SSamuel Dai /// Dentry的对标(x
831074eb34SSamuel Dai ///
841074eb34SSamuel Dai /// 简单的生成一个新的DName,以实现简单的RCU
851074eb34SSamuel Dai #[derive(Debug)]
861074eb34SSamuel Dai pub struct DName(pub Arc<String>);
871074eb34SSamuel Dai 
881074eb34SSamuel Dai impl PartialEq for DName {
eq(&self, other: &Self) -> bool891074eb34SSamuel Dai     fn eq(&self, other: &Self) -> bool {
901074eb34SSamuel Dai         return *self.0 == *other.0;
911074eb34SSamuel Dai     }
921074eb34SSamuel Dai }
931074eb34SSamuel Dai impl Eq for DName {}
941074eb34SSamuel Dai 
951074eb34SSamuel Dai impl Hash for DName {
hash<H: core::hash::Hasher>(&self, state: &mut H)961074eb34SSamuel Dai     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
971074eb34SSamuel Dai         self.0.hash(state)
981074eb34SSamuel Dai     }
991074eb34SSamuel Dai }
1001074eb34SSamuel Dai 
1011074eb34SSamuel Dai impl PartialOrd for DName {
partial_cmp(&self, other: &Self) -> Option<Ordering>1021074eb34SSamuel Dai     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1031074eb34SSamuel Dai         Some(self.cmp(other))
1041074eb34SSamuel Dai     }
1051074eb34SSamuel Dai }
1061074eb34SSamuel Dai 
1071074eb34SSamuel Dai impl Ord for DName {
cmp(&self, other: &Self) -> Ordering1081074eb34SSamuel Dai     fn cmp(&self, other: &Self) -> Ordering {
1091074eb34SSamuel Dai         return self.0.cmp(&other.0);
1101074eb34SSamuel Dai     }
1111074eb34SSamuel Dai }
1121074eb34SSamuel Dai 
1131074eb34SSamuel Dai impl Default for DName {
default() -> Self1141074eb34SSamuel Dai     fn default() -> Self {
1151074eb34SSamuel Dai         Self(Arc::new(String::new()))
1161074eb34SSamuel Dai     }
1171074eb34SSamuel Dai }
1181074eb34SSamuel Dai 
1191074eb34SSamuel Dai impl From<String> for DName {
from(value: String) -> Self1201074eb34SSamuel Dai     fn from(value: String) -> Self {
1211074eb34SSamuel Dai         Self(Arc::from(value))
1221074eb34SSamuel Dai     }
1231074eb34SSamuel Dai }
1241074eb34SSamuel Dai 
1251074eb34SSamuel Dai impl From<&str> for DName {
from(value: &str) -> Self1261074eb34SSamuel Dai     fn from(value: &str) -> Self {
1271074eb34SSamuel Dai         Self(Arc::from(String::from(value)))
1281074eb34SSamuel Dai     }
1291074eb34SSamuel Dai }
1301074eb34SSamuel Dai 
1311074eb34SSamuel Dai impl Clone for DName {
clone(&self) -> Self1321074eb34SSamuel Dai     fn clone(&self) -> Self {
1331074eb34SSamuel Dai         Self(self.0.clone())
1341074eb34SSamuel Dai     }
1351074eb34SSamuel Dai }
1361074eb34SSamuel Dai 
137*bd70d2d1SLoGin impl fmt::Display for DName {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result138*bd70d2d1SLoGin     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139*bd70d2d1SLoGin         write!(f, "{}", self.0)
1401074eb34SSamuel Dai     }
1411074eb34SSamuel Dai }
1421074eb34SSamuel Dai 
1431074eb34SSamuel Dai impl AsRef<str> for DName {
as_ref(&self) -> &str1441074eb34SSamuel Dai     fn as_ref(&self) -> &str {
1451074eb34SSamuel Dai         self.0.as_str()
1461074eb34SSamuel Dai     }
1471074eb34SSamuel Dai }
148