pub async fn create_or_load_child_symlink_helper(
        &mut self,
        child_symlink_name: OsString,
        target_path_opt: Option<PathBuf>, // If not None, create symlink
    ) -> anyhow::Result<Self> {
        let ino = self.get_ino();
        let fd = self.fd;
        let dir_data = self.get_dir_data_mut();
        if let Some(ref target_path) = target_path_opt {
            debug_assert!(
                !dir_data.contains_key(&child_symlink_name),
                "create_or_load_child_symlink_helper() cannot create duplicated symlink name={:?}",
                child_symlink_name,
            );
            let child_symlink_name_clone = child_symlink_name.clone();
            let target_path_clone = target_path.clone();
            smol::unblock(move || {
                unistd::symlinkat(
                    &target_path_clone,
                    Some(fd),
                    child_symlink_name_clone.as_os_str(),
                )
            })
            .await
            .context(format!(
                "create_or_load_child_symlink_helper() failed to create symlink \
                    name={:?} to target path={:?} under parent ino={}",
                child_symlink_name, target_path, ino,
            ))?;
        };

        let child_symlink_name_clone = child_symlink_name.clone();
        let child_fd = Self::get_child_symlink_fd(fd, child_symlink_name_clone)
            .await
            .context(format!(
            "create_or_load_child_symlink_helper() failed to open symlink itself with name={:?} \
                under parent ino={}",
            child_symlink_name, ino,
        ))?;
        let child_attr = fs_util::load_attr(child_fd)
            // let child_attr = util::load_symlink_attr(fd, child_symlink_name.clone())
            .await
            .context(format!(
                "create_or_load_child_symlink_helper() failed to get the attribute of the new symlink={:?}",
                child_symlink_name,
            ))?;
        debug_assert_eq!(SFlag::S_IFLNK, child_attr.kind);

        let target_path = if let Some(target_path) = target_path_opt {
            // insert new entry to parent directory
            // TODO: support thread-safe
            let previous_value = dir_data.insert(
                child_symlink_name.clone(),
                DirEntry::new(child_attr.ino, child_symlink_name.clone(), SFlag::S_IFLNK),
            );
            debug_assert!(previous_value.is_none()); // double check creation race
            target_path
        } else {
            let child_symlink_name_clone = child_symlink_name.clone();
            let target_path_osstr =
                smol::unblock(move || fcntl::readlinkat(fd, child_symlink_name_clone.as_os_str()))
                    .await
                    .context(format!(
                        "create_or_load_child_symlink_helper() failed to open \
                            the new directory name={:?} under parent ino={}",
                        child_symlink_name, ino,
                    ))?;
            Path::new(&target_path_osstr).to_owned()
        };

        let mut full_path = OsString::clone(&self.full_path);
        full_path.push(OsString::clone(&child_symlink_name));

        Ok(Self::new(
            self.get_ino(),
            child_symlink_name,
            full_path,
            child_attr,
            // NodeData::SymLink(Box::new(SymLinkData::new(child_fd, target_path).await)),
            NodeData::SymLink(target_path),
            child_fd,
        ))
    }
