chapter6练习

  • 本节难度: 理解文件系统比较费事,编程难度适中

本章任务

  • ch6b_usertest

  • merge ch6 的改动,然后再次测试 ch6_usertest。

  • 完成本章问答作业。

  • 完成本章编程作业。

  • 最终,完成实验报告并 push 你的 ch6 分支到远程仓库。

编程作业

硬链接

你的电脑桌面是什么样的?放满了图标吗?反正我的 windows 是这样的。显然很少人会真的把可执行文件放到桌面上,桌面图标其实都是一些快捷方式。或者用 unix 的术语来说:软链接。为了减少工作量,我们今天来实现软链接的兄弟: 硬链接

硬链接要求两个不同的目录项指向同一个文件,在我们的文件系统中也就是两个不同名称目录项指向同一个磁盘块。本节要求实现三个系统调用 sys_linkat、sys_unlinkat、sys_stat

linkat

  • syscall ID: 37

  • 功能:创建一个文件的一个硬链接, linkat标准接口

  • 接口: int linkat(int olddirfd, char* oldpath, int newdirfd, char* newpath, unsigned int flags)

  • 参数:
    • olddirfd,newdirfd: 仅为了兼容性考虑,本次实验中始终为 AT_FDCWD (-100),可以忽略。

    • flags: 仅为了兼容性考虑,本次实验中始终为 0,可以忽略。

    • oldpath:原有文件路径

    • newpath: 新的链接文件路径。

  • 说明:
    • 为了方便,不考虑新文件路径已经存在的情况(属于未定义行为),除非链接同名文件。

    • 返回值:如果出现了错误则返回 -1,否则返回 0。

  • 可能的错误
    • 链接同名文件。

unlinkat:

  • syscall ID: 35

  • 功能:取消一个文件路径到文件的链接, unlinkat标准接口

  • 接口: int unlinkat(int dirfd, char* path, unsigned int flags)

  • 参数:
    • dirfd: 仅为了兼容性考虑,本次实验中始终为 AT_FDCWD (-100),可以忽略。

    • flags: 仅为了兼容性考虑,本次实验中始终为 0,可以忽略。

    • path:文件路径。

  • 说明:
    • 需要注意 unlink 掉所有硬链接后彻底删除文件的情况。

  • 返回值:如果出现了错误则返回 -1,否则返回 0。

  • 可能的错误
    • 文件不存在。

fstat:

  • syscall ID: 80

  • 功能:获取文件状态。

  • 接口: int fstat(int fd, struct Stat* st)

  • 参数:
    • fd: 文件描述符

    • st: 文件状态结构体

    struct Stat {
       uint64 dev,     // 文件所在磁盘驱动号,该实现写死为 0 即可。
       uint64 ino,     // inode 文件所在 inode 编号
       uint32 mode,    // 文件类型
       uint32 nlink,   // 硬链接数量,初始为1
       uint64 pad[7],  // 无需考虑,为了兼容性设计
    }
    
    // 文件类型只需要考虑:
    #define DIR 0x040000              // directory
    #define FILE 0x100000             // ordinary regular file
    
  • 返回值:如果出现了错误则返回 -1,否则返回 0。

  • 可能的错误
    • fd 无效。

    • st 地址非法。

实验要求

  • 实现分支:ch6。

  • 实验目录要求不变。

  • 通过所有测例。

在 os 目录下 make run BASE=2 加载所有测例, 正确实现后,你的 os 应该能够正确运行 ch6_file* 对应的测试用例,在 shell 中执行 ch6_usertest 来执行测试。 ch6_usertest 打包了所有你需要通过的测例,你也可以通过修改这个文件调整本地测试的内容。

你的内核必须前向兼容,能通过前一章的所有测例。

Tips

  • 需要给 inode 和 dinode 都增加 link 的计数,但强烈建议不要改变整个数据结构的大小,事实上,推荐你修改一个 pad。

  • os 和 nfs 的修改需要同步,只不过 nfs 比较简单,只需要初始化 link 计数为 1 就行(可以通过修改 ialloc 来实现)。

  • unlink 有删除文件的语义,如果 link 计数为 0,需要删除 inode 和对应的数据块,为此你需要正确调用 ivalidiupdateiput (如果测试遇到bug了不妨再看看这句话),并取消 iput 中判断条件的注释。你可能需要修改 iput 注释中的变量名(如果你的计数变量不叫 nlink)。

问答作业

  1. 在我们的文件系统中,root inode起着什么作用?如果root inode中的内容损坏了,会发生什么?

报告要求

注意目录要求,报告命名 lab4.mdlab4.pdf,位于 reports 目录下。

特别的,ch7 的问答问题要一并写入本分支的报告。

报告内容:

  • 简单总结你实现的功能(200字以内,不要贴代码)。

  • 完成问答题。

  • 加入 荣誉准则 的内容。否则,你的提交将视作无效,本次实验的成绩将按“0”分计。

  • 推荐markdown文档格式。

  • (optional) 你对本次实验设计及难度/工作量的看法,以及有哪些需要改进的地方,欢迎畅所欲言。

选做题目

选作题目列表

  • (6分)按需加载执行文件(Demanding Paging)

  • (7分)log-easyfs:实现基于日志的可靠文件系统(可参考xv6-fs)

提交要求

  • (占分比:40%)实现代码(包括基本的注释)

  • (占分比:50%)设计与功能/性能测试分析文档,测试用例。

  • (占分比:10%)鼓励形成可脱离OS独立存在的库,可以裸机测试或在用户态测试(比如easyfs那样)