Notes: Disk Abstraction -- File System(操作系统的文件系统)

来源:互联网 发布:js实现数组排序 编辑:程序博客网 时间:2024/05/05 22:18

注:以下图片来自《鸟哥的Linux私房菜》


操作系统的三大重要抽象:对程序的抽象 —— 进程、线程; 对内存的抽象 —— 地址空间;对磁盘的抽象 —— 文件系统。正是文件系统的抽象,使用户只需要关注文件的组织形式和metadata(权限、属性)便可以管理文件了。


磁盘的物理组成:


但在正式将文件系统前,还是很有必要先说说磁盘的物理实现的。一个典型的磁盘由很多个磁头和盘片组成,如下图所示【1】:




每个磁头通过移动,能读取其中一条磁轨的内容。这条磁轨成为track。每条磁轨都能分为若干个sector,就是扇区。扇区是被规定了大小使512Bytes。然后,移动到同一个半径的所有磁头下的所有磁轨可以组成一个Cylinder,也就是柱面。


分区的实质便是把一定的半径范围 (实质是柱面m到柱面n) 的柱面分成一个区,分区的意义有两点:1)方便磁头寻轨的性能,一旦知道想访问的数据在哪个分区后,便能寻轨范围;2)增强了数据安全,分区与分区间的数据有一定的独立性,可以在格式化某个分区时,把该分区的内容暂时备份到另一个分区。分区的信息都记录在一个叫做分区表的区域,分区表的大小是64Bytes,位于每个磁盘的第一个sector(扇区)中。磁盘默认的分区表只能分成4个分区。这4个能在分区表中分的分区称为主分区 (Primary Partition)。但Linux系统给予我们能在四个分区中,选择其中一个作为拓展分区的功能(注意,系统限制只有一个),在拓展分区(extened partition)中可以分很多个逻辑分区(Logic Partition)。逻辑分区数量的限制是:IDE硬盘最多有59个逻辑分区(hdx5到hdx63),SATA硬盘最多有11个逻辑分区(sdx5到sdx15)。


主分区、拓展分区和逻辑分区之间的联系图:


1)全是主分区无拓展分区的分区示意:




上述示意图假设磁盘只有400个柱面,然后利用4个主分区等分了400个柱面。然而,柱面不是必须要等分的,而且也可以选择只分1、2、3个主分区,同时还可以在其中一个主分作为拓展分区在里面再分逻辑分区。


2)例如,只分了两个主分区,再选择其中一个作为拓展分区,里面再分逻辑分区:




注意,逻辑分区不一定需要分满了拓展分区,可以在拓展分区中留一部分空间备用。


关于拓展分区的特别性,需要说明一下的有以下两点:1、拓展分区本身不能用来格式化,其作用只是利用额外的扇区来作为分区表的补充以记录更多的分区信息;2)如果破坏了拓展分区,所有的逻辑分区都会被删除。


上面提到了IDE磁盘和SATA磁盘,两者的区别在于:




IDE的传输速度可达133MB/s。IDE的接口比较宽。SATA的接口比较窄。SATA1的速率是150MB/s,而SATA2速率是300MB/s。在Linux系统当中,IDE硬盘的文件是以hd开头,而SATA硬盘以sd开头。之后跟着字母,字母的顺序在IDE中根据Primary和Secondary以及Master和Slave区分,而在SATA当中根据Linux内核识别到的顺序决定。例子如下:






在hdx或者sdx之后,跟着的是数字。数字是根据分区来决定的。其中1-4是专门为了Primary Partition而设的。5-15或者5-63是为了逻辑分区而设的。所以,上面的第二种分区情况如果是SATA硬盘得到的dev文件是:sda1、sda2和sda5/6/7/8/9。但是,需要注意的是sda2只是一个拓展分区,不能删除。否则,所有逻辑分区都不能用。


分析磁盘的延时需要用的数据:


磁盘转速:5400rpm、7200rpm或者10800rpm。桌面电脑是7200,笔记本则通常为5400转。


磁头随机移动一个柱面的时间是5ms - 10ms。移动到相邻的柱面是1ms。


传输速率,IDE是133MB/s。而SATA则为150或者300MB/s。


Linux的文件系统实现


磁盘分区后,必须格式化后才能被用户使用。格式化是针对不同的文件系统格式而将磁盘的数据以不同的属性特点描述和组织形式来组织数据。像Windows98之后的FAT-16和FAT-32就是经典的文件系统格式。而WIndows NT之后出现了NTFS,目前仍是Windows 10的主流文件系统格式。而Linux的文件主流格式Ex-2,但目前主流已切换到Ex-3,它是向后兼容Ex-2的所有特点,并且提供了日志记录服务的文件系统。


日志文件系统是确保文件系统一致性的举措。以克服在修改数据的过程中,发生严重错误(如突然断电)后,文件系统的数据不一致(譬如只向data block更新了内容,却没来得及更新iNode bitmap和 block bitmap)。通过设置以下三个记录点来确保数据的一致性:

1)预备记录点:当系统准备写入一个文件时,先在日志记录块中记录要写的内容;

2)写入data block 和 inode的metadata 记录点:当系统完成了对data block/ inode 的内容写入后,完成这一点;但这一步还没有开始对inode bitmap和 block bitmap的更新。

