文件系统
文件系统
文件系统组成
每个文件分配:索引节点inode和目录项dentry,用来记录文件元信息和目录层次结构。
- 索引节点inode:记录文件元信息:inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等。inode是文件唯一标识,存磁盘,所以inode同样占用磁盘空间
- 目录项dentry:记录文件名、inode指针以及与其他目录项的层级关联关系。多个目录项关联就会形成目录结构,与inode不同的是目录项由内核维护,不存磁盘,缓存在内存
文件数据如何存磁盘
磁盘读写最小单位是扇区,扇区大小只有 512B
,如果每次读写都以扇区为单位,那读写效率会非常低。所以文件系统把8个扇区组成一个逻辑块,大小为 4KB
,每次读写最小单位就是逻辑块
磁盘分成三个存储区域:
- 超级块:存储文件系统详细信息,比如块个数、块大小、空闲块等
- inode区:存储inode
- 数据块区:存储文件或目录数据
软链接和硬链接
硬链接:多个目录项中的inode指向一个文件,也就是指向同一个 inode,但是 inode 是不可能跨越文件系统的,每个文件系统都有各自的 inode 数据结构和列表,所以硬链接不可用于跨文件系统。由于多个目录项都是指向一个 inode,那么只有删除文件的所有硬链接以及源文件时,系统才会彻底删除该文件
软链接:相当于重创一个文件,这个文件有独立的 inode,但文件内容是另一个文件的路径,所以访问软链接时,实际上相当于访问了另一个文件,所以软链接是可以跨文件系统的,目标文件被删除了,链接文件还是在的,只不过指向的文件找不到而已
文件IO
I/O分两个过程:
- 数据准备过程
- 数据从内核空间拷贝到用户进程缓冲区的过程
阻塞 I/O会阻塞在1和2,而非阻塞 I/O 和基于非阻塞 I/O 的多路复用只会阻塞在2,所以这三个都可以认为是同步 I/O。异步 I/O 1和2都不会阻塞
调用read后内核会干哪些操作
Linux系统通过int80号中断实现系统调用。调系统调用后,会通过寄存器保存fd参数,触发int80号中断,在内核栈保存用户上文信息,然后在TSS里找到内核栈,由用户态切换到内核态。内核通过int80中断得知这是一个系统调用,然后通过系统调用号去系统调用表中找到对应的系统调用函数sys_read并跳转去执行。
进程PCB中有一个进程描述符表file_table,sys_read先通过参数fd在这个表里找到对应的文件实例file,file中包括很多信息比如文件读写偏移量、文件大小等,通过偏移量和inode中的块描述符表确定要读写文件的位置。
确定位置后,接下来会先去内核page cache页高速缓存中查看要读的页是否有缓存命中,有就直接返回read信息,没有则通知硬件设备DMA和磁盘准备数据,此时该进程会陷入阻塞,当磁盘准备好数据后,DMA会将数据从磁盘缓冲区拷贝到page cache中,然后唤醒进程,随后进程把数据从内核page cache中拷贝到用户态buffer里。
随后进程通过IRET从内核态切换到用户态,然后恢复上下文信息