系统分区完成后,将要将分区格式化文件系统(文件系统是个管理软件,存到磁盘分区的某个位置,文件系统不是整个分区)可是文件系统上的数据是在这个分区上的,因此说文件系统是一个管理软件。node
文件系统把磁盘分为两片:元数据存储区**(metadata)**(inode位图、块位图、inode条目等等)、数据存储区(数据存储区又分为多个逻辑存储单元叫作磁盘块(是逻辑概念))linux
任何文件系统中的数据分为数据和元数据(metadata)。数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限、文件拥有者以及文件数据块的分布信息(inode...)等等。可是元数据中★不包含文件名★文件名存放在磁盘块上的。git
由上而下主要分为用户层、VFS层、文件系统层、缓存层、块设备层、磁盘驱动层、磁盘物理层github
用户层:最上面用户层就是咱们平常使用的各类程序,须要的接口主要是文件的建立、删除、打开、关闭、写、读等。算法
VFS层:咱们知道Linux分为用户态和内核态,用户态请求硬件资源须要调用System Call经过内核态去实现。用户的这些文件相关操做都有对应的System Call函数接口,接口调用 VFS对应的函数。windows
文件系统层:不一样的文件系统实现了VFS的这些函数,经过指针注册到VFS里面。因此,用户的操做经过VFS转到各类文件系统。文件系统把文件读写命令转化为对磁盘LBA的操做,起了一个翻译和磁盘管理的做用。缓存
缓存层:文件系统底下有缓存,Page Cache,加速性能。对磁盘LBA的读写数据缓存到这里。函数
块设备层:块设备接口Block Device是用来访问磁盘LBA的层级,读写命令组合以后插入到命令队列,磁盘的驱动从队列读命令执行。Linux设计了电梯算法等对不少LBA的读写进行优化排序,尽可能把连续地址放在一块儿。性能
磁盘驱动层:磁盘的驱动程序把对LBA的读写命令转化为各自的协议,好比变成ATA命令,SCSI命令,或者是本身硬件能够识别的自定义命令,发送给磁盘控制器。Host Based SSD甚至在块设备层和磁盘驱动层实现了FTL,变成对Flash芯片的操做。优化
磁盘物理层:读写物理数据到磁盘介质。
咱们都知道,windows文件系统主要有fat、ntfs等,而linux文件系统则种类多的很,主要有VFS作了一个软件抽象层,
向上提供文件操做接口,向下提供标准接口供不一样文件系统对接,下面主要就以EXT4文件系统为例,讲解下文件系统结构与工做原理:
上面两个图大致呈现了ext4文件系统的结构,从中也相信可以初步的领悟到文件系统读写的逻辑过程。下面对上图里边的构成元素作个简单的讲解:
引导块:为磁盘分区的第一个块,记录文件系统分区的一些信息,,引导加载当前分区的程序和数据被保存在这个块中。通常占用2kB,
1)超级块:
超级块用于存储文件系统全局的配置参数(譬如:块大小,总的块数和inode数)和动态信息(譬如:当前空闲块数和inode数),其处于文件系统开始位置的1k处,所占大小为1k。为了系统的健壮性,最初每一个块组都有超级块和组描述符表(如下将用GDT)的一个拷贝,可是当文件系统很大时,这样浪费了不少块(尤为是GDT占用的块多),后来采用了一种稀疏的方式来存储这些拷贝,只有块组号是3, 5 ,7的幂的块组(譬如说1,3,5,7,9,25,49…)才备份这个拷贝。一般状况下,只有主拷贝(第0块块组)的超级块信息被文件系统使用,其它拷贝只有在主拷贝被破坏的状况下才使用。
2)块组描述符:
GDT用于存储块组描述符,其占用一个或者多个数据块,具体取决于文件系统的大小。它主要包含块位图,inode位图和inode表位置,当前空闲块数,inode数以及使用的目录数(用于平衡各个块组目录数),具体定义能够参见ext3_fs.h文件中struct ext3_group_desc。每一个块组都对应这样一个描述符,目前该结构占用32个字节,所以对于块大小为4k的文件系统来讲,每一个块能够存储128个块组描述符。因为GDT对于定位文件系统的元数据很是重要,所以和超级块同样,也对其进行了备份。GDT在每一个块组(若是有备份)中内容都是同样的,其所占块数也是相同的。从上面的介绍能够看出块组中的元数据譬如块位图,inode位图,inode表其位置不是固定的,固然默认状况下,文件系统在建立时其位置在每一个块组中都是同样的,如图2所示(假设按照稀疏方式存储,且n不是3,5,7的幂)
3)块组:
每一个块组包含一个块位图块,一个 inode 位图块,一个或多个块用于描述 inode 表和用于存储文件数据的数据块,除此以外,还有可能包含超级块和全部块组描述符表(取决于块组号和文件系统建立时使用的参数)。下面将对这些元数据做一些简要介绍。
4)块位图:
块位图用于描述该块组所管理的块的分配状态。若是某个块对应的位未置位,那么表明该块未分配,能够用于存储数据;不然,表明该块已经用于存储数据或者该块不可以使用(譬如该块物理上不存在)。因为块位图仅占一个块,所以这也就决定了块组的大小。
5)Inode位图:
Inode位图用于描述该块组所管理的inode的分配状态。咱们知道inode是用于描述文件的元数据,每一个inode对应文件系统中惟一的一个号,若是inode位图中相应位置位,那么表明该inode已经分配出去;不然可使用。因为其仅占用一个块,所以这也限制了一个块组中所可以使用的最大inode数量。
6)Inode表:
Inode表用于存储inode信息。它占用一个或多个块(为了有效的利用空间,多个inode存储在一个块中),其大小取决于文件系统建立时的参数,因为inode位图的限制,决定了其最大所占用的空间。
以上这几个构成元素所处的磁盘块成为文件系统的元数据块,剩余的部分则用来存储真正的文件内容,称为数据块,而数据块其实也包含数据和目录。
了解了文件系统的结构后,接下来咱们来看看操做系统是如何读取一个文件的:
大致过程以下:
1)根据文件所在目录的inode信息,找到目录文件对应数据块
2)根据文件名从数据块中找到对应的inode节点信息
3)从文件inode节点信息中找到文件内容所在数据块块号
4)读取数据块内容
到这里,相信不少人会有一个疑问,咱们知道一个文件只有一个Inode节点来存放它的属性信息,那么你可能会想若是一个大文件,那它的block必定是多个的,且可能不连续的,那么inode怎么来表示呢,下面的图告诉你答案:
也就是说,若是文件内容太大,对应数据块数量过多,inode节点自己提供的存储空间不够,会使用其余的间接数据块来存储数据块位置信息,最多能够有三级寻址结构。
到这里,应该都已经很是清楚文件读取的过程了,那么下面再抛出两个疑问:
1)文件的拷贝、剪切的底层过程是怎样的?
2)软链接和硬链接分别是如何实现的?
下面来结合stat命令动手操做一下,便知真相:
1)拷贝文件:建立一个新的inode节点,而且拷贝数据块内容
2)剪切文件:同个分区里边mv,inode节点不变,只是更新目录文件对应数据块里边的文件名和inode对应关系;跨分区mv,则跟拷贝一个道理,须要建立新的inode,由于inode节点不一样分区是不能共享的。
3)软链接:建立软链接会建立一个新的inode节点,其对应数据块内容存储所连接的文件名信息,这样原文件即使删除了,从新创建一个同名的文件,软链接依然可以生效。
4)硬连接:建立硬连接,并不会新建inode节点,只是links加1,还有再目录文件对应数据块上增长一条文件名和inode对应关系记录;只有将硬连接和原文件都删除以后,文件才会真正删除,即links为0才真正删除。
一、什么是文件系统
二、文件系统结构与工做原理