2024 春夏季开源操作系统训练营 阶段二 Lab4 实验报告

本次实验需要我们实现 sys_linkatsys_unlinkatsys_stat 这三个系统调用。

先从 sys_linkat 开始。这个系统调用的作用是创建一个文件的硬链接。所谓硬链接,就是多个目录项指向同一个 inode。从目录项来看,这是两个文件,并且也有不同的名称,但是他们实际上是同一个文件。

在之前的实现中,我们都是默认一个 inode 只会有一个目录项指向它,这很符合直觉,因为一个 inode 就代表一个文件,只会有一个名字。当 inode 对应的目录项被删除了,那么就代表这个 inode 也无效了,可以被释放掉。

而实现了硬链接之后,我们就需要修改 DiskInode 的内容,增加一个变量 nlink 来维护有多少个目录项指向该 inode,也就是有多少硬链接数。需要注意的是,为了保持 DiskInode 的大小不变,需要减小 dirent

接下来就是如何增加硬链接了。我们可以模仿查找文件的实现方法,通过旧文件名找到链接的 inode,增加其硬链接数,再添加一个指向该 inode 的新文件名的目录项即可。

sys_unlinkat 的作用是删除一个硬链接,就是 sys_linkat 的反操作。

还是通过文件名找到对应的 inode,减少其硬链接计数,判断若其硬链接数为 0 后,就可以清空这个 inode 了。框架提供了 clear() 方法来很方便地清空一个 inode 并回收其数据块。

然后删除对应的目录项。不过由于目录项是连续存储的,直接删除会需要进行移动操作,效率很低。我们可以采用将其 name 清空的方法,来让文件系统无法找到这个目录项,从而用很少的空间浪费换取了高效的删除操作。

sys_fstat 的作用提供一个 fd,返回其相关的 inode 信息。不过本实验中,我们只需要关心 inonlink 就好了。mode 因为我们只能打开文件,所以一定是 StatMode::FILE

实现方式也很简单,获取对应的数据返回即可。我采用的方法是在 File trait 里新增了 fstat 方法。这样还需要给 Stdin、Stdout、Stderr 也实现这个方法,由于对这些进行 fstat 是非法操作,我就直接返回了 None

root inode 是文件系统的根,起到了给 os 一个文件系统入口的作用,当 os 想要从文件系统中对文件进行操作的时候,就通过全局的 ROOT_INODE 来获取根目录的 inode,然后再访问其下的目录项来查找文件。

当时用管道符号 | 进行文本提取的时候。例如查看本机 CPU 型号:

1
cat /proc/cpuinfo | grep 'model name' | uniq

上述指令使用 cat 获取 cpu 相关的信息,然后用管道传给 grep 提取出包含有 'model name' 的行,最后传递给 uniq 进行去重,就得到了当前的 cpu 型号。

对于需要在多个进程之间进行相互通信,可以采用共享内存的方式,给所有进程分配一段实际物理块相同的内存空间,再加上读写锁等类似的互斥同步机制,就可以实现了。

  1. 在完成本次实验的过程(含此前学习的过程)中,我曾分别与 以下各位 就(与本次实验相关的)以下方面做过交流,还在代码中对应的位置以注释形式记录了具体的交流对象及内容:

    SaZiKK: 部分理解性的原理

  2. 此外,我也参考了 以下资料 ,还在代码中对应的位置以注释形式记录了具体的参考来源及内容:

  3. 我独立完成了本次实验除以上方面之外的所有工作,包括代码与文档。 我清楚地知道,从以上方面获得的信息在一定程度上降低了实验难度,可能会影响起评分。

  4. 我从未使用过他人的代码,不管是原封不动地复制,还是经过了某些等价转换。 我未曾也不会向他人(含此后各届同学)复制或公开我的实验代码,我有义务妥善保管好它们。 我提交至本实验的评测系统的代码,均无意于破坏或妨碍任何计算机系统的正常运转。 我清楚地知道,以上情况均为本课程纪律所禁止,若违反,对应的实验成绩将按“-100”分计。