/// Helper function to create or read symlink itself in a directory
Helper function to create or read symlink itself in a directory
Helper function to create or read symlink itself in a directory
pub async fn create_or_load_child_symlink_helper(
        &mut self,
        child_symlink_name: OsString,
        target_path_opt: Option<PathBuf>, // If not None, create symlink
    ) -> anyhow::Result<Self> {
        let ino = self.get_ino();
        let fd = self.fd;
        let dir_data = self.get_dir_data_mut();
        if let Some(ref target_path) = target_path_opt {
            debug_assert!(
                !dir_data.contains_key(&child_symlink_name),
                "create_or_load_child_symlink_helper() cannot create duplicated symlink name={:?}",
                child_symlink_name,
            );
            let child_symlink_name_clone = child_symlink_name.clone();
            let target_path_clone = target_path.clone();
            smol::unblock(move || {
                unistd::symlinkat(
                    &target_path_clone,
                    Some(fd),
                    child_symlink_name_clone.as_os_str(),
                )
            })
            .await
            .context(format!(
                "create_or_load_child_symlink_helper() failed to create symlink \
                    name={:?} to target path={:?} under parent ino={}",
                child_symlink_name, target_path, ino,
            ))?;
        };
        let child_symlink_name_clone = child_symlink_name.clone();
        let child_fd = Self::get_child_symlink_fd(fd, child_symlink_name_clone)
            .await
            .context(format!(
            "create_or_load_child_symlink_helper() failed to open symlink itself with name={:?} \
                under parent ino={}",
            child_symlink_name, ino,
        ))?;
        let child_attr = fs_util::load_attr(child_fd)
            // let child_attr = util::load_symlink_attr(fd, child_symlink_name.clone())
            .await
            .context(format!(
                "create_or_load_child_symlink_helper() failed to get the attribute of the new symlink={:?}",
                child_symlink_name,
            ))?;
        debug_assert_eq!(SFlag::S_IFLNK, child_attr.kind);
        let target_path = if let Some(target_path) = target_path_opt {
            // insert new entry to parent directory
            // TODO: support thread-safe
            let previous_value = dir_data.insert(
                child_symlink_name.clone(),
                DirEntry::new(child_attr.ino, child_symlink_name.clone(), SFlag::S_IFLNK),
            );
            debug_assert!(previous_value.is_none()); // double check creation race
            target_path
        } else {
            let child_symlink_name_clone = child_symlink_name.clone();
            let target_path_osstr =
                smol::unblock(move || fcntl::readlinkat(fd, child_symlink_name_clone.as_os_str()))
                    .await
                    .context(format!(
                        "create_or_load_child_symlink_helper() failed to open \
                            the new directory name={:?} under parent ino={}",
                        child_symlink_name, ino,
                    ))?;
            Path::new(&target_path_osstr).to_owned()
        };
        let mut full_path = OsString::clone(&self.full_path);
        full_path.push(OsString::clone(&child_symlink_name));
        Ok(Self::new(
            self.get_ino(),
            child_symlink_name,
            full_path,
            child_attr,
            // NodeData::SymLink(Box::new(SymLinkData::new(child_fd, target_path).await)),
            NodeData::SymLink(target_path),
            child_fd,
        ))
    }
pub async fn create_or_load_child_symlink_helper ( & mut self , child_symlink_name : OsString , target_path_opt : Option < PathBuf > , // If not None, create symlink ) -> anyhow :: Result < Self > { let ino = self . get_ino ( ) ; let fd = self . fd ; let dir_data = self . get_dir_data_mut ( ) ; if let Some ( ref target_path ) = target_path_opt { debug_assert ! ( dir_data contains_key ( child_symlink_name ) " " child_symlink_name ) ; let child_symlink_name_clone = child_symlink_name . clone ( ) ; let target_path_clone = target_path . clone ( ) ; smol :: unblock ( move | | { unistd :: symlinkat ( & target_path_clone , Some ( fd ) , child_symlink_name_clone . as_os_str ( ) , ) } ) . await . context ( format ! ( " \
 " child_symlink_name target_path ino ) ) ? ; } ; let child_symlink_name_clone = child_symlink_name . clone ( ) ; let child_fd = Self :: get_child_symlink_fd ( fd , child_symlink_name_clone ) . await . context ( format ! ( " \
 " child_symlink_name ino ) ) ? ; let child_attr = fs_util :: load_attr ( child_fd ) // let child_attr = util::load_symlink_attr(fd, child_symlink_name.clone()) . await . context ( format ! ( " " child_symlink_name ) ) ? ; debug_assert_eq ! ( SFlag S_IFLNK child_attr kind ) ; let target_path = if let Some ( target_path ) = target_path_opt { // insert new entry to parent directory // TODO: support thread-safe let previous_value = dir_data . insert ( child_symlink_name . clone ( ) , DirEntry :: new ( child_attr . ino , child_symlink_name . clone ( ) , SFlag :: S_IFLNK ) , ) ; debug_assert ! ( previous_value is_none ( ) ) ; // double check creation race target_path } else { let child_symlink_name_clone = child_symlink_name . clone ( ) ; let target_path_osstr = smol :: unblock ( move | | fcntl :: readlinkat ( fd , child_symlink_name_clone . as_os_str ( ) ) ) . await . context ( format ! ( " \
 " child_symlink_name ino ) ) ? ; Path :: new ( & target_path_osstr ) . to_owned ( ) } ; let mut full_path = OsString :: clone ( & self . full_path ) ; full_path . push ( OsString :: clone ( & child_symlink_name ) ) ; Ok ( Self :: new ( self . get_ino ( ) , child_symlink_name , full_path , child_attr , // NodeData::SymLink(Box::new(SymLinkData::new(child_fd, target_path).await)), NodeData :: SymLink ( target_path ) , child_fd , ) ) }
Helper function to create or read symlink itself in a directory
Helper function to create or read symlink itself in a directory
&mut self
child_symlink_name
OsString
target_path_opt
Option<PathBuf>
&mut self
child_symlink_name
OsString
target_path_opt
Option<PathBuf>