第七章 Linux文件系统(一)

1.文件系统特性

磁盘分区后还需要进行格式化后操作系统才能使用这个文件系统,为什么要格式化?

因为每个操作系统所设定的文件属性、权限不一样,因此需要将分区槽格式化,以成为操作系统能够利用的"文件系统格式"。

传统技术中,一个分区槽只能被格式化成为一个文件系统,所以我们可以说一个filesystem是一个partition。但由于新技术的发展,例如LVM与软件磁盘阵列(software raid),可以将一个分区槽格式化为多个文件系统,也能将多个分区槽格式化为一个文件系统。所以说,通常我们称"一个可被挂载的数据为一个文件系统而不是一个分区槽"。

文件系统通常将操作系统的文件权限(rwx)和文件属性(拥有者、群组、时间参数等)分别存放在不同的区块,权限与属性放到inode中,至于实际数据放到data block中。另外,还有一个超级区块:

  • superblock:记录整个文件系统的整体信息,包括inode与block的总量、使用量、剩余量等。

  • inode:记录文件的权限与相关属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码。

  • block:实际记录文件的内容,若文件太大时,会占用多个block。

由于每个inode与block都有编号,而每个文件都会占用一个inode,inode内会放置有block号码,也就能够读文件的实际数据。如下图所示:

inode/block资料存取示意图

假设一个文件的属性与权限数据放到了inode4号,而这个inode记录了文件数据的实际放置点是2、7、13、15,操作系统就能够据此来排列磁盘的阅读顺序。这种数据存取方法我们称为"索引式文件系统"。

还有惯用的是"随身碟",文件系统一般为FAT格式:

FAT文件系统资料存取示意图

这个文件系统没有办法一口气知道4个block的号码,它得将每个block读出,才知道下一个block在哪。如果同一个文件数据写入的block分散的厉害,磁盘头就需要转好几圈才能完整读取到文件的内容。

Linux的EXT2文件系统(inode)

文件系统一开始就将inode与block规划好了,除非重新格式化,否则inode与block固定后就不再变动。但如果文件系统有几百GB时,所有的inode与block放置在一起时很不明智的。

所以,EXT2文件系统在格式化的时候基本上时区分为多个区块群组,每个群组都有自己独立的inode/block/superblock系统。如下图所示:

ext2文件系统示意图
  • data block

用来放置文件内容数据,在EXT2文件系统中所支持的block大小有1K、2K、4K三种。

block大小产生的EXT2文件系统限制

除了大小限制还有什么限制?基本限制如下:

block的大小与数量在格式化完就不能在改变了

每个block内最多只能存放一个文件的数据

如果文件大于block的大小,则一个文件会占用多个block数量

如果文件小于block的大小,则该block的剩余容量就不能在被使用

  • inode table

inode记录文件的属性以及该文件实际数据放置在哪个block内。inode记录的文件数据至少有以下这些:

该文件的存取模式(read/write/excute)

该文件的拥有者与群组(owner/group)

该文件的容量

该文件建立或状态改变的事件(ctime)

最近一次的读取时间(atime)

最近修改的时间(mtime)

定义文件特性的旗标(flag),如SetUID...

该文件真正内容的指向(pointer)

inode的特点:

数量与大小也是在格式化时就已经固定了

每个inode大小均固定为128bytes(新的ext4)

每个文件都只占用一个inode

文件系统能建立都文件数量与inode的数量有关

系统读取文件时需要先找到inode,并分析inode记录的权限与用户是否符合,符合才能开始实际读取block的内容

我们来分析以下EXT2的inode/block与文件大小的关系。inode要记录的数据非常多,但大小只有128bytes,而inode记录一个block号码要花掉4byte,假设我有一个文件有400MB且每个block为4K时,那么至少要10w个block号码记录。inode哪有这么多可记录的信息?为此我们系统将inode记录与block号码的区域定义为12个直接,1个间接,1个双间接,1个三间接记录区,结构如下所示:

inode结构示意图

假设我们以1K block大小来说明:

12个直接指向:12*1K=12K
直接指向就是直接存放的block的数据,总共可记录12笔

间接:256*1K=256K
拿到额外一个block专门存取block号码,每个block号码记录花去4bytes,1K的大小能记录256个block。

双间接:2562561K=256^2K
第一层block会指定256个第二层,每个第二层可以指定256个block号码

三间接:256256256*1K=256^3K
第一层block会指定256个第二层,每个第二层指定256个第三层,每个第三层指定256个block号码

  • superblock

记录整个文件系统相关信息的地方,主要记录的信息有:

block与inode的总量

未使用与已使用的inode/block数量

block与inode的大小(block为1,2,4K;inode为128或256bytes)

filesystem的挂载时间、最近一次写入数据的时间、最近一次检验磁盘的时间等文件系统的相关信息

一个valid bit数值,若此文件系统已被挂载,则valid bit为0,没被挂载就为1。

一般来说,supderblock大小为1024bytes

