- 浏览: 596451 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (669)
- oracle (36)
- java (98)
- spring (48)
- UML (2)
- hibernate (10)
- tomcat (7)
- 高性能 (11)
- mysql (25)
- sql (19)
- web (42)
- 数据库设计 (4)
- Nio (6)
- Netty (8)
- Excel (3)
- File (4)
- AOP (1)
- Jetty (1)
- Log4J (4)
- 链表 (1)
- Spring Junit4 (3)
- Autowired Resource (0)
- Jackson (1)
- Javascript (58)
- Spring Cache (2)
- Spring - CXF (2)
- Spring Inject (2)
- 汉字拼音 (3)
- 代理模式 (3)
- Spring事务 (4)
- ActiveMQ (6)
- XML (3)
- Cglib (2)
- Activiti (15)
- 附件问题 (1)
- javaMail (1)
- Thread (19)
- 算法 (6)
- 正则表达式 (3)
- 国际化 (2)
- Json (3)
- EJB (3)
- Struts2 (1)
- Maven (7)
- Mybatis (7)
- Redis (8)
- DWR (1)
- Lucene (2)
- Linux (73)
- 杂谈 (2)
- CSS (13)
- Linux服务篇 (3)
- Kettle (9)
- android (81)
- protocol (2)
- EasyUI (6)
- nginx (2)
- zookeeper (6)
- Hadoop (41)
- cache (7)
- shiro (3)
- HBase (12)
- Hive (8)
- Spark (15)
- Scala (16)
- YARN (3)
- Kafka (5)
- Sqoop (2)
- Pig (3)
- Vue (6)
- sprint boot (19)
- dubbo (2)
- mongodb (2)
最新评论
Linux最传统的磁盘文件系统(filesystem)使用的是EXT2这个啦!所以要了解文件系统就得要由认识EXT2开始! 而文件系统是创建在硬盘上面的,因此我们得了解硬盘的物理组成才行。磁盘物理组成的部分我们在第零章谈过了,至于磁盘分区则在第三章谈过了,所以底下只会很快的复习这两部份。 重点在于inode, block还有superblock等文件系统的基本部分喔!
硬盘组成与分割的复习
由于各项磁盘的物理组成我们在第零章里面就介绍过, 同时第三章也谈过分割的概念了, 所以这个小节我们就拿之前的重点出来介绍就好了!详细的信息请您回去那两章自行复习喔!^_^。 好了,首先说明一下磁盘的物理组成,整颗磁盘的组成主要有:
从上面我们知道数据储存与读取的重点在于磁盘盘,而磁盘盘上的物理组成则为(假设此磁盘为单盘片, 磁盘盘图标请参考第三章图2.2.1的示意):
各种接口的磁盘在Linux中的文件名分别为:
复习完物理组成后,来复习一下磁盘分区吧!所谓的磁盘分区指的是告诉操作系统『我这颗磁盘在此分割槽可以存取的区域是由 A 磁柱到 B 磁柱之间的区块』, 如此一来操作系统就能够知道他可以在所指定的区块内进行文件数据的读/写/搜寻等动作了。 也就是说,磁盘分区就是指定分割槽的启始与结束磁柱就是了。
那么指定分割槽的磁柱范围是记录在哪里?就是第一个扇区的分割表中啦!但是因为分割表仅有64bytes而已, 因此最多只能记录四笔分割槽的记录,这四笔记录我们称为主要 (primary) 或延伸 (extended) 分割槽,其中扩展分配槽还可以再分割出逻辑分割槽 (logical) , 而能被格式化的则仅有主要分割与逻辑分割而已。
最后,我们再将第三章关于分割的定义拿出来说明一下啰:
文件系统特性
我们都知道磁盘分区完毕后还需要进行格式化(format),之后操作系统才能够使用这个分割槽。 为什么需要进行『格式化』呢?这是因为每种操作系统所配置的文件属性/权限并不相同, 为了存放这些文件所需的数据,因此就需要将分割槽进行格式化,以成为操作系统能够利用的『文件系统格式(filesystem)』。
由此我们也能够知道,每种操作系统能够使用的文件系统并不相同。 举例来说,windows 98 以前的微软操作系统主要利用的文件系统是 FAT (或 FAT16),windows 2000 以后的版本有所谓的 NTFS 文件系统,至于 Linux 的正统文件系统则为 Ext2 (Linux second extended file system, ext2fs)这一个。此外,在默认的情况下,windows 操作系统是不会认识 Linux 的 Ext2 的。
传统的磁盘与文件系统之应用中,一个分割槽就是只能够被格式化成为一个文件系统,所以我们可以说一个 filesystem 就是一个 partition。但是由于新技术的利用,例如我们常听到的LVM与软件磁盘阵列(software raid), 这些技术可以将一个分割槽格式化为多个文件系统(例如LVM),也能够将多个分割槽合成一个文件系统(LVM, RAID)! 所以说,目前我们在格式化时已经不再说成针对 partition 来格式化了, 通常我们可以称呼一个可被挂载的数据为一个文件系统而不是一个分割槽喔!
那么文件系统是如何运行的呢?这与操作系统的文件数据有关。较新的操作系统的文件数据除了文件实际内容外, 通常含有非常多的属性,例如 Linux 操作系统的文件权限(rwx)与文件属性(拥有者、群组、时间参数等)。 文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到 inode 中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等。
每个 inode 与 block 都有编号,至于这三个数据的意义可以简略说明如下:
我们将 inode 与 block 区块用图解来说明一下,如下图所示,文件系统先格式化出 inode 与 block 的区块,假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内),而这个 inode 记录了文件数据的实际放置点为 2, 7, 13, 15 这四个 block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个 block 内容读出来! 那么数据的读取就如同下图中的箭头所指定的模样了。
这种数据存取的方法我们称为索引式文件系统(indexed allocation)。那有没有其他的惯用文件系统可以比较一下啊? 有的,那就是我们惯用的闪盘(闪存),闪盘使用的文件系统一般为 FAT 格式。FAT 这种格式的文件系统并没有 inode 存在,所以 FAT 没有办法将这个文件的所有 block 在一开始就读取出来。每个 block 号码都记录在前一个 block 当中, 他的读取方式有点像底下这样:
上图中我们假设文件的数据依序写入1->7->4->15号这四个 block 号码中, 但这个文件系统没有办法一口气就知道四个 block 的号码,他得要一个一个的将 block 读出后,才会知道下一个 block 在何处。 如果同一个文件数据写入的 block 分散的太过厉害时,则我们的磁盘读取头将无法在磁盘转一圈就读到所有的数据, 因此磁盘就会多转好几圈才能完整的读取到这个文件的内容!
常常会听到所谓的『碎片整理』吧? 需要碎片整理的原因就是文件写入的 block 太过于离散了,此时文件读取的效能将会变的很差所致。 这个时候可以透过碎片整理将同一个文件所属的 blocks 汇整在一起,这样数据的读取会比较容易啊! 想当然尔,FAT 的文件系统需要经常的碎片整理一下,那么 Ext2 是否需要磁盘重整呢?
由于 Ext2 是索引式文件系统,基本上不太需要常常进行碎片整理的。但是如果文件系统使用太久, 常常删除/编辑/新增文件时,那么还是可能会造成文件数据太过于离散的问题,此时或许会需要进行重整一下的。 不过,老实说,鸟哥倒是没有在 Linux 操作系统上面进行过 Ext2/Ext3 文件系统的碎片整理说!似乎不太需要啦!^_^
Linux 的 EXT2 文件系统(inode):
在第六章当中我们介绍过 Linux 的文件除了原有的数据内容外,还含有非常多的权限与属性,这些权限与属性是为了保护每个用户所拥有数据的隐密性。 而前一小节我们知道 filesystem 里面可能含有的 inode/block/superblock 等。为什么要谈这个呢?因为标准的 Linux 文件系统 Ext2 就是使用这种 inode 为基础的文件系统啦!
而如同前一小节所说的,inode 的内容在记录文件的权限与相关属性,至于 block 区块则是在记录文件的实际内容。 而且文件系统一开始就将 inode 与 block 规划好了,除非重新格式化(或者利用 resize2fs 等命令变更文件系统大小),否则 inode 与 block 固定后就不再变动。但是如果仔细考虑一下,如果我的文件系统高达数百GB时, 那么将所有的 inode 与 block 通通放置在一起将是很不智的决定,因为 inode 与 block 的数量太庞大,不容易管理。
为此之故,因此 Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。感觉上就好像我们在当兵时,一个营里面有分成数个连,每个连有自己的联络系统, 但最终都向营部回报连上最正确的信息一般!这样分成一群群的比较好管理啦!整个来说,Ext2 格式化后有点像底下这样:
在整体的规划当中,文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动管理程序, 这是个非常重要的设计,因为如此一来我们就能够将不同的启动管理程序安装到个别的文件系统最前端,而不用覆盖整颗硬盘唯一的 MBR, 这样也才能够制作出多重引导的环境啊!至于每一个区块群组(block group)的六个主要内容说明如后:
data block (数据区块)
data block 是用来放置文件内容数据地方,在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已。在格式化时 block 的大小就固定了,且每个 block 都有编号,以方便 inode 的记录啦。 不过要注意的是,由于 block 大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。 因为 block 大小而产生的 Ext2 文件系统限制如下:(注2)
你需要注意的是,虽然 Ext2 已经能够支持大于 2GB 以上的单一文件容量,不过某些应用程序依然使用旧的限制, 也就是说,某些程序只能够捉到小于 2GB 以下的文件而已,这就跟文件系统无关了! 举例来说,鸟哥在环工方面的应用中有一套秀图软件称为PAVE(注3), 这套软件就无法捉到鸟哥在数值模式仿真后产生的大于 2GB 以上的文件!害的鸟哥常常还要重跑数值模式...
除此之外 Ext2 文件系统的 block 还有什么限制呢?有的!基本限制如下:
如上第四点所说,由于每个 block 仅能容纳一个文件的数据而已,因此如果你的文件都非常小,但是你的 block 在格式化时却选用最大的 4K 时,可能会产生一些容量的浪费喔!我们以底下的一个简单例题来算一下空间的浪费吧!
什么情况会产生上述的状况呢?例如 BBS 网站的数据啦!如果 BBS 上面的数据使用的是纯文本文件来记载每篇留言, 而留言内容如果都写上『如题』时,想一想,是否就会产生很多小文件了呢?
好,既然大的 block 可能会产生较严重的磁盘容量浪费,那么我们是否就将 block 大小订为 1K 即可? 这也不妥,因为如果 block 较小的话,那么大型文件将会占用数量更多的 block ,而 inode 也要记录更多的 block 号码,此时将可能导致文件系统不良的读写效能。
所以我们可以说,在您进行文件系统的格式化之前,请先想好该文件系统预计使用的情况。 以鸟哥来说,我的数值模式仿真平台随便一个文件都好几百 MB,那么 block 容量当然选择较大的!至少文件系统就不必记录太多的 block 号码,读写起来也比较方便啊!
inode table (inode 表格)
再来讨论一下 inode 这个玩意儿吧!如前所述 inode 的内容在记录文件的属性以及该文件实际数据是放置在哪几号 block 内! 基本上,inode 记录的文件数据至少有底下这些:(注4)
inode 的数量与大小也是在格式化时就已经固定了,除此之外 inode 还有些什么特色呢?
我们简略来分析一下 inode / block 与文件大小的关系好了。inode 要记录的数据非常多,但偏偏又只有 128bytes 而已, 而 inode 记录一个 block 号码要花掉 4byte ,假设我一个文件有 400MB 且每个 block 为 4K 时, 那么至少也要十万笔 block 号码的记录呢!inode 哪有这么多可记录的信息?为此我们的系统很聪明的将 inode 记录 block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区。这是啥?我们将 inode 的结构画一下好了。
上图最左边为 inode 本身 (128 bytes),里面有 12 个直接指向 block 号码的对照,这 12 笔记录就能够直接取得 block 号码啦! 至于所谓的间接就是再拿一个 block 来当作记录 block 号码的记录区,如果文件太大时, 就会使用间接的 block 来记录编号。如上图 1.3.2 当中间接只是拿一个 block 来记录额外的号码而已。 同理,如果文件持续长大,那么就会利用所谓的双间接,第一个 block 仅再指出下一个记录编号的 block 在哪里, 实际记录的在第二个 block 当中。依此类推,三间接就是利用第三层 block 来记录编号啦!
这样子 inode 能够指定多少个 block 呢?我们以较小的 1K block 来说明好了,可以指定的情况如下:
此时我们知道当文件系统将 block 格式化为 1K 大小时,能够容纳的最大文件为 16GB,比较一下文件系统限制表的结果可发现是一致的!但这个方法不能用在 2K 及 4K block 大小的计算中, 因为大于 2K 的 block 将会受到 Ext2 文件系统本身的限制,所以计算的结果会不太符合之故。
Superblock (超级区块)
Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。他记录的信息主要有:
superblock 是非常重要的,因为我们这个文件系统的基本信息都写在这里,因此,如果 superblock 死掉了, 你的文件系统可能就需要花费很多时间去挽救啦!一般来说, superblock 的大小为 1024bytes。相关的 superblock 信息我们等一下会以 dumpe2fs 命令来呼叫出来观察喔!
此外,每个 block group 都可能含有 superblock 喔!但是我们也说一个文件系统应该仅有一个 superblock 而已,那是怎么回事啊? 事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock , 而若含有 superblock 则该 superblock 主要是做为第一个 block group 内 superblock 的备份咯,这样可以进行 superblock 的救援呢!
Filesystem Description (文件系统描述说明)
这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段 (superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间。这部份也能够用 dumpe2fs 来观察的。
block bitmap (区块对照表)
如果你想要新增文件时总会用到 block 吧!那你要使用哪个 block 来记录呢?当然是选择『空的 block 』来记录新文件的数据啰。 那你怎么知道哪个 block 是空的?这就得要透过 block bitmap 的辅助了。从 block bitmap 当中可以知道哪些 block 是空的,因此我们的系统就能够很快速的找到可使用的空间来处置文件啰。
同样的,如果你删除某些文件时,那么那些文件原本占用的 block 号码就得要释放出来, 此时在 block bitmap 当中相对应到该 block 号码的标志就得要修改成为『未使用中』啰!这就是 bitmap 的功能。
inode bitmap (inode 对照表)
这个其实与 block bitmap 是类似的功能,只是 block bitmap 记录的是使用与未使用的 block 号码, 至于 inode bitmap 则是记录使用与未使用的 inode 号码啰!
了解了文件系统的概念之后,再来当然是观察这个文件系统啰!刚刚谈到的各部分数据都与 block 号码有关! 每个区段与 superblock 的信息都可以使用 dumpe2fs 这个命令来查询的!查询的方法与实际的观察如下:
如上所示,利用 dumpe2fs 可以查询到非常多的信息,不过依内容主要可以区分为上半部是 superblock 内容, 下半部则是每个 block group 的信息了。从上面的表格中我们可以观察到这个 /dev/hdc2 规划的 block 为 4K, 第一个 block 号码为 0 号,且 block group 内的所有信息都以 block 的号码来表示的。 然后在 superblock 中还有谈到目前这个文件系统的可用 block 与 inode 数量喔!
至于 block group 的内容我们单纯看 Group0 信息好了。从上表中我们可以发现:
如果你对文件系统的详细信息还有更多想要了解的话,那么请参考本章最后一小节的介绍喔! 否则文件系统看到这里对于基础认知您应该是已经相当足够啦!底下则是要探讨一下, 那么这个文件系统概念与实际的目录树应用有啥关连啊?
与目录树的关系
由前一小节的介绍我们知道在 Linux 系统下,每个文件(不管是一般文件还是目录文件)都会占用一个 inode , 且可依据文件内容的大小来分配多个 block 给该文件使用。而由第六章的权限说明中我们知道目录的内容在记录文件名, 一般文件才是实际记录数据内容的地方。那么目录与文件在 Ext2 文件系统当中是如何记录数据的呢? 基本上可以这样说:
目录
当我们在 Linux 下的 ext2 文件系统创建一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。也就是说目录所占用的 block 内容在记录如下的信息:
如果想要实际观察 root 家目录内的文件所占用的 inode 号码时,可以使用 ls -i 这个选项来处理:
由于每个人所使用的计算机并不相同,系统安装时选择的项目与 partition 都不一样,因此你的环境不可能与我的 inode 号码一模一样!上表的左边所列出的 inode 仅是鸟哥的系统所显示的结果而已!而由这个目录的 block 结果我们现在就能够知道, 当你使用『 ll / 』时,出现的目录几乎都是 1024 的倍数,为什么呢?因为每个 block 的数量都是 1K, 2K, 4K 嘛! 看一下鸟哥的环境:
由于鸟哥的根目录 /dev/hdc2 使用的 block 大小为 4K ,因此每个目录几乎都是 4K 的倍数。 其中由于 /sbin 的内容比较复杂因此占用了 3 个 block ,此外,鸟哥的系统中 /boot 为独立的 partition , 该 partition 的 block 为 1K 而已,因此该目录就仅占用 1024 bytes 的大小啰!至于奇怪的 /proc 我们在第六章就讲过该目录不占硬盘容量, 所以当然耗用的 block 就是 0 啰!
文件:
当我们在 Linux 下的 ext2 创建一个一般文件时, ext2 会分配一个 inode 与相对于该文件大小的 block 数量给该文件。例如:假设我的一个 block 为 4 Kbytes ,而我要创建一个 100 KBytes 的文件,那么 linux 将分配一个 inode 与 25 个 block 来储存该文件! 但同时请注意,由于 inode 仅有 12 个直接指向,因此还要多一个 block 来作为区块号码的记录喔!
目录树读取:
好了,经过上面的说明你也应该要很清楚的知道 inode 本身并不记录文件名,文件名的记录是在目录的 block 当中。 因此在第六章文件与目录的权限说明中, 我们才会提到『新增/删除/更名文件名与目录的 w 权限有关』的特色!那么因为文件名是记录在目录的 block 当中, 因此当我们要读取某个文件时,就务必会经过目录的 inode 与 block ,然后才能够找到那个待读取文件的 inode 号码, 最终才会读到正确的文件的 block 内的数据。
由于目录树是由根目录开始读起,因此系统透过挂载的信息可以找到挂载点的 inode 号码(通常一个 filesystem 的最顶层 inode 号码会由 2 号开始喔!),此时就能够得到根目录的 inode 内容,并依据该 inode 读取根目录的 block 内的文件名数据,再一层一层的往下读到正确的档名。
举例来说,如果我想要读取 /etc/passwd 这个文件时,系统是如何读取的呢?
在鸟哥的系统上面与 /etc/passwd 有关的目录与文件数据如上表所示,该文件的读取流程为(假设读取者身份为 vbird 这个一般身份使用者):
filesystem 大小与磁盘读取效能:
另外,关于文件系统的使用效率上,当你的一个文件系统规划的很大时,例如 100GB 这么大时, 由于硬盘上面的数据总是来来去去的,所以,整个文件系统上面的文件通常无法连续写在一起(block 号码不会连续的意思), 而是填入式的将数据填入没有被使用的 block 当中。如果文件写入的 block 真的分的很散, 此时就会有所谓的文件数据离散的问题发生了。
如前所述,虽然我们的 ext2 在 inode 处已经将该文件所记录的 block 号码都记上了, 所以数据可以一次性读取,但是如果文件真的太过离散,确实还是会发生读取效率低落的问题。 因为磁盘读取头还是得要在整个文件系统中来来去去的频繁读取! 果真如此,那么可以将整个 filesystme 内的数据全部复制出来,将该 filesystem 重新格式化, 再将数据给他复制回去即可解决这个问题。
此外,如果 filesystem 真的太大了,那么当一个文件分别记录在这个文件系统的最前面与最后面的 block 号码中, 此时会造成硬盘的机械手臂移动幅度过大,也会造成数据读取效能的低落。而且读取头在搜寻整个 filesystem 时, 也会花费比较多的时间去搜寻!因此, partition 的规划并不是越大越好, 而是真的要针对您的主机用途来进行规划才行!^_^
EXT2/EXT3 文件的存取与日志式文件系统的功能
上一小节谈到的仅是读取而已,那么如果是新建一个文件或目录时,我们的 Ext2 是如何处理的呢? 这个时候就得要 block bitmap 及 inode bitmap 的帮忙了!假设我们想要新增一个文件,此时文件系统的行为是:
一般来说,我们将 inode table 与 data block 称为数据存放区域,至于其他例如 superblock、 block bitmap 与 inode bitmap 等区段就被称为 metadata (中介数据) 啰,因为 superblock, inode bitmap 及 block bitmap 的数据是经常变动的,每次新增、移除、编辑时都可能会影响到这三个部分的数据,因此才被称为中介数据的啦。
挂载点的意义 (mount point):
每个 filesystem 都有独立的 inode / block / superblock 等信息,这个文件系统要能够链接到目录树才能被我们使用。 将文件系统与目录树结合的动作我们称为『挂载』。 关于挂载的一些特性我们在第三章稍微提过, 重点是:挂载点一定是目录,该目录为进入该文件系统的入口。 因此并不是你有任何文件系统都能使用,必须要『挂载』到目录树的某个目录后,才能够使用该文件系统的。
举例来说,如果你是依据鸟哥的方法安装你的 CentOS 5.x 的话, 那么应该会有三个挂载点才是,分别是 /, /boot, /home 三个 (鸟哥的系统上对应的装置文件名为 /dev/hdc2, /dev/hdc1, /dev/hdc3)。 那如果观察这三个目录的 inode 号码时,我们可以发现如下的情况:
看到了吧!由于 filesystem 最顶层的目录之 inode 一般为 2 号,因此可以发现 /, /boot, /home 为三个不同的 filesystem 啰! (因为每一行的文件属性并不相同,且三个目录的挂载点也均不相同之故。) 我们在第七章一开始的路径中曾经提到根目录下的 . 与 .. 是相同的东西, 因为权限是一模一样嘛!如果使用文件系统的观点来看,同一个 filesystem 的某个 inode 只会对应到一个文件内容而已(因为一个文件占用一个 inode 之故), 因此我们可以透过判断 inode 号码来确认不同文件名是否为相同的文件喔!所以可以这样看:
上面的信息中由于挂载点均为 / ,因此三个文件 (/, /., /..) 均在同一个 filesystem 内,而这三个文件的 inode 号码均为 2 号,因此这三个档名都指向同一个 inode 号码,当然这三个文件的内容也就完全一模一样了! 也就是说,根目录的上一级 (/..) 就是他自己!这么说,看的懂了吗? ^_^
转自:http://vbird.dic.ksu.edu.tw/linux_basic/0230filesystem_1.php
硬盘组成与分割的复习
由于各项磁盘的物理组成我们在第零章里面就介绍过, 同时第三章也谈过分割的概念了, 所以这个小节我们就拿之前的重点出来介绍就好了!详细的信息请您回去那两章自行复习喔!^_^。 好了,首先说明一下磁盘的物理组成,整颗磁盘的组成主要有:
A 圆形的磁盘盘(主要记录数据的部分); B 机械手臂,与在机械手臂上的磁盘读取头(可擦写磁盘盘上的数据); C 主轴马达,可以转动磁盘盘,让机械手臂的读取头在磁盘盘上读写数据。
从上面我们知道数据储存与读取的重点在于磁盘盘,而磁盘盘上的物理组成则为(假设此磁盘为单盘片, 磁盘盘图标请参考第三章图2.2.1的示意):
A 扇区(Sector)为最小的物理储存单位,每个扇区为 512 bytes; B 将扇区组成一个圆,那就是磁柱(Cylinder),磁柱是分割槽(partition)的最小单位; C 第一个扇区最重要,里面有:(1)主要启动区(Master boot record, MBR)及分割表(partition table), 其中 MBR 占有 446 bytes,而 partition table 则占有 64 bytes。
各种接口的磁盘在Linux中的文件名分别为:
A /dev/sd[a-p][1-15]:为SCSI, SATA, U盘, Flash闪盘等接口的磁盘文件名; B /dev/hd[a-d][1-63]:为 IDE 接口的磁盘文件名;
复习完物理组成后,来复习一下磁盘分区吧!所谓的磁盘分区指的是告诉操作系统『我这颗磁盘在此分割槽可以存取的区域是由 A 磁柱到 B 磁柱之间的区块』, 如此一来操作系统就能够知道他可以在所指定的区块内进行文件数据的读/写/搜寻等动作了。 也就是说,磁盘分区就是指定分割槽的启始与结束磁柱就是了。
那么指定分割槽的磁柱范围是记录在哪里?就是第一个扇区的分割表中啦!但是因为分割表仅有64bytes而已, 因此最多只能记录四笔分割槽的记录,这四笔记录我们称为主要 (primary) 或延伸 (extended) 分割槽,其中扩展分配槽还可以再分割出逻辑分割槽 (logical) , 而能被格式化的则仅有主要分割与逻辑分割而已。
最后,我们再将第三章关于分割的定义拿出来说明一下啰:
A 主要分割与扩展分配最多可以有四笔(硬盘的限制) B 扩展分配最多只能有一个(操作系统的限制) C 逻辑分割是由扩展分配持续切割出来的分割槽; C 能够被格式化后,作为数据存取的分割槽为主要分割与逻辑分割。扩展分配无法格式化; D 逻辑分割的数量依操作系统而不同,在Linux系统中,IDE硬盘最多有59个逻辑分割(5号到63号), SATA硬盘则有11个逻辑分割(5号到15号)。
文件系统特性
我们都知道磁盘分区完毕后还需要进行格式化(format),之后操作系统才能够使用这个分割槽。 为什么需要进行『格式化』呢?这是因为每种操作系统所配置的文件属性/权限并不相同, 为了存放这些文件所需的数据,因此就需要将分割槽进行格式化,以成为操作系统能够利用的『文件系统格式(filesystem)』。
由此我们也能够知道,每种操作系统能够使用的文件系统并不相同。 举例来说,windows 98 以前的微软操作系统主要利用的文件系统是 FAT (或 FAT16),windows 2000 以后的版本有所谓的 NTFS 文件系统,至于 Linux 的正统文件系统则为 Ext2 (Linux second extended file system, ext2fs)这一个。此外,在默认的情况下,windows 操作系统是不会认识 Linux 的 Ext2 的。
传统的磁盘与文件系统之应用中,一个分割槽就是只能够被格式化成为一个文件系统,所以我们可以说一个 filesystem 就是一个 partition。但是由于新技术的利用,例如我们常听到的LVM与软件磁盘阵列(software raid), 这些技术可以将一个分割槽格式化为多个文件系统(例如LVM),也能够将多个分割槽合成一个文件系统(LVM, RAID)! 所以说,目前我们在格式化时已经不再说成针对 partition 来格式化了, 通常我们可以称呼一个可被挂载的数据为一个文件系统而不是一个分割槽喔!
那么文件系统是如何运行的呢?这与操作系统的文件数据有关。较新的操作系统的文件数据除了文件实际内容外, 通常含有非常多的属性,例如 Linux 操作系统的文件权限(rwx)与文件属性(拥有者、群组、时间参数等)。 文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到 inode 中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等。
每个 inode 与 block 都有编号,至于这三个数据的意义可以简略说明如下:
superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等; inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码; block:实际记录文件的内容,若文件太大时,会占用多个 block 。 由于每个 inode 与 block 都有编号,而每个文件都会占用一个 inode ,inode 内则有文件数据放置的 block 号码。 因此,我们可以知道的是,如果能够找到文件的 inode 的话,那么自然就会知道这个文件所放置数据的 block 号码, 当然也就能够读出该文件的实际数据了。这是个比较有效率的作法,因为如此一来我们的磁盘就能够在短时间内读取出全部的数据, 读写的效能比较好啰。
我们将 inode 与 block 区块用图解来说明一下,如下图所示,文件系统先格式化出 inode 与 block 的区块,假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内),而这个 inode 记录了文件数据的实际放置点为 2, 7, 13, 15 这四个 block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个 block 内容读出来! 那么数据的读取就如同下图中的箭头所指定的模样了。
这种数据存取的方法我们称为索引式文件系统(indexed allocation)。那有没有其他的惯用文件系统可以比较一下啊? 有的,那就是我们惯用的闪盘(闪存),闪盘使用的文件系统一般为 FAT 格式。FAT 这种格式的文件系统并没有 inode 存在,所以 FAT 没有办法将这个文件的所有 block 在一开始就读取出来。每个 block 号码都记录在前一个 block 当中, 他的读取方式有点像底下这样:
上图中我们假设文件的数据依序写入1->7->4->15号这四个 block 号码中, 但这个文件系统没有办法一口气就知道四个 block 的号码,他得要一个一个的将 block 读出后,才会知道下一个 block 在何处。 如果同一个文件数据写入的 block 分散的太过厉害时,则我们的磁盘读取头将无法在磁盘转一圈就读到所有的数据, 因此磁盘就会多转好几圈才能完整的读取到这个文件的内容!
常常会听到所谓的『碎片整理』吧? 需要碎片整理的原因就是文件写入的 block 太过于离散了,此时文件读取的效能将会变的很差所致。 这个时候可以透过碎片整理将同一个文件所属的 blocks 汇整在一起,这样数据的读取会比较容易啊! 想当然尔,FAT 的文件系统需要经常的碎片整理一下,那么 Ext2 是否需要磁盘重整呢?
由于 Ext2 是索引式文件系统,基本上不太需要常常进行碎片整理的。但是如果文件系统使用太久, 常常删除/编辑/新增文件时,那么还是可能会造成文件数据太过于离散的问题,此时或许会需要进行重整一下的。 不过,老实说,鸟哥倒是没有在 Linux 操作系统上面进行过 Ext2/Ext3 文件系统的碎片整理说!似乎不太需要啦!^_^
Linux 的 EXT2 文件系统(inode):
在第六章当中我们介绍过 Linux 的文件除了原有的数据内容外,还含有非常多的权限与属性,这些权限与属性是为了保护每个用户所拥有数据的隐密性。 而前一小节我们知道 filesystem 里面可能含有的 inode/block/superblock 等。为什么要谈这个呢?因为标准的 Linux 文件系统 Ext2 就是使用这种 inode 为基础的文件系统啦!
而如同前一小节所说的,inode 的内容在记录文件的权限与相关属性,至于 block 区块则是在记录文件的实际内容。 而且文件系统一开始就将 inode 与 block 规划好了,除非重新格式化(或者利用 resize2fs 等命令变更文件系统大小),否则 inode 与 block 固定后就不再变动。但是如果仔细考虑一下,如果我的文件系统高达数百GB时, 那么将所有的 inode 与 block 通通放置在一起将是很不智的决定,因为 inode 与 block 的数量太庞大,不容易管理。
为此之故,因此 Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。感觉上就好像我们在当兵时,一个营里面有分成数个连,每个连有自己的联络系统, 但最终都向营部回报连上最正确的信息一般!这样分成一群群的比较好管理啦!整个来说,Ext2 格式化后有点像底下这样:
在整体的规划当中,文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动管理程序, 这是个非常重要的设计,因为如此一来我们就能够将不同的启动管理程序安装到个别的文件系统最前端,而不用覆盖整颗硬盘唯一的 MBR, 这样也才能够制作出多重引导的环境啊!至于每一个区块群组(block group)的六个主要内容说明如后:
data block (数据区块)
data block 是用来放置文件内容数据地方,在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已。在格式化时 block 的大小就固定了,且每个 block 都有编号,以方便 inode 的记录啦。 不过要注意的是,由于 block 大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。 因为 block 大小而产生的 Ext2 文件系统限制如下:(注2)
你需要注意的是,虽然 Ext2 已经能够支持大于 2GB 以上的单一文件容量,不过某些应用程序依然使用旧的限制, 也就是说,某些程序只能够捉到小于 2GB 以下的文件而已,这就跟文件系统无关了! 举例来说,鸟哥在环工方面的应用中有一套秀图软件称为PAVE(注3), 这套软件就无法捉到鸟哥在数值模式仿真后产生的大于 2GB 以上的文件!害的鸟哥常常还要重跑数值模式...
除此之外 Ext2 文件系统的 block 还有什么限制呢?有的!基本限制如下:
A 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化); B 每个 block 内最多只能够放置一个文件的数据; C 承上,如果文件大于 block 的大小,则一个文件会占用多个 block 数量; D 承上,若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)。
如上第四点所说,由于每个 block 仅能容纳一个文件的数据而已,因此如果你的文件都非常小,但是你的 block 在格式化时却选用最大的 4K 时,可能会产生一些容量的浪费喔!我们以底下的一个简单例题来算一下空间的浪费吧!
例题: 假设你的Ext2文件系统使用 4K block ,而该文件系统中有 10000 个小文件,每个文件大小均为 50bytes, 请问此时你的磁盘浪费多少容量? 答: 由于 Ext2 文件系统中一个 block 仅能容纳一个文件,因此每个 block 会浪费『 4096 - 50 = 4046 (byte)』, 系统中总共有一万个小文件,所有文件容量为:50 (bytes) x 10000 = 488.3Kbytes,但此时浪费的容量为:『 4046 (bytes) x 10000 = 38.6MBytes 』。想一想,不到 1MB 的总文件容量却浪费将近 40MB 的容量,且文件越多将造成越多的磁盘容量浪费。
什么情况会产生上述的状况呢?例如 BBS 网站的数据啦!如果 BBS 上面的数据使用的是纯文本文件来记载每篇留言, 而留言内容如果都写上『如题』时,想一想,是否就会产生很多小文件了呢?
好,既然大的 block 可能会产生较严重的磁盘容量浪费,那么我们是否就将 block 大小订为 1K 即可? 这也不妥,因为如果 block 较小的话,那么大型文件将会占用数量更多的 block ,而 inode 也要记录更多的 block 号码,此时将可能导致文件系统不良的读写效能。
所以我们可以说,在您进行文件系统的格式化之前,请先想好该文件系统预计使用的情况。 以鸟哥来说,我的数值模式仿真平台随便一个文件都好几百 MB,那么 block 容量当然选择较大的!至少文件系统就不必记录太多的 block 号码,读写起来也比较方便啊!
inode table (inode 表格)
再来讨论一下 inode 这个玩意儿吧!如前所述 inode 的内容在记录文件的属性以及该文件实际数据是放置在哪几号 block 内! 基本上,inode 记录的文件数据至少有底下这些:(注4)
该文件的存取模式(read/write/excute); 该文件的拥有者与群组(owner/group); 该文件的容量; 该文件创建或状态改变的时间(ctime); 最近一次的读取时间(atime); 最近修改的时间(mtime); 定义文件特性的旗标(flag),如 SetUID...; 该文件真正内容的指向 (pointer);
inode 的数量与大小也是在格式化时就已经固定了,除此之外 inode 还有些什么特色呢?
每个 inode 大小均固定为 128 bytes; 每个文件都仅会占用一个 inode 而已; 承上,因此文件系统能够创建的文件数量与 inode 的数量有关; 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容。
我们简略来分析一下 inode / block 与文件大小的关系好了。inode 要记录的数据非常多,但偏偏又只有 128bytes 而已, 而 inode 记录一个 block 号码要花掉 4byte ,假设我一个文件有 400MB 且每个 block 为 4K 时, 那么至少也要十万笔 block 号码的记录呢!inode 哪有这么多可记录的信息?为此我们的系统很聪明的将 inode 记录 block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区。这是啥?我们将 inode 的结构画一下好了。
上图最左边为 inode 本身 (128 bytes),里面有 12 个直接指向 block 号码的对照,这 12 笔记录就能够直接取得 block 号码啦! 至于所谓的间接就是再拿一个 block 来当作记录 block 号码的记录区,如果文件太大时, 就会使用间接的 block 来记录编号。如上图 1.3.2 当中间接只是拿一个 block 来记录额外的号码而已。 同理,如果文件持续长大,那么就会利用所谓的双间接,第一个 block 仅再指出下一个记录编号的 block 在哪里, 实际记录的在第二个 block 当中。依此类推,三间接就是利用第三层 block 来记录编号啦!
这样子 inode 能够指定多少个 block 呢?我们以较小的 1K block 来说明好了,可以指定的情况如下:
12 个直接指向: 12*1K=12K 由于是直接指向,所以总共可记录 12 笔记录,因此总额大小为如上所示; 间接: 256*1K=256K 每笔 block 号码的记录会花去 4bytes,因此 1K 的大小能够记录 256 笔记录,因此一个间接可以记录的文件大小如上; 双间接: 256*256*1K=2562K 第一层 block 会指定 256 个第二层,每个第二层可以指定 256 个号码,因此总额大小如上; 三间接: 256*256*256*1K=2563K 第一层 block 会指定 256 个第二层,每个第二层可以指定 256 个第三层,每个第三层可以指定 256 个号码,因此总额大小如上; 总额:将直接、间接、双间接、三间接加总,得到 12 + 256 + 256*256 + 256*256*256 (K) = 16GB
此时我们知道当文件系统将 block 格式化为 1K 大小时,能够容纳的最大文件为 16GB,比较一下文件系统限制表的结果可发现是一致的!但这个方法不能用在 2K 及 4K block 大小的计算中, 因为大于 2K 的 block 将会受到 Ext2 文件系统本身的限制,所以计算的结果会不太符合之故。
Superblock (超级区块)
Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。他记录的信息主要有:
A block 与 inode 的总量; B 未使用与已使用的 inode / block 数量; C block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128 bytes); D filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息; E 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1 。
superblock 是非常重要的,因为我们这个文件系统的基本信息都写在这里,因此,如果 superblock 死掉了, 你的文件系统可能就需要花费很多时间去挽救啦!一般来说, superblock 的大小为 1024bytes。相关的 superblock 信息我们等一下会以 dumpe2fs 命令来呼叫出来观察喔!
此外,每个 block group 都可能含有 superblock 喔!但是我们也说一个文件系统应该仅有一个 superblock 而已,那是怎么回事啊? 事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock , 而若含有 superblock 则该 superblock 主要是做为第一个 block group 内 superblock 的备份咯,这样可以进行 superblock 的救援呢!
Filesystem Description (文件系统描述说明)
这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段 (superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间。这部份也能够用 dumpe2fs 来观察的。
block bitmap (区块对照表)
如果你想要新增文件时总会用到 block 吧!那你要使用哪个 block 来记录呢?当然是选择『空的 block 』来记录新文件的数据啰。 那你怎么知道哪个 block 是空的?这就得要透过 block bitmap 的辅助了。从 block bitmap 当中可以知道哪些 block 是空的,因此我们的系统就能够很快速的找到可使用的空间来处置文件啰。
同样的,如果你删除某些文件时,那么那些文件原本占用的 block 号码就得要释放出来, 此时在 block bitmap 当中相对应到该 block 号码的标志就得要修改成为『未使用中』啰!这就是 bitmap 的功能。
inode bitmap (inode 对照表)
这个其实与 block bitmap 是类似的功能,只是 block bitmap 记录的是使用与未使用的 block 号码, 至于 inode bitmap 则是记录使用与未使用的 inode 号码啰!
了解了文件系统的概念之后,再来当然是观察这个文件系统啰!刚刚谈到的各部分数据都与 block 号码有关! 每个区段与 superblock 的信息都可以使用 dumpe2fs 这个命令来查询的!查询的方法与实际的观察如下:
[root@www ~]# dumpe2fs [-bh] 装置文件名 选项与参数: -b :列出保留为坏轨的部分(一般用不到吧!?) -h :仅列出 superblock 的数据,不会列出其他的区段内容! 范例:找出我的根目录磁盘文件名,并观察文件系统的相关信息 [root@www ~]# df <==这个命令可以叫出目前挂载的装置 Filesystem 1K-blocks Used Available Use% Mounted on /dev/hdc2 9920624 3822848 5585708 41% / <==就是这个光! /dev/hdc3 4956316 141376 4559108 4% /home /dev/hdc1 101086 11126 84741 12% /boot tmpfs 371332 0 371332 0% /dev/shm [root@www ~]# dumpe2fs /dev/hdc2 dumpe2fs 1.39 (29-May-2006) Filesystem volume name: /1 <==这个是文件系统的名称(Label) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file Default mount options: user_xattr acl <==默认挂载的参数 Filesystem state: clean <==这个文件系统是没问题的(clean) Errors behavior: Continue Filesystem OS type: Linux Inode count: 2560864 <==inode的总数 Block count: 2560359 <==block的总数 Free blocks: 1524760 <==还有多少个 block 可用 Free inodes: 2411225 <==还有多少个 inode 可用 First block: 0 Block size: 4096 <==每个 block 的大小啦! Filesystem created: Fri Sep 5 01:49:20 2008 Last mount time: Mon Sep 22 12:09:30 2008 Last write time: Mon Sep 22 12:09:30 2008 Last checked: Fri Sep 5 01:49:20 2008 First inode: 11 Inode size: 128 <==每个 inode 的大小 Journal inode: 8 <==底下这三个与下一小节有关 Journal backup: inode blocks Journal size: 128M Group 0: (Blocks 0-32767) <==第一个 data group 内容, 包含 block 的启始/结束号码 Primary superblock at 0, Group descriptors at 1-1 <==超级区块在 0 号 block Reserved GDT blocks at 2-626 Block bitmap at 627 (+627), Inode bitmap at 628 (+628) Inode table at 629-1641 (+629) <==inode table 所在的 block 0 free blocks, 32405 free inodes, 2 directories <==所有 block 都用完了! Free blocks: Free inodes: 12-32416 <==剩余未使用的 inode 号码 Group 1: (Blocks 32768-65535) ....(底下省略).... # 由于数据量非常的庞大,因此鸟哥将一些信息省略输出了!上表与你的屏幕会有点差异。 # 前半部在秀出 supberblock 的内容,包括标头名称(Label)以及inode/block的相关信息 # 后面则是每个 block group 的个别信息了!您可以看到各区段数据所在的号码! # 也就是说,基本上所有的数据还是与 block 的号码有关就是了!很重要!
如上所示,利用 dumpe2fs 可以查询到非常多的信息,不过依内容主要可以区分为上半部是 superblock 内容, 下半部则是每个 block group 的信息了。从上面的表格中我们可以观察到这个 /dev/hdc2 规划的 block 为 4K, 第一个 block 号码为 0 号,且 block group 内的所有信息都以 block 的号码来表示的。 然后在 superblock 中还有谈到目前这个文件系统的可用 block 与 inode 数量喔!
至于 block group 的内容我们单纯看 Group0 信息好了。从上表中我们可以发现:
Group0 所占用的 block 号码由 0 到 32767 号,superblock 则在第 0 号的 block 区块内! 文件系统描述说明在第 1 号 block 中; block bitmap 与 inode bitmap 则在 627 及 628 的 block 号码上。 至于 inode table 分布于 629-1641 的 block 号码中! 由于 (1)一个 inode 占用 128 bytes ,(2)总共有 1641 - 629 + 1(629本身) = 1013 个 block 花在 inode table 上, (3)每个 block 的大小为 4096 bytes(4K)。由这些数据可以算出 inode 的数量共有 1013 * 4096 / 128 = 32416 个 inode 啦! 这个 Group0 目前没有可用的 block 了,但是有剩余 32405 个 inode 未被使用; 剩余的 inode 号码为 12 号到 32416 号。
如果你对文件系统的详细信息还有更多想要了解的话,那么请参考本章最后一小节的介绍喔! 否则文件系统看到这里对于基础认知您应该是已经相当足够啦!底下则是要探讨一下, 那么这个文件系统概念与实际的目录树应用有啥关连啊?
与目录树的关系
由前一小节的介绍我们知道在 Linux 系统下,每个文件(不管是一般文件还是目录文件)都会占用一个 inode , 且可依据文件内容的大小来分配多个 block 给该文件使用。而由第六章的权限说明中我们知道目录的内容在记录文件名, 一般文件才是实际记录数据内容的地方。那么目录与文件在 Ext2 文件系统当中是如何记录数据的呢? 基本上可以这样说:
目录
当我们在 Linux 下的 ext2 文件系统创建一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。也就是说目录所占用的 block 内容在记录如下的信息:
如果想要实际观察 root 家目录内的文件所占用的 inode 号码时,可以使用 ls -i 这个选项来处理:
[root@www ~]# ls -li total 92 654683 -rw------- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg 648322 -rw-r--r-- 1 root root 42304 Sep 4 18:26 install.log 648323 -rw-r--r-- 1 root root 5661 Sep 4 18:25 install.log.syslog
由于每个人所使用的计算机并不相同,系统安装时选择的项目与 partition 都不一样,因此你的环境不可能与我的 inode 号码一模一样!上表的左边所列出的 inode 仅是鸟哥的系统所显示的结果而已!而由这个目录的 block 结果我们现在就能够知道, 当你使用『 ll / 』时,出现的目录几乎都是 1024 的倍数,为什么呢?因为每个 block 的数量都是 1K, 2K, 4K 嘛! 看一下鸟哥的环境:
[root@www ~]# ll -d / /bin /boot /proc /lost+found /sbin drwxr-xr-x 23 root root 4096 Sep 22 12:09 / <==一个 4K block drwxr-xr-x 2 root root 4096 Sep 24 00:07 /bin <==一个 4K block drwxr-xr-x 4 root root 1024 Sep 4 18:06 /boot <==一个 1K block drwx------ 2 root root 16384 Sep 5 01:49 /lost+found <==四个 4K block dr-xr-xr-x 96 root root 0 Sep 22 20:07 /proc <==此目录不占硬盘空间 drwxr-xr-x 2 root root 12288 Sep 5 12:33 /sbin <==三个 4K block
由于鸟哥的根目录 /dev/hdc2 使用的 block 大小为 4K ,因此每个目录几乎都是 4K 的倍数。 其中由于 /sbin 的内容比较复杂因此占用了 3 个 block ,此外,鸟哥的系统中 /boot 为独立的 partition , 该 partition 的 block 为 1K 而已,因此该目录就仅占用 1024 bytes 的大小啰!至于奇怪的 /proc 我们在第六章就讲过该目录不占硬盘容量, 所以当然耗用的 block 就是 0 啰!
文件:
当我们在 Linux 下的 ext2 创建一个一般文件时, ext2 会分配一个 inode 与相对于该文件大小的 block 数量给该文件。例如:假设我的一个 block 为 4 Kbytes ,而我要创建一个 100 KBytes 的文件,那么 linux 将分配一个 inode 与 25 个 block 来储存该文件! 但同时请注意,由于 inode 仅有 12 个直接指向,因此还要多一个 block 来作为区块号码的记录喔!
目录树读取:
好了,经过上面的说明你也应该要很清楚的知道 inode 本身并不记录文件名,文件名的记录是在目录的 block 当中。 因此在第六章文件与目录的权限说明中, 我们才会提到『新增/删除/更名文件名与目录的 w 权限有关』的特色!那么因为文件名是记录在目录的 block 当中, 因此当我们要读取某个文件时,就务必会经过目录的 inode 与 block ,然后才能够找到那个待读取文件的 inode 号码, 最终才会读到正确的文件的 block 内的数据。
由于目录树是由根目录开始读起,因此系统透过挂载的信息可以找到挂载点的 inode 号码(通常一个 filesystem 的最顶层 inode 号码会由 2 号开始喔!),此时就能够得到根目录的 inode 内容,并依据该 inode 读取根目录的 block 内的文件名数据,再一层一层的往下读到正确的档名。
举例来说,如果我想要读取 /etc/passwd 这个文件时,系统是如何读取的呢?
[root@www ~]# ll -di / /etc /etc/passwd 2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 / 1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc 1914888 -rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd
在鸟哥的系统上面与 /etc/passwd 有关的目录与文件数据如上表所示,该文件的读取流程为(假设读取者身份为 vbird 这个一般身份使用者):
1 / 的 inode: 透过挂载点的信息找到 /dev/hdc2 的 inode 号码为 2 的根目录 inode,且 inode 规范的权限让我们可以读取该 block 的内容(有 r 与 x) ; 2 / 的 block: 经过上个步骤取得 block 的号码,并找到该内容有 etc/ 目录的 inode 号码 (1912545); 3 etc/ 的 inode: 读取 1912545 号 inode 得知 vbird 具有 r 与 x 的权限,因此可以读取 etc/ 的 block 内容; 4 etc/ 的 block: 经过上个步骤取得 block 号码,并找到该内容有 passwd 文件的 inode 号码 (1914888); 5 passwd 的 inode: 读取 1914888 号 inode 得知 vbird 具有 r 的权限,因此可以读取 passwd 的 block 内容; 6 passwd 的 block: 最后将该 block 内容的数据读出来。
filesystem 大小与磁盘读取效能:
另外,关于文件系统的使用效率上,当你的一个文件系统规划的很大时,例如 100GB 这么大时, 由于硬盘上面的数据总是来来去去的,所以,整个文件系统上面的文件通常无法连续写在一起(block 号码不会连续的意思), 而是填入式的将数据填入没有被使用的 block 当中。如果文件写入的 block 真的分的很散, 此时就会有所谓的文件数据离散的问题发生了。
如前所述,虽然我们的 ext2 在 inode 处已经将该文件所记录的 block 号码都记上了, 所以数据可以一次性读取,但是如果文件真的太过离散,确实还是会发生读取效率低落的问题。 因为磁盘读取头还是得要在整个文件系统中来来去去的频繁读取! 果真如此,那么可以将整个 filesystme 内的数据全部复制出来,将该 filesystem 重新格式化, 再将数据给他复制回去即可解决这个问题。
此外,如果 filesystem 真的太大了,那么当一个文件分别记录在这个文件系统的最前面与最后面的 block 号码中, 此时会造成硬盘的机械手臂移动幅度过大,也会造成数据读取效能的低落。而且读取头在搜寻整个 filesystem 时, 也会花费比较多的时间去搜寻!因此, partition 的规划并不是越大越好, 而是真的要针对您的主机用途来进行规划才行!^_^
EXT2/EXT3 文件的存取与日志式文件系统的功能
上一小节谈到的仅是读取而已,那么如果是新建一个文件或目录时,我们的 Ext2 是如何处理的呢? 这个时候就得要 block bitmap 及 inode bitmap 的帮忙了!假设我们想要新增一个文件,此时文件系统的行为是:
1 先确定用户对于欲新增文件的目录是否具有 w 与 x 的权限,若有的话才能新增; 2 根据 inode bitmap 找到没有使用的 inode 号码,并将新文件的权限/属性写入; 3 根据 block bitmap 找到没有使用中的 block 号码,并将实际的数据写入 block 中,且升级 inode 的 block 指向数据; 4 将刚刚写入的 inode 与 block 数据同步升级 inode bitmap 与 block bitmap,并升级 superblock 的内容。
一般来说,我们将 inode table 与 data block 称为数据存放区域,至于其他例如 superblock、 block bitmap 与 inode bitmap 等区段就被称为 metadata (中介数据) 啰,因为 superblock, inode bitmap 及 block bitmap 的数据是经常变动的,每次新增、移除、编辑时都可能会影响到这三个部分的数据,因此才被称为中介数据的啦。
挂载点的意义 (mount point):
每个 filesystem 都有独立的 inode / block / superblock 等信息,这个文件系统要能够链接到目录树才能被我们使用。 将文件系统与目录树结合的动作我们称为『挂载』。 关于挂载的一些特性我们在第三章稍微提过, 重点是:挂载点一定是目录,该目录为进入该文件系统的入口。 因此并不是你有任何文件系统都能使用,必须要『挂载』到目录树的某个目录后,才能够使用该文件系统的。
举例来说,如果你是依据鸟哥的方法安装你的 CentOS 5.x 的话, 那么应该会有三个挂载点才是,分别是 /, /boot, /home 三个 (鸟哥的系统上对应的装置文件名为 /dev/hdc2, /dev/hdc1, /dev/hdc3)。 那如果观察这三个目录的 inode 号码时,我们可以发现如下的情况:
[root@www ~]# ls -lid / /boot /home 2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 / 2 drwxr-xr-x 4 root root 1024 Sep 4 18:06 /boot 2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home
看到了吧!由于 filesystem 最顶层的目录之 inode 一般为 2 号,因此可以发现 /, /boot, /home 为三个不同的 filesystem 啰! (因为每一行的文件属性并不相同,且三个目录的挂载点也均不相同之故。) 我们在第七章一开始的路径中曾经提到根目录下的 . 与 .. 是相同的东西, 因为权限是一模一样嘛!如果使用文件系统的观点来看,同一个 filesystem 的某个 inode 只会对应到一个文件内容而已(因为一个文件占用一个 inode 之故), 因此我们可以透过判断 inode 号码来确认不同文件名是否为相同的文件喔!所以可以这样看:
[root@www ~]# ls -ild / /. /.. 2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 / 2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /. 2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /..
上面的信息中由于挂载点均为 / ,因此三个文件 (/, /., /..) 均在同一个 filesystem 内,而这三个文件的 inode 号码均为 2 号,因此这三个档名都指向同一个 inode 号码,当然这三个文件的内容也就完全一模一样了! 也就是说,根目录的上一级 (/..) 就是他自己!这么说,看的懂了吗? ^_^
转自:http://vbird.dic.ksu.edu.tw/linux_basic/0230filesystem_1.php
发表评论
文章已被作者锁定,不允许评论。
-
Linux ubuntu配置SSH免密登陆
2017-05-05 16:15 4611、安装 Ubuntu14.04默认安装了ssh-client ... -
Linux ubuntu虚拟机连接上网总结
2017-05-05 13:37 5111.首先查看主机的ip信息 ipconfig /all ... -
Linux七个运行级别
2015-03-03 09:20 542运行级别就是操作系统当前正在运行的功能级别。级别是从0到6,具 ... -
第二十四章 CentOS 系统配置工具: setup
2014-10-30 20:05 671系统配置除了使用手动 ... -
第二十二章 启动过程的问题解决
2014-10-28 19:34 421很多时候,我们可能因 ... -
第二十二章 Boot Loader: Grub
2014-10-27 19:44 568在看完了前面的整个启 ... -
第二十二章 核心与核心模块
2014-10-23 19:28 343谈完了整个启动的流程 ... -
第二十二章 Linux 的启动流程分析
2014-10-22 20:08 389启动不是只要按一下电 ... -
第二十一章 管理的抉择:RPM 还是 Tarball
2014-10-20 19:24 499这一直是个有趣的问题 ... -
第二十一章 YUM 线上升级机制
2014-10-15 19:33 525我们在本章一开始的地方谈到过 yum 这玩意儿,这个 yum ... -
第二十一章 SRPM 的使用 : rpmbuild
2014-10-14 19:44 955谈完了 RPM 类型的软件之后,再来我们谈一谈包含了 Sour ... -
第二十一章 RPM 软件管理程序: rpm
2014-10-13 20:10 449RPM 的使用其实不难,只要使用 rpm 这个命令即可!鸟哥最 ... -
第二十章 函式库管理
2014-10-13 19:25 475在我们的 Linux 操作系统 ... -
第二十章 Tarball 的管理与建议
2014-10-10 19:54 491在我们知道了原始码的 ... -
第二十章 用 make 进行巨集编译
2014-10-09 20:04 529在本章一开始我们提到过 make 的功能是可以简化编译过程里面 ... -
第二十章 开放源码的软件安装与升级简介
2014-10-09 19:47 439如果鸟哥想要在我的 Lin ... -
第十九章 分析登录文件
2014-10-08 19:34 408登录文件的分析是很重要的!你可以自行以 vi 进入登录文 ... -
第十九章 登录文件的轮替(logrotate)
2014-10-08 19:28 511假设我们已经将登 ... -
第十九章 syslogd :记录登录文件的服务
2014-09-28 20:11 678刚刚提到说 Linux 的登录文件主要是由 syslogd 在 ... -
第十八章 系统开启的服务
2014-09-25 19:33 715好了,现在假设你已经知道了 daemons 的启动文件放置的目 ...
相关推荐
第8章 Linux磁盘与文件系统管理 第9章 文件的压缩与打包 第三部分 学习Shell和Shell脚本 第10章 vi文字处理器 第11章 认识Bash Shell 第12章 正则表达式 第13章 学习Shell脚本 第四...
Linux支持多种文件系统类型,如ext2、ext3、ext4等。本文将详细介绍Linux系统文件系统的内部工作原理。 #### 二、文件系统的组成 Linux文件系统由几个关键部分组成: 1. **Superblock(超级块)**:超级块包含...
第8章 模板与组件基础 / 385 8.1 模板 / 385 8.1.1 模板概述 / 385 8.1.2 ext.template的创建与编译 / 385 8.1.3 格式化输出数据:ext.string、ext.number、ext.date和ext.util.format / 389 8.1.4 超级模板:...
通过前一章的概念性介绍,我们对ExtJS有了初步的认识。现在,我们将开始实际的开发工作。 **认识ExtJS的开发包** ExtJS的开发包包含了多个子目录和文件,每个部分都有其特定的作用: 1. **Adapter**:这个目录...
第2章 开始ExtJS之旅 2.1 认识ExtJS的开发包 2.2 也从Helloworld开始 2.3 ExtJS中的基本概念 2.4 非常有用的开发工具 2.4.1 开发插件spket 2.4.2 FullSource 2.4.3 MicrosoftScriptDebugger 2.5 ExtJS对原有...
2. 文件系统类型:介绍ext2、ext3、ext4等常见的Linux文件系统,以及与Windows NTFS或FAT32的异同。 3. 文件与目录操作:教授如何使用命令行进行文件和目录的创建、删除、移动、复制等基本操作。 **第六章 管理...
实现一个简单的FAT或ext2文件系统可以让你深入理解其原理。 6. **设备驱动**:设备驱动程序是操作系统与硬件之间的桥梁,允许操作系统控制硬件。通过编写简单的字符设备或块设备驱动,你可以了解I/O操作的过程。 7...
此版本包含了从第8章到第12章的内容,涉及多个重要的主题和技术细节。 #### 二、核心章节知识点解析 ##### 1. 第8章:高级计算机架构 - **超标量处理与流水线技术**:这一章节深入探讨了现代处理器如何通过并行...
书中会介绍文件系统的原理,如FAT和ext2,并指导如何实现一个简单的文件系统。 10. **系统调用**:系统调用是用户程序与操作系统交互的接口,通过学习如何实现系统调用,读者可以了解操作系统的服务是如何被用户...
8. **第八章:内核模块** - 内核模块加载与卸载:讲解如何编写和管理内核模块,以及insmod、rmmod命令的使用。 - 模块编译与调试:介绍如何构建内核模块,并使用kgdb等工具进行内核调试。 9. **第九章:安全与...
4. **文件系统**:Linux支持多种文件系统,如ext2, ext3, ext4, FAT32等。在嵌入式系统中,选择合适的文件系统至关重要,因为它影响到系统的稳定性和效率。 5. **嵌入式Linux开发环境**:学习者将学习如何设置交叉...
"第8课磁盘和文件系统.pptx"关注磁盘管理和文件系统类型,如EXT4、FAT32、NTFS等。这包括挂载、格式化、检查和修复文件系统,以及理解LVM(逻辑卷管理)的概念。 "第11课认识和学习bash.pptx"将介绍Bash shell,它...
2. **引导和初始化**(第2章 引导和初始化.DOC):系统启动过程涉及BIOS/UEFI引导、加载内核到内存、初始化硬件、运行init进程等步骤。这一章会讲解如何配置GRUB等引导装载程序,以及Systemd等初始化系统的工作机制...
4. **文件系统**:阐述文件的组织、命名、存取控制,文件系统的层次结构,以及磁盘I/O管理,如FAT、NTFS、EXT系列文件系统的工作原理。 5. **输入/输出管理**:讲解I/O设备的分类、中断处理、DMA方式、缓冲技术,...
由于提供的文件信息中,并未包含《Linux内核设计的艺术:图解Linux操作系统架构设计与实现原理 第2版》的具体内容,因此无法从这部分内容生成相关的知识点。不过,我可以根据标题、描述以及提供的标签生成与Linux...
4. 文件系统:文件系统是数据存储的抽象层,书中会详细讲解Linux内核中的各种文件系统类型,如EXT2、EXT3、EXT4等,以及VFS(虚拟文件系统)接口,它是不同文件系统之间的统一接口。 5. 网络协议栈:Linux内核如何...
第一讲 Linux基础...........................................................................................................................2 一.什么是Linux?............................................
第八讲《娱乐软件安装与Linux分区详解》涵盖了非必需但实用的软件安装,以及如何规划和管理Linux硬盘分区,包括EXT4等文件系统的使用。 第九讲《补充讲解Linux重要内容》可能是对前面章节的回顾或补充,可能涉及到...