22 文件系统
可以永久保存文件
22.1 功能规划
需要考虑的问题:
1 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储
2 文件系统中也要有索引区,用来方便查找一个文件分成的多个块都存放在了什么位置
3 如果文件系统中有的文件是热点文件,近期经常被读取和写入,文件系统应该有缓存层
4 文件应该用文件夹的形式组织起来,方便管理和查询,即分门别类,形成树形结构,也可以减少命名冲突,因为不同节点下的节点文件可以重名
5 Linux内核要在自己的内存里面维护一套数据结构,来保存哪些文件被哪些进程打开和使用
22.2 文件系统相关命令行
fdisk -l:查看格式化和没有格式化的分区
mkfs.ex4 盘:对指定分区盘建立分区,格式化为ext4格式
fdisk 盘:启动一个交互式程序,可以用来格式化为多个分区而不是一个
mount 盘 /根⽬录/⽤⼾A⽬录/⽬录1:格式化后的硬盘,需要挂在到某个目录下面,才能作为普通的文件系统进行访问
umount /根⽬录/⽤⼾A⽬录/⽬录1:卸载
Linux里面一切都是文件,那从哪里看出是什么文件呢?要从ls -l的结果的第一位标识位看出来:
-表示普通文件;
d表示文件夹;
c表示字符设备文件;
b表示块设备文件;
s表示套接字socket文件;
l表示符号链接,也即软链接,就是通过名字指向另外一个文件;
22.3 文件系统相关系统调用
open:打开一个文件。操作系统会创建一些数据结构来表示这个被打开的文件;
为了能够找到这些数据结构,在进程中会为这个打开的文件分配一个文件描述符fd(File Descriptor),用来区分一个进程打开的多个文件。
write:写入数据
lseek:重新定位读写的位置
read:读取数据
close:关闭一个文件
stat、fstat、lstat:返回与打开的文件描述符相关的文件状态信息;
这个信息将会写到类型为struct stat的buf结构中;
函数stat和lstat返回的是通过文件名查到的状态信息:stat没有处理符号链接(软链接)的能力。如果一个文件是符号链接,stat会直接返回它所指向的文件的属性;
而lstat返回的就是这个符号链接的内容;
fstat则是通过文件描述符获取文件对应的属性。
opendir函数:打开一个目录名所对应的DIR目录流。
readdir函数:从DIR目录流中读取一个项目
closedir函数:关闭参数dir所指的目录流
22.4 总结
文件系统的主要功能:
在文件系统上,需要维护文件的严格的格式,要通过mkfs.ext4命令来格式化为严格的格式。
每一个硬盘上保存的文件都要有一个索引,来维护这个文件上的数据块都保存在哪里。
文件通过文件夹组织起来,可以方便用户使用。
为了能够更快读取文件,内存里会分配一块空间作为缓存,让一些数据块放在缓存里面。
在内核中,要有一整套的数据结构来表示打开的文件。
在用户态,每个打开的文件都有一个文件描述符,可以通过各种文件相关的系统调用,操作这个文件描述
符。
23 硬盘文件系统
如图左边是最常见的硬盘,中间是磁盘的盘片,右边是盘片抽象出来的图;
每一层里分多个磁道,每个磁道分多个扇区,每个扇区是512个字节。
文件系统就是安装在这样的硬盘之上。
这一节重点分析目前Linux下最主流的文件系统格式——ext系列的文件系统的格式。
23.1 inode与块的存储
硬盘分成相同大小的单元,称为块(Block);
一块的大小是扇区大小的整数倍,默认是4K(大概8个扇区)。
一大块硬盘被分成了一个个小的块,用来存放文件的数据部分;
这样一来,如果我们存放一个文件,就不用给他分配一块连续的空间了;
我们可以分散成一个个小块进行存放。这样就灵活得多,也比较容易添加、删除和插入数据。
这也带来一个新的问题,那就是文件的数据存放得太散,找起来就比较困难,可以使用一个索引结构来维护“某个文件分成几块、每一块在哪里“等等这些基本信息;
另外,文件还有元数据部分,例如名字、权限等也需要存储;
这就需要一个结构inode(index node)来存放
每个文件都会对应一个inode;
一个文件夹就是一个文件,也对应一个inode。
inode结构的信息:文件的读写权限i_mode,属于哪个用户i_uid,哪个组i_gid,大小是多少i_size_io,占用多少个块i_blocks_io;
i_atim最近一次访问文件的时间,i_ctime最近一次更改inode的时间,i_mtime最近一次更改文件的时间;
i_block保存文件具体分隔成块的块信息,如“某个文件分成几块、每一块在哪里”
ls命令列出来的权限、用户、大小这些信息,就是从文件对应的inode取出来的,这也是其原理
struct ext4_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size_lo; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Inode Change time */
__le32 i_mtime; /* Modification time */
__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
__le32 i_blocks_lo; /* Blocks count */
__le32 i_flags; /* File flags */
....