3)完成所有写入操作的记录点:完成了两个bitmap的更新。


由于历史原因,过去人们常常把一个分区格式化成一个格式的文件系统。所以,往往当我们说到一个文件系统的时候,往往指的是一个分区。


每个分区都有自己的第一个sector都是该分区的boot sector,里面可以安装引导加载程序(boot loader)。引导加载程序的作用是加载该分区(如果有安装操作系统在该分区)的操作系统的内核文件。然后内核文件会开始加载操作系统的功能。


然后,Linux将剩余的分区空间分为多个Block Group,每一个Block Group有自己的inodes和data blocks。这么分组的目的是为了将大容量的磁盘分成小块进行管理,更有效率。


这也是由Linux的文件系统对数据的组织形式决定的,相对于Windows的FAT-16或者FAT-32,Linux的文件系统是索引式文件系统(indexed allocation)。因为Linux存储文件的机制是将文件的实质内容存放在data block当中,而每个文件都占用一个inode来存储它的metadata和存储它是在内容的data block的索引。这些metadata包括:这个文件的所有者是谁、是属于哪个用户组、三个时间(aTime 文件内容被取用,更新这个读取时间 ; mTime 内容被修改的时间; cTime 权限和属性被更改的时间),默认情况下,ls显示出来的是mTime;权限(所有者、所在用户组、其它用户)、文件大小等。具体流程如下:




而Windows的FAT-16或者FAT-32文件系统则是把后一个的data block的地址存放在前一个data block上,类似链表那样的寻址方式。




在文件系统(分区)被格式化之后,所有的inode和block都规划好了,除非重新格式化,否则都固定不再改变了。所以,根据目前的磁盘大都是上百GB的内存,如果一下子把所有的inode和block放在一起,会导致数量过大,不容易管理。所以,才像我上面所说,使用block group的方式管理。于是,每个文件系统就变成下图所述:




一般而言,每个文件系统都会只有一个super block,有些时候,会还有其它的block group含有superblock以作为备份。super block是一个大小为1KB的Block。记录着整个文件文件系统的信息。包括:inode和block的总量,未使用和已使用的inode 和 block的数量。block的单位大小(1KB/ 2KB/ 4KB)和 inode的单位大小(128 bytes)。该文件系统是否已被挂载(valid bit = 0,则未被挂载;valid bit = 1,则已被挂载)。关于superblock所记录的信息可以用dumpe2fs调出来。


文件系统描述:描述每个block的开始和结束的block号码,以及每个group的bitmap,inode, data block是哪些编号的block号码。


block/ inode bitmap:记录空闲的block/ inode的位图。


Inode:Inode的大小固定是128Bytes,每一个文件(无论是文件或者是目录文件等)仅且必须占用一个inode。因为创建文件的数量的主要限制是Inode的数量。inode记录的信息是这个文件的所有者是谁、是属于哪个用户组、三个时间(aTime 文件内容被取用,更新这个读取时间 ; mTime 内容被修改的时间; cTime 权限和属性被更改的时间),默认情况下,ls显示出来的是mTime;权限(所有者、所在用户组、其它用户)、文件大小等,以及最重要的文件内容实质存在哪些号码的data block中。


Data Block:data block的大小可以是1KB/ 2KB/ 4KB。在格式化时固定后不能改变。Data Block以编号作为索引,方便inode记录。在考虑data block的大小时,需要考虑到每一个data block都只能存储一个文件的内容,如果这个文件的内容不够data block的大写,则剩下的空间就会被浪费了。但是如果设置block size很小,又会需要增加inode记录的开销。所以,如何选择inode的size是根据该计算机日常的应用决定。


Linux的文件类型和文件读取过程


Linux的文件类型有:[d] 文件目录;[l]链接文件; [b]设备文件的可供存储的设备;[c]设备文件的串行端口设备,如键盘、鼠标;以及最常见的[-]就是普通文件了。


文件系统以目录树的形式组织文件,所以就有了特殊的文件类型:目录。


Ex-2 文件系统会默认分配给目录文件1个inode和至少一个data block。data block用以记录这个目录下的文件信息,如文件名和文件所占用的inode。如果一个block不够,会多分配几个block。


补充内容:


当需要查看每个文件的inode编号时,可以利用ls -i 查看。如果只想查看当前目录下的文件夹的信息,可以使用 ls -dl查看。例如,




可以看出,ls -l 的第2列是当前文件夹下inode的个数(引用计数),如果类型是[-]时,都为1。如果有link的话,引用就可能不止1个了。接着是,拥有者、所属的用户群,以Byte为代为的大小,内容修改时间以及文件名。可以看出,有些文件夹因为文件较多,信息量较大,占用的不止一个block size。


最后总结一下Block和Sectors之间的关系:


Block的操作系统抽象出来的概念,而Sector是一个物理概念。Block一般是整数倍的Sector的Size。所以,Linux所支持的Block Size是1KB(2*Sector Size)、2KB(4*Sector Size)和4KB(8*Sector Size)。而且,Linux还规定Block Size一定小于等于内存的页面大小。


Linux的文件类型有5种:-,普通文件(包括二进制文件或者文本文件等);d,目录文件;c,字符设备文件;b,块设备文件;l,链接文件。



0 0
原创粉丝点击