思考题
-
如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。请思考:这么做这会引发什么问题?对于不同种类的设备(如我们提到的串口设备和 IDE 磁盘)的操作会有差异吗?可以从缓存的性质和缓存更新的策略来考虑。
在串口设备中,是通过物理内存实时响应的。若在串口设备中使用缓存,则只有在响应缓存页被替换时,物理内存才更新,导致串口设备读取的数据过期。
在 IDE 磁盘中,我认为没有问题。 如果 IDE 磁盘不会在操作系统无介入的情况下自行调整存储状态,静态磁盘应该是可以使用缓存加速读写的。
- 查找代码中的相关定义,试回答
- 一个磁盘块中最多能存储多少个文件控制块?
4KB / 256B = 16 - 一个目录下最多能有多少个文件?
16 * (10 + 4KB / 4B - 10) = 16 K - 我们的文件系统支持的单个文件最大为多大?
4KB / 4B * 4KB = 4MB
- 一个磁盘块中最多能存储多少个文件控制块?
-
请思考,在满足磁盘块缓存的设计的前提下,我们实验使用的内核支持的最大磁盘大小是多少?
DISKMAX * 1B = 1GB
-
在本实验中,fs/serv.h、user/include/fs.h 等文件中出现了许多宏定义,试列举你认为较为重要的宏定义,同时进行解释,并描述其主要应用之处。
#define BY2SECT 512 /* 磁盘区大小 */ #define SECT2BLK (BY2BLK / BY2SECT) /* 磁盘块包含的物理磁盘区数 */ #define DISKMAP 0x10000000 // 磁盘缓存的虚拟地址 #define BY2BLK BY2PG //磁盘块大小=页面大小 #define BY2FILE 256 // 文件控制块大小
-
在 Lab4“系统调用与 fork”的实验中我们实现了极为重要的 fork 函数。那么 fork 前后的父子进程是否会共享文件描述符和定位指针呢?请在完成上述练习的基础上编写一个程序进行验证。
serv.c 中,PTE_LIBRARY 共享了 Fd 所在页面。
1 2 3 4 5
void serve_map(u_int envid, struct Fsreq_map* rq){ ... //PTE_LIBRARY 共享 Fd 所在页面 ipc_send(envid, 0, blk, PTE_D | PTE_LIBRARY); }
-
请解释 File, Fd, Filefd 结构体及其各个域的作用。比如各个结构体会在哪些过程中被使用,是否对应磁盘上的物理实体还是单纯的内存数据等。说明形式自定,要求简洁明了,可大致勾勒出文件系统数据结构与物理实体的对应关系与设计框架。
File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
struct File { //物理实体 char f_name[MAXNAMELEN]; // filename uint32_t f_size; // file size in bytes uint32_t f_type; // file type uint32_t f_direct[NDIRECT]; //直接内容 uint32_t f_indirect; // 间接指针 struct File *f_dir; // 所在目录指针 char f_pad[BY2FILE - MAXNAMELEN - (3 + NDIRECT) * 4 - sizeof(void *)]; } __attribute__((aligned(4), packed)); struct Fd { //内存数据 u_int fd_dev_id; //设备id u_int fd_offset; // 读写的偏移量 u_int fd_omode; //⽂件打开的读写模式 }; struct Filefd { //两者结合 struct Fd f_fd; u_int f_fileid; struct File f_file; };
-
图5.7中有多种不同形式的箭头,请解释这些不同箭头的差别,并思考我们 的操作系统是如何实现对应类型的进程间通信的。
ENV_CREATE(user_env) ENV_CREATE(fs_serv) 在内核态完成,直接创建用户进程。
fs_serv 进程在初始化 fs_init() 后,和其他需要使用文件系统的用户进程使用 ipc_* 通信。
实验难点
本次实验需要理解文件系统结构,用户使用 fd.c 接口,使用文件描述符读写文件,fsipc.c 与文件系统服务进程使用 ipc_* 交互,文件系统服务进程实现磁盘缓存,并使用驱动程序操作磁盘。
实验体会
文件系统较为复杂,我们的 lab 只涉及了其中很小一部分,对于用户进程与服务进程的了解不够透彻。限于实验篇幅,内容十分精简。