OS-Lab5
一、思考题
Thinking 5.1

- 由于外部设备会更改自己对应地址空间的数据,CPU写入外设的数据存入Cache中,若在此时访问Cache,由于缓存内容只有在被新数据换出时才会被写入内存,因此会导致缓存内容覆盖了之前的操作,这相当于只进行最后一次操作,即操作覆盖。
- 串口访问频繁,而IDE磁盘访问频率较小,因此串口出错概率更高。
Thinking 5.2

- 由File文件控制块定义可知,文件控制块被f_pad限制对齐为256B,而一个磁盘块大小为4KB,因此一个磁盘块最多存储16个文件控制块。
- 目录文件最多用1024个磁盘块存储数据,因此最多有1024 * 16 = 16384个文件。
- 一个文件最多用1024个磁盘块存储数据,因此单个文件最大为1024 * 4KB = 4MB。
Thinking 5.3

内核支持最大磁盘大小为DISKMAX
即0x40000000B = 1GB。
Thinking 5.4

fs/serv.h
:
1 |
|
这些宏标记了扇区大小以及diskmap的地址范围。
user/include/fs.h
:
1 | // Bytes per file system block - same as page size |
这些宏定义了各种关于文件结构体的信息,比如文件直接指针数以及文件类型。
Thinking 5.5

由于文件描述符以及定位指针都存在于用户空间内,因此fork前后的父子进程会共享文件描述符和定位指针。
程序代码如下:
1 |
|
Thinking 5.6

File
:
1 | struct File { |
File
结构体在描述以及管理文件时使用,主要作用是获得文件的各种属性以及文件内容在磁盘上的位置,File
结构体是物理实体。
Fd
:
1 | struct Fd { |
Fd
结构体记录已打开文件的状态,便于用户直接使用其对文件进行操作。该结构体是内存数据。
Filefd
:
1 | struct Filefd { |
Filefd
结构体是对文件描述符的扩展,便于获得更多文件描述信息。该结构体是内存数据。
Thinking 5.7


ENV_CREATE(user_env)
与ENV_CREATE(fs_env)
是同步消息,表示两种进程的创建,在结束创建过程后init才会向下执行。- fs进程在执行完初始化后,就进入serv()函数,调用
ipc_receive()
函数将自身阻塞,等待用户进程发送请求,直到收到用户进程的ipc_send
同步信息被唤醒。 - fs进程服务结束,通过
ipc_send
发送一个同步的返回信息,唤醒用户进程继续执行,而自身继续阻塞等待下次请求服务。
二、实验难点
1.文件数据块定位

文件的数据离散地存放在不同的磁盘块中,而在文件控制块内,存在指针指向这些存放数据的磁盘块。在f_direct
数组中存在十个直接指针,这些指针直接指向磁盘块,还有存在于f_indirect
指针指向的磁盘块中的1024个指针,由于前十个指针不使用,因此存在1014个间接指针,因此一个文件最大可以有1024个磁盘块保存数据,一个目录也可以最多有1024个磁盘块保存子文件或子目录。
2.用户进程与文件系统服务进程交互流程


用户进程通过用户接口申请文件服务,这些服务都定义在file.c中,之后请求会通过fsipc.c中的函数利用IPC机制将请求发送至文件系统服务进程。文件系统服务进程接收到请求后摆脱阻塞态,使用serv.c中的函数调用fs.c中的服务函数解决请求,之后通过serv.c中的函数向用户进程发出返回信息,交互结束。
三、心得体会
本次实验逻辑比较清晰,因为有请求服务->发出信号->服务进程处理->返回信号这一过程,因此代码实现目的性强。但本次实验代码量很大,需要一定时间阅读理解。总体而言加深了我对外设以及文件系统管理与服务的理解,收获很多。