我们说一个文件系统应该只有一个superblock,但是后续的block group可能还会有superblock,这是为了防止superblock死掉,进行的备份。

  • filesystem Description(文件系统描述说明)

这个区段描述每个block group的开始与结束的block号码,以及说明每个区段(superblock、bitmap、inodemap、data block)分别介于哪一个block号码之间。

  • block bitmap(区块对照表)
    在新增文件的时候总会用到block,那怎么知道哪个block是空的呢,这就需要block bitmap的辅助了,能够快速找到可使用的空间。

  • inode bitmap(inode对照表)
    这个和block bitmap相似的功能。记录inode使用与未使用的号码。

2.文件系统与目录树

2.1 目录

在Linux下的文件系统建立一个目录时,文件系统会给该目录分配一个inode与至少一个block。其中,inode记录该目录的相关权限与属性,并可以记录分配到了哪块block号码;block记录了这个目录下的文件名与文件名占用的inode号码数据。

可以使用命令"ls -il"选项查看某个目录下的文件所占用的inode号码

[jumpserver@xxx tomcat-analysis]$ ls -il
total 108
   239384 drwxr-xr-x. 2 jumpserver root  4096 Apr  2 14:12 bin
268848599 drwxr-xr-x. 3 jumpserver root  4096 Apr  3 10:41 conf
538441458 drwxr-xr-x. 2 jumpserver root  4096 Apr  2 14:12 lib
268848635 -rw-r--r--. 1 jumpserver root 56846 Sep 14  2016 LICENSE
537335010 drwxr-xr-x. 3 jumpserver root  4096 Apr 10 15:08 logs
268848636 -rw-r--r--. 1 jumpserver root  1239 Sep 14  2016 NOTICE
268848637 -rw-r--r--. 1 jumpserver root  8965 Sep 14  2016 RELEASE-NOTES
268848638 -rw-r--r--. 1 jumpserver root 16195 Sep 14  2016 RUNNING.txt
807646942 drwxr-xr-x. 2 jumpserver root    29 Apr  2 14:12 temp
   239395 drwxr-xr-x. 9 jumpserver root  4096 Apr  4 10:26 webapps
268848634 drwxr-xr-x. 3 jumpserver root    21 Apr  3 10:31 work

2.2 文件

在Linux下的EXT2下建立一个一般文件时,EXT2会分配一个inode和相对于该文件大小的block数量给该文件。

例如:假设block为4KB,我们要建立一个100KB的文件,那么Linux将分配一个inode和25个block来存储该文件。注意:inode只有12个直接指向,因此还要多一个block来作为区块号码的记录。

2.3 目录树读取

inode本身并不记录文件名,文件名的记录在目录的block中。所以我们在第五章文件与目录的权限说明中,才会提到"新增、删除、更名文件名与目录的w权限有关"。

目录树是由根目录开始读起的,系统通过挂载的信息可以找到挂载点的inode号码,此时就能够得到根目录的inode内容,根据该inode读取根目录的block内的文件名数据,再一层一层向下读到正确的档名。例如:我们想读取"/etc/passwd"这个文件,系统由以下步骤:

[jumpserver@xxx tomcat-analysis]$ ll -di / /etc/ /etc/passwd
     128 dr-xr-xr-x. 18 root root 4096 Aug 10  2018 /
16777345 drwxr-xr-x. 91 root root 8192 Mar 30 03:45 /etc/
18615857 -rw-r--r--.  1 root root 1613 Mar 15 15:53 /etc/passwd
[jumpserver@host-172-16-13-249 tomcat-analysis]$
    1. / 的inode:通过挂载点的信息找到inode号码为128的根目录inode,且inode规范的权限让我们可以读取该block的内容(由r、x)
    1. / 的block:经过上面步骤取得block号码,并找到该内容有/etc目录的inode号码(16777345)
    1. etc/ 的inode:读取16777345号inode得知root具有r、x的权限,因此可以读取etc/的block
  • 4.etc/ 的block:经过上个步骤取得block号码,并找到该内容有passwd文件的inode号码(18615857)

  • 5.passwd的inode:读取18615857号inode得知root有r的权限,因此可以读取passwd的block内容

  • 6.passwd的block:最后将该block内容的数据读出来

2.4 磁盘读取功能

当你的文件系统很大时,例如100GB,由于磁盘上面的数据总是来来去去,所以正规文件系统的文件通常无法连续卸载一起(block号码不会连续),而是填入式的将数据填入未被使用的block中。这样就会有所谓的"文件数据离散"问题。

它导致的结果就是读取效率很低,因为磁盘读取头要在正规文件系统中反反复复的频繁读取。不过,你可以将整个文件系统的数据全部复制出来,将该系统重新格式化,再将数据复制回去可以解决这个问题。

EXT2/EXT3/EXT4 文件的存取与日志式文件系统的功能

假设我们想要新增一个文件,它的行为是怎样的呢?

  • 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的同步更新步骤没有做完,此时就会发生metadata的内容与实际数据存放区产生不一致。

