OS lab5 思考题

OS lab5 思考题

rainbowYao Lv3

Thinking 5.1

如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。

请思考:这么做这会引发什么问题?对于不同种类的设备(如我们提到的串口设备和 IDE 磁盘)的操作会有差异吗?可以从缓存的性质和缓存更新的策略来考虑。

  • 这么做是一个很危险的行为,最主要的是数据一致性问题。缓存是为了提高效率而设计的,体现为数据发生改变时并不立即写入内存,而是在cache发生替换时才写入。若系统崩溃或者意外断电,缓存中的数据可能会丢失,而设备上的数据却没有被更新,导致数据不一致。
  • 从更新策略的角度来说
    • 若是写透策略(Write-through):每次对缓存的写操作都会同时更新主存(或者设备)。这确保了主存和缓存中的数据是一致的,是安全的,但是会增加写操作的延迟
    • 若是写回策略(Write-back):只有在缓存中的数据被替换时才将其写回主存(或者设备)。这样做虽然可以减少写操作引起的主存访问,提高性能,但会导致缓存中的数据和主存中的数据不一致一段时间,若这段时间发生系统崩溃或者意外断电,会引发很严重的问题。
  • 对于不同种类的设备的操作是有差异的
    • 串口设备:串口设备通常是实时的,数据需要立即发送到设备上,将其写入缓存而不刷新到设备可能会导致数据发送延迟或者丢失,故更倾向于直接将数据写入设备而不使用缓存。
    • IDE磁盘设备:通常会使用缓存来提高性能,因为磁盘操作通常是比较慢的。但是,对于关键性的数据,如文件系统的元数据或者数据库的事务日志,可能需要采取一些策略来确保数据的可靠性。

Thinking 5.2

查找代码中的相关定义,试回答一个磁盘块中最多能存储多少个文件控制块?一个目录下最多能有多少个文件?我们的文件系统支持的单个文件最大为多大?

  • 一个文件控制块的大小FILE_STRUCT_SIZE是256B,而一个磁盘块的大小BLOCK_SIZE是4KB,故最多有16个文件控制块
  • 一个文件控制块中能存下的指针个数为1K(Note中说只使用一级间接指针域),则一个目录最多有16K个文件
  • user/include/fs.h中有宏定义:#define MAXFILESIZE (NINDIRECT * BLOCK_SIZE),即单个文件最大为:1K*4KB = 4MB

Thinking 5.3

请思考,在满足磁盘块缓存的设计的前提下,我们实验使用的内核支持的最大磁盘大小是多少?

快缓存的大小DISKMAX为0x40000000,即1GB,故内核支持的最大磁盘大小也是1GB

Thinking 5.4

在本实验中,fs/serv.h、user/include/fs.h 等文件中出现了许多宏定义,试列举你认为较为重要的宏定义,同时进行解释,并描述其主要应用之处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//serv.h
#define SECT_SIZE 512 //一个扇区的大小,即512B,在ide_write和ide_read中使用
#define SECT2BLK (BLOCK_SIZE / SECT_SIZE) //一个磁盘块拥有的扇区数,在write_block中调用ide_write时使用,是逻辑与物理的转化

#define DISKMAP 0x10000000 //块缓存的起始地址,disk_addr中用到
#define DISKMAX 0x40000000 //块缓存的最大范围

//fs.h
#define BLOCK_SIZE PAGE_SIZE //磁盘块大小,等于一页的大小(4KB),经常在计算一个文件的nblock时使用,同时disk_addr用到了他

#define FILE_STRUCT_SIZE 256 //File这个结构体的大小,即256B,定义File时用到

#define NDIRECT 10 //f_direct的最大数量,即直接指针的最大数量,定义File时和需要遍历nblock时用到
#define NINDIRECT (BLOCK_SIZE / 4) //同理,间接指针域的最大数量,即1K

#define FILE2BLK (BLOCK_SIZE / sizeof(struct File)) //一个磁盘块拥有的文件数,一般在遍历一个磁盘块中的文件的时使用

Thinking 5.5

在 Lab4“系统调用与 fork”的实验中我们实现了极为重要的 fork 函数。那么 fork 前后的父子进程是否会共享文件描述符和定位指针呢?请在完成上述练习的基础上编写一个程序进行验证。

  • 文件描述符与定位指针在[FDTABLE, FILEBASE)中,在fork执行时,这一部分会被复制到子进程的页表中,所以他们会共享。

Thinking 5.6

请解释 File, Fd, Filefd 结构体及其各个域的作用。比如各个结构体会在哪些过程中被使用,是否对应磁盘上的物理实体还是单纯的内存数据等。说明形式自定,要求简洁明了,可大致勾勒出文件系统数据结构与物理实体的对应关系与设计框架。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct File {                   
char f_name[MAXNAMELEN]; // 文件名
uint32_t f_size; // 文件大小
uint32_t f_type; // 文件的类型
uint32_t f_direct[NDIRECT]; // 文件的直接指针
uint32_t f_indirect; // 文件的间接指针

struct File *f_dir; // 文件的目录
char f_pad[FILE_STRUCT_SIZE - MAXNAMELEN - (3 + NDIRECT) * 4 - sizeof(void *)]; // 文件补齐256B
};

struct Fd {
u_int fd_dev_id; // 文件描述符的设备id,用于确定该文件属于的设备
u_int fd_offset; // 文件描述符的使用偏移,用于read,write,seek等操作的定位
u_int fd_omode; // 用于确定打开方式
};

struct Filefd {
struct Fd f_fd; // 利于强制类型转换涵盖Fd
u_int f_fileid; // 文件服务系统中标识文件的fileid
struct File f_file; // fileid对应的文件的具体内容
};
  • File是对应了物理实体中恰恰好好的256B,在磁盘块中,File是文件服务系统操作文件的基本单位,可以通过File来遍历他的所有指针指向的内容,可以遍历目录中的文件或者文件存储的内容
  • Fd是文件标识符,它的作用是方便用户态来使用操作文件,所以他是内存数据,Fd也用在Fsipc时作为信息传递的载体
  • Filefd是Fd的拓展,是构建起Fsipc的桥梁,在文件服务系统进程中将File打包成Filefd返回给用户进程,用户进程可以选择拓展Fd为Filefd来获取f_fileid或者f_file,也可以只操作f_fd,在我看来它既包括物理实体又包括内存数据
  • 标题: OS lab5 思考题
  • 作者: rainbowYao
  • 创建于 : 2024-07-02 21:25:27
  • 更新于 : 2024-09-18 09:28:39
  • 链接: https://redefine.ohevan.com/2024/07/02/OS-lab5-思考题/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
此页目录
OS lab5 思考题