Skip to main content

embednfs/memfs/
hardlinks.rs

1use async_trait::async_trait;
2
3use crate::fs::*;
4
5use super::{InodeData, MemFs};
6
7#[async_trait]
8impl HardLinks<u64> for MemFs {
9    async fn link(
10        &self,
11        _ctx: &RequestContext,
12        source: &u64,
13        parent: &u64,
14        name: &str,
15    ) -> FsResult<()> {
16        let mut inner = self.inner.write().await;
17        let source_inode = inner.inodes.get(source).ok_or(FsError::Stale)?;
18        if source_inode.attrs.object_type == ObjectType::Directory {
19            return Err(FsError::IsDirectory);
20        }
21
22        let parent_inode = inner.inodes.get_mut(parent).ok_or(FsError::Stale)?;
23        match &mut parent_inode.data {
24            InodeData::Directory(entries) => {
25                if entries.contains_key(name) {
26                    return Err(FsError::AlreadyExists);
27                }
28                let _ = entries.insert(name.to_string(), *source);
29            }
30            _ => return Err(FsError::NotDirectory),
31        }
32        self.touch_change(&mut parent_inode.attrs);
33        parent_inode.attrs.mtime = Timestamp::now();
34        Self::recompute_link_counts(&mut inner);
35        Ok(())
36    }
37}