小林图解系统文件系统和设备管理
文件系统的基本组成:
文件系统是操作系统中负责管理持久数据的子系统,即将负责用户的文件存到磁盘硬件中,这样断电也不会丢失数据,所以可以持久化保存文件。
文件系统会给每个文件分配两个数据结构,索引节点和目录项,主要用来记录文件的元信息和目录层次结构。
- 索引节点,也就是 inode,用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、 数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间。
- 目录项,也就是 dentry,用来记录文件的名字、 索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是, 目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。
目录项和索引节点之间的关系是多对一,也就是一个文件可以有多个别字。比如,硬链接的实现就是多个目录项中的索引节点指向同一个文件。
目录和目录项不一样,目录是个文件,持久化存储在硬盘;目录项是内核的数据结构,缓存在内存;
- 超级块:存储文件系统的详细信息,比如块大小、空闲块等,文件系统挂载时进入内存。
- 索引节点区,用来存储索引节点,文件被访问时进入内存。
- 数据块区,用来存储文件或目录结构。
根据存储位置的不同,可以把文件系统分成三类:
- 磁盘的文件系统,它是直接把数据存储在磁盘中,比如 Ext 2/3/4、 XFS 等都是这类文件系统。
- 内存的文件系统,这类文件系统的数据不是存储在硬盘的,而是占用内存空间,我们经常用到的 /proc 和 /sys 文件系统都属于这⼀类,读写这类文件,实际上是读写内核中相关的数据。
- 网络的文件系统,用来访问其他计算机主机数据的文件系统,比如 NFS、 SMB 等等。
文件的存储
- 连续空间存放方式:链表方式和索引方式,读写效率高,但是有磁盘空间碎片和文件长度不易扩展的缺点。
- 非连续空间存放方式:可以消除磁盘碎片,提高磁盘利用率,文件大小可扩展;缺点是不能直接访问数据块,只能通过指针顺序访问文件。
空闲空间管理
- 空闲表:用一个表专门记录第一个空闲块号和空闲块个数
- 空闲链表:将所有的空闲块以链表的形式串联起来
- 位图法:用0,1表示盘块是否空闲,(Linux采用)
软链接和硬链接
- 硬链接:多个目录项中的索引节点指向同一个文件,也就是指向同一个inode,不可跨文件系统】
- 软链接:相当于重新创建一个文件,这个文件有独立的inode,但是这个文件的内容是另外一个文件的路径,可以跨文件系统,即使目标文件被删除了,链接文件还存在,只是找不到指向的文件了。
文件I/O
- 缓存I/O:利用标准库的缓存实现文件的加速访问,标准库再通过系统调用访问文件,减小了上下文切换
- 非缓存I/O:直接通过系统调用访问文件,不经过标准库缓存
- 直接I/O:没有内核缓存和用户之间数据复制,直接经过文件系统访问磁盘
- 非直接I/O:读操作时,数据从内核拷贝给用户程序,写操作时,先写到内核,内核决定什么时候写入数据到磁盘
- 阻塞I/O:read时阻塞,等待内核数据准备好并把数据从内核缓冲区拷贝到应用程序的缓冲区中
- 非阻塞I/O:数据在为准备好时立即返回,继续向下执行,此时应用不断的轮询内核,直到数据准备好可读
- 同步I/O:阻塞I/O和非阻塞I/O都是同步I/O,内核将数据从内核空间拷贝到应用程序空间是需要等待的。
- 异步I/O:数据准备的过程和数据从内核拷贝到用户空间时都不会阻塞,如果数据准备好,就直接拷贝,没准备好,就立即返回;注意这个拷贝的过程用户也是不需要等待的;
设备管理
电脑可以接入多种输入输出设备,每个设备都有一个设备控制器组件。CPU通过设备控制器和具体的设备打交道
控制器主要包括三类寄存器:状态寄存器,命令寄存器和数据寄存器
- 数据寄存器, CPU 向 I/O 设备写入需要传输的数据,比如要打印的内容是「Hello」,CPU 就要先发送⼀个 H 字符给到对应的 I/O 设备。
- 命令寄存器, CPU 发送⼀个命令,告诉 I/O 设备,要进行输入/输出操作,于是就会交给I/O 设备去工作,任务完成后,会把状态寄存器里面的状态标记为完成。
- 状态寄存器,目的是告诉 CPU ,现在已经在工作或工作已经完成,如果已经在工作状态, CPU 再发送数据或者命令过来,都是没有用的,直到前面的工作已经完成,状态寄存标记成已完成, CPU 才能发送下⼀个字符和命令。
设备控制器读取外数据通知CPU的方式:
- CPU轮询等待,查看寄存器的状态,直到状态标记为完成,但是效率太低
- 中断,软中断通过INT指令触发,硬中断通过硬件实现,但是CPU容易被经常打断。一种解决方式就是DMA(即CPU不参与的情况下,自行完成把设备I/O数据放入到内存,CPU只需要告诉DMA想读多少数据,当读完后触发中断通知CPU)
- 输入a之后,首先控制器,把扫描到的a放入到了控制器的寄存器中。
- 触发硬中断通知cpu—> 中断IO控制方式,由硬件触发的。键盘读入中断
- cpu触发软中断,保存中断进程的CPU上下文,调用键盘驱动程序,将a读入到读队列中。
- 之后,显示设备的驱动程序会定时从读缓冲区队列放到写缓冲区队列中。
- 把写缓冲区队列的数据一个个写入到显示设备控制器的寄存器里。
- 显示出结果后,恢复被中断进程的上下文。