早期的EXT2中,如果发生这个问题,系统在重启的时候,就会把superblock记录的valid bit(是否有挂载)与filesystem state(是否clean)等状态来判断是否需要进行数据一致性检查。这样的检查真的很费时,metadata区域与实际数据存放区进行比对,要搜索整个filesystem!

日志式文件系统

为了避免上面的问题发生,后来想到一种方式:如果在我们的filesystem中规划出一个区块,该区块专门记录写入活修订文件的步骤:

  • 1.预备:当系统要写入一个文件时,会先在日志记录区块中记录某个文件准备要写入的信息。

  • 2.实际写入:开始写入文件的权限与数据;开始更新metadata的数据。

  • 3.结束:完成数据与metadata的更新后,在日志记录区块中完成该文件的记录。

EXT3/EXT4是EXT2的升级版本,并可向下兼容。我们可以用"dumpe2fs"查看输出的讯息,可以发现superblock里面含有journal处理日志区块的记录。

3.Linux文件系统的运作

3.1 大文件的运作

所有的数据要加载到内存后CPU才能对该数据进行处理。如果你编辑一个大文件,编辑过程中又频繁的要系统来写入到磁盘中,由于磁盘写入的速度比内存慢很多,因此会常常等待磁盘的写入/读取效率!

为了解决整个问题,Linux使用的方式是异步处理(asynchronously):

当系统加载一个文件到内存后,如果该文件没有被动过,则在内存区段的文件数据会被设定为干净(clean)的。但如果内存中但文件数据被改过,此时该内存的数据会被设定为脏的(Dirty),此时所有的动作都还在内存中执行,并没有写入磁盘中。系统会不定时的将内存中设定为"Dirty"的数据写回磁盘。其实也就是缓冲的功能。

3.2 挂载点的意义

每个filesystem都有独立的inode/block/superblock等信息,这个文件系统要能够链接到目录树才能被我们使用。将文件系统与目录树结合的动作我们成为"挂载"。

注意:挂载点一定是目录,该目录为进入该文件系统的入口。

举例来说,CentOS7.x应该有3个挂载点,分别是"/","/boot","/home"。如果我们观察这3个目录的inode号码,可以发现:

由于XFS文件系统最顶层的目录inode一般为128,因此可以发现"/","/boot","/home"为3个不同的fielsystem。(因为每行的文件属性不相同,并且3个目录挂载点也不同)。

4.XFS文件系统

CentOS7开始,预设的文件系统由EXT4变成了XFS文件系统。这是由于哪些原因?

4.1 EXT家族目前的问题:支持度最广,但格式化很慢!

EXT文件系统对于文件格式化处理,采用但是预先规划出所有的inode/block/metadata等数据。早期磁盘容量不大这个还没什么问题,但现在磁盘容量越来越大。光是系统要预先分配inode与block就要消耗很长很长时间了。

4.2 XFS文件系统配置

XFS在文件系统资料分布上,主要有3个部分:数据区(data section)、文件系统活动登录区(log section)、实时运作区(realtime section)。

  • 1.数据区(data section)

像EXT家族一样,包括inode/datablock/superblock等,都放在这个区块。这个数据去与EXT的block group类似,分为多个储存区群组(allocation groups)来分别放置文件系统所需要的数据。

每个存储区又包含:整个文件系统的superblock;剩余空间的管理机制;inode的分配与追踪。此外,inode与block都是系统需要用到时,才动态配置产生,所以格式化很快!

  • 2.文件系统活动登录区(log section)

主要来记录文件系统的变化。如果文件系统因为某些故障损毁时,系统会拿这个登录区来进行检验,查看系统挂掉前,文件系统正在做哪些动作。

  • 3.实时运作区(realtime section)

有文件要被建立时,XFS会在这个区段里找一个或多个extent区块,将文件放置在这个区块内,等分配完成后,再写入data section的inode与block。extent区块的大小要在格式化的时候就先指定,最小4K最大1GB。

4.3 XFS文件系统的描述数据观察

有么有像EXT家族的dumpe2fs一样可以观察superblock内容的相关指令?我们可以用xfs_info。

xfs指令
  • 第1行里面的isize指inode的容量,每个有256bytes大小。agcount是储存区群组的个数,一共是4个。agsize是指每个储存区具有65536个block。配合第4行的block设定为4K,因此整个文件系统的容量是4655364K这么大。

  • 第2行sectsz指逻辑扇区(sector)的容量设定为512bytes。

  • 第4行bsize指block的容量,每个block为4K,共有262144个block在这个文件系统内。

  • 第5行第sunit与swidth与磁盘阵列第stripe相关性较高。下面说明。

  • 第7行internal指这个登录区的位置在文件系统内,而不是外部设备的意思。占用4K*2560个block,总共月10MB的容量。

  • 第9行的realtime区域,里面的extent容量为4K。目前没有使用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容