Linux文件系统——全方位掌握

文件系统的特性

磁盘分区完毕后需要进行格式化,操作系统才能使用这个分区。 不同操作系统能够使用的文件系统是不同的,例如:Windows98以前使用FAT/FAT16文件系统,Windows2000以后使用NTFS文件系统,Linux使用Ext2文件系统。在分区完成之后,要使得操作系统能够识别文件系统,就需要进行格式化,把分区格式化成某一个操作系统能够识别的文件系统。 一般来说,一个分区中装一个文件系统,但是现在技术发展了,一个分区可以装多个文件系统,也能将多个分区合并成一个文件系统。一个文件系统可以挂载到操作系统上。

文件系统的构成

一个文件由许多的属性和文件本身的数据组成,文件系统会把同一个文件的两种数据分别存放在inode和block中。此外,整个文件系统还有个super block,用于记录整个文件系统的整体信息。

  • inode:记录一个文件的所有属性,以及这个文件所对应的block的号码(一个文件对应一个inode)
  • block:存放文件的实际数据(若文件数据太大,则使用多个block存放)
  • super block:记录文件系统的整体信息,包括:inode、block的数量、文件系统的使用量、剩余量等。

Ext2文件系统读取数据的过程

要访问一个文件时,首先找到这个文件的inode,根据inode中的权限查看当前用户是否有权力读取这个文件;然后查看inode中block的位置,最后找到block,读出数据。这种文件系统就叫做索引式文件系统,所以Linux的ext2文件系统就是索引式文件系统。 PS:U盘(闪存)一般使用FAT文件系统,而FAT文件系统并没有inode,每个block中记录着本文件下一个block的位置。所以FAT文件系统无法通过inode一次性将这个文件所有的block号码读取出来,而只能一个个地读取block后才能知道下一个block的位置。所以如果同一个文件的block分散地太开,那么读取一个文件的时间就会很长,所以就有所谓的“碎片整理“,就是将同一个文件的block们尽量放到一起去。但Linux的ext2文件系统由于是索引式的,因此不太需要碎片整理。

关于Ext2文件系统的一些补充说明

  • 有些文件系统非常大,高达数百GB,那么格式化后会有大量的inode和block,为了方便管理,文件系统对所有的inode和block进行分组,每一组叫做block group,每一组都有独立的inode/block/super block。
  • data block数据块是用来存储文件实际数据的地方,只有1KB、2KB、3KB这三种。
  • 所有的inode和block在格式化的时候大小和数量就固定了,而且每一个block都有固定的编号,便于inode查找。
  • 文件系统支持的最大磁盘容量和单一文件容量是不一样的;

block大小

1KB

2KB

4KB

最大单一文件容量

16GB

256GB

2T

一个block只能存放一个文件的数据,如果文件太大,则使用多个block存放,如果一个block放不满,则剩下的就空着。

  • 每个block的大小要合理地选择, 如果太大,会造成最后一个block中会有大量剩余的空间;如果太小,那么inode中就要记录更多的block号码,每次找block要耗时,所以这样效率也不高。
  • 由于每个inode在格式化的时候大小就已经固定了,并且只有128bytes,并且每个文件仅能占用一个inode,因此,文件系统能够创建的文件数与inode的数量有关。除此之外:
  • 当一个文件很大时,它的block太多,每个block号码需要4byte,那么inode记录不下了怎么办?这时候将block号码存在一个block中,inode仅仅需要记录这个block的号码即可,这就是一次间接索引。Linux的ext2文件系统最多支持3级间接索引。
  • super block记录了整个文件系统的相关信息,是非常重要的,如果super block死掉了,那么系统会花费大量时间去挽救他。
  • 一般super block的大小为1024bytes
  • 每个block group中都含有一个super block,由于一个文件系统中只能有一个super block,所以这些group中的super block都是一样的,在第一个super block挂了的时候进行挽救用的。
  • File System Description文件系统描述说明:描述所有区段的起始和结束的block号码,所有区段包括:superblock、data block、inodebitmap、bitmap。
  • block bitmap块对照表:这个表记录了哪些block是空的,从而创建一个文件的时候能够快速分配空的block。
  • inode bitmap:这个与block bitmap类似,它记录哪些inode是空的。

inode与目录的关系

当我们在Linux的ext2下创建一个目录时,文件系统会给我们分配一个inode和一个block。 其中,inode记录该目录的相关权限与属性,并记录该block的号码。 而block中记录的是这个目录的名字、这个目录下所有的文件名、以及这些文件所占用的inode号码。

//通过增加-i参数,可以查看文件所占用的inode号码
//PS:最前面的数字就是inode号码
ls -li
total 24
 606624 drwx------+  8 chaibozhou  staff   272  4 28 08:31 Desktop
 606608 drwx------+ 15 chaibozhou  staff   510  4 26 20:14 Documents
 606610 drwx------+ 60 chaibozhou  staff  2040  4 29 20:37 Downloads
 606612 drwx------@ 52 chaibozhou  staff  1768  4 30 12:38 Library

inode与文件的关系

当我们创建一个文件时,文件系统会分配一个inode和相对于文件大小的一些block。例如一个block为4KB,我们创建了一个100KB的文件,那么需要分配一个inode和25个block;但Linux的ext2文件系统只有12个直接索引,所以还需要一个间接索引的block来存放该文件block的号码。

文件的读取过程

假设读取/etc/passwd这个文件:

  1. 根据挂载点信息找到/dev/hdc2根目录inode,也就是号码为2的inode。(根目录的inode号码是2)。然后根据inode中的权限信息判断当前用户是否有权限访问当前目录;然后找到跟目录对应的block号码。
  2. 根目录的block中存放着根目录下所有文件和文件夹的名字和inode号码;找到etc文件夹的inode号码。
  3. 读取该inode中的权限,判断当前用户是否有权限进入该目录;读取inode中的block号;到block 中查找passwd对应的inode号。
  4. 读取该inode中权限并判断,再读取inode中block号码,最后读取block中的数据即可。

文件系统大小与磁盘读写性能的关系

当一个文件很大,需要很多的block,而这些block又存放的比较离散,这时磁盘读写性能就很低了。 如果由于文件系统的空闲block较为离散,即使是存一些小文件,仍然需要磁头大量的移动,这时候就考虑将所有数据拷出来,然后格式化整个文件系统,再将数据拷回去。 如果文件系统太大,一个文件的block存放的位置很远,那么磁头要移动大量的位置来读取一个文件,此时效率就低了;也就是说,文件系统的大小不是越大越好的。

Ext2/3文件系统创建文件的过程

  • 文件的创建过程 a)首先判断该用户对于新文件所在的目录是否具有w和x权限,若有的话才能创建。 PS:因为目录的w权限代表能够创建、删除、重命名、移动文件;x权限代表能够cd到目录中去。 b)根据inode bitmap找到没有使用的inode号码,把文件的属性写进去; c)根据block bitmap找到没有使用的block,将文件的数据写进去,并更新inode,将block的号码写进去; d)更新inode bitmap和block bitmap,更新super block。(更新中间数据)
  • 数据的不一致性 inode和block被称为数据的存放区域,super block、block bitmap、inode bitmap称为中间数据(metadata)。如果在文件创建的过程中,因不明原因导致中断,数据已经写入inode和data block,但是更新中间数据的工作还没有做完,此时就会出现meta data和实际数据存放区产生了不一致。
  • 解决数据的不一致的方法——日志文件系统 a)预备:当要写入一个文件时,先在日志文件中记录某个文件准备要写入的信息; b)实际写入:开始写入文件的权限、属性和数据;然后更新中间meta data。 c)结束:完成数据记录与meta data更新之后,在日志记录块中完成对该文件的记录。 有了日志文件的记录,万一哪个文件在创建过程中发生异常,那么系统直接查看日志文件,看看哪一个文件有预备记录,但没有结束记录,然后仅对有问题的文件进行一致性检查即可,无需对整个文件系统进行检查,这样就能够实现快速恢复文件系统了。

异步处理

要处理一个文件,必须要把它全部放到内存中;那么当处理一个很大的文件的时候,如果频繁地要求操作系统将文件保存到外存,那么我们系统会出现卡顿,等待文件写入外存。为了避免写入外存时候的等待,我们就引入了异步处理方式。 一个文件在内存中,如果没有对他进行修改,那么它的状态是clean,系统不会把它写入外存;若我们对文件进行了修改,那么它的状态就变成了dirty,此时我们继续对文件进行操作,只不过系统会在后台不定时地将dirty状态的文件写入外存;也就是说,我们的操作和文件写入外存是并行的,去除了我们的等待时间。

  • 我们可以手动调用sync,强迫内存中状态为dirty的文件写回外存中去(就相当于我们使用ctrl+s,如果不自己按的话,系统会不定时地自动把数据写回外存)
  • 如果正常关机,系统会调用sync将内存中的数据写回外存
  • 如果非正常关机,系统来不及将数据写回外存,因此重启的时候系统会花很多时间进行磁盘检验,甚至可能导致文件系统的损坏(不会引起磁盘的损坏)

挂载点

每个文件系统都有独立的inode、block、super block等信息,每个文件系统都必须连接到系统的目录树上才能够被使用。我们将文件系统连接到目录树上的动作叫做挂载,就好像果子挂到树上去。 PS:挂载点一定得是目录,这个目录是进入这个文件系统的入口。 举例来说:假设有三个挂载点/、/boot、/home,他们对应的设备文件分别是:/dev/hdc2,/dev/hdc1,/dev/hdc3,那么查看这三个目录的inode号码可以发现:

2 drwxr-xr-x  23 root  wheel  3122  3 22 22:18 /
2 drwxr-xr-x  4 root  wheel  1422  3 24 22:18 /boot
2 drwxr-xr-x  6 root  wheel  122  3 25 22:18 /home

他们的inode号码都是2,说明他们都是文件系统的根目录,但是它们的其他数据都是不一样的,说明他们不是同一个文件,所以他们三个人来自三个不同的文件系统。 如果inode号码一致,并且其他属性都相同,则可以判断他们是同一个文件,就像/,/.,/..

文件系统的简单操作

  • 获取磁盘容量 df/du a)df:获取整个文件系统的磁盘使用量
df [option] 目录/文件

-a:列出所有的文件系统
-k:以KB为单位显示文件系统
-m:以MB为单位显示文件系统
-h:以人们较易阅读的单位显示文件系统
-H:以1M=1000K代替1M=1024K
-T:连同该分区的文件系统的类型一并显示,如ext3……
-i:用inode个数代替硬盘容量
df//不添加参数,显示所有的文件系统,以1KB为单位

Filesystem    512-blocks      Used Available Capacity  iused     ifree %iused  Mounted on
/dev/disk1     974389248 108237816 865639432    12% 13593725 108204929   11%   /
devfs                363       363         0   100%      628         0  100%   /dev
map -hosts             0         0         0   100%        0         0  100%   /net
map auto_home          0         0         0   100%        0         0  100%   /home
  • Filesystem:这一列是各个磁盘设备的名字,表示这个文件系统在哪个分区
  • 512-blocks:代表下面block是以512KB为单位的,代表block的个数
  • Used:使用掉的磁盘空间
  • Available:剩下的磁盘空间
  • Capacity:剩下磁盘空间的百分比
  • iused:使用了多少磁盘空间
  • ifree:
  • %iused :使用掉空间的百分比
  • Mounted on:挂载点的名字,也就是磁盘挂载的目录 PS:df主要是针对整个文件系统,因此读取的是super block中的数据,所以它显示的非常快。 PS:我们需要特别留意根目录的剩余量,因为所有的数据都是从根目录衍生而来的,因此当根目录的剩余量为0时,那你的系统问题就很大了。 b)du:获取某个目录的容量
du [option] 文件/目录

-a:列出所有的目录和文件的容量,要是不写这个参数默认只是列出文件的容量而已。
-n:以人们较为容易的格式显示容量
-s:列出目标目录的总容量,而不列出个别的目录容量
-S:列出目录总容量,但不包括子目录
-k:容量以KB显示
-m:容量以MB显示

//PS:若这个命令不带任何参数则列出当前目录的容量,单位是1KB。
  • 连接文件 ln Linux下的连接文件有两种,一种是类似于Windows下的快捷方式,称为符号连接;另一种称为硬连接。 a)硬连接(实际连接) 我们知道,目录的block中存放的是这个目录下的所有文件名和他们的inode号码,也就是说,文件名只与目录有关,而文件的内容是通过目录block中记录的inode号码来找到的。 硬连接就是新建一个文件名,连接到某inode号码。就是两个不同的文件名,但是指向同一个inode。 经过了硬连接的文件,如果删除其中一个文件,那么还有另外一个文件名指向这个文件,这个文件的block仍然是存在的。此外,不论通过哪个文件名修改文件,由于两个文件名都是指向同一个文件内容,所以两个文件的内容都会发生变化。 使用硬连接设置文件连接时,磁盘空间的inode和block的数目都不会发生变化。只是某个目录的block下多了一个连接文件名的inode号码而已。 硬连接不能跨文件系统。 硬连接只能连接两个文件,而不能连接两个目录。 b)符号连接(快捷方式) 再新建一个文件,只不过这个新文件会让数据的读取指向它连接的那个文件名。由于只是利用了文件的内容作为指向的操作,所以当原文件被删除之后,再打开连接文件酒会提示“文件无法打开“。 由于符号文件会创建一个新的独立的文件,所以它会用掉inode和block。 由于硬连接无法连接到目录,所以一般是符号连接比较常用。 符号文件的一个显著特性:
//表示chai是一个符号连接文件,它指向/home/shixv,而硬连接是不会有->这个符号的。
/chai->/home/shixv
//将目标文件指向原文件
ln [option] 原文件 目标文件

-s:不加参数就是硬连接,加了s就是符号连接
-f:force模式,如果目标文件存在,直接把它覆盖
//权限后面的数字就代表连接到这个inode上的连接文件个数
drwxr-xr-x    31 root  wheel   1122  3 21 22:18 .
drwxr-xr-x    31 root  wheel   1122  3 21 22:18 ..
  • 新建目录时连接数的变化 新建一个目录/chai实际上会产生三个目录,分别是:/chai,/chai/.,/chai/..。 /chai,/chai/.都表示该目录,/chai/..表示上层目录。 所以新建一个目录后,上层目录的连接数会+1,新建目录的连接数是2。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python数据科学

Python爬虫之模拟登录wechat

不知何时,微信已经成为我们不可缺少的一部分了,我们的社交圈、关注的新闻或是公众号、还有个人信息或是隐私都被绑定在了一起。既然它这么重要,如果我们可以利用爬虫模拟...

721
来自专栏零基础使用Django2.0.1打造在线教育网站

零基础使用Django2.0.1打造在线教育网站(十二):错误信息提示

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

61
来自专栏我的博客

TP入门第二天

1、配置说明 //’配置项’=>’配置值,配置在conf文件夹下config.php 2、Action文件定义规定 类名和文件名一样,首字母大写,后面必须要加A...

2735
来自专栏鬼谷君

django权限管理(Permission)

1614
来自专栏用户2442861的专栏

IntelliJ IDEA 缺少 javax 包 支持

在初次使用 IntelliJ IDEA 中,当你使用javax.servlet包下的类时(例:javax.servlet.http.HttpServlet),...

331
来自专栏逆向技术

逆向实战第一讲,寻找OllyDbg调试工具的Bug并修复

           逆向实战第一讲,寻找OllyDbg调试工具的Bug并修复 首先我们要知道这个OD的Bug是什么. 我们调试一个UNICODE的窗口,看下其...

1827
来自专栏还债之路

Nginx

直接去官网(www.nginx.org)查找源码包,直接复制链接地址下载,我们一般选择stable(稳定版),不选择最新版本

28620
来自专栏smy

prompt() 方法,弹框带输入框

prompt()  有alert的风格,却带着输入框,这是怎么实现的呢? 语法 prompt(text,defaultText) 参数 描述 t...

3555
来自专栏后端技术探索

nginx实现图片防盗链-技术精短文

前几天讲了《nginx下载防盗链》,今天继续说下图片防盗链. 他们两个使用的指令不同,前者使用secure link,并且需要程序配合,但是效果非常好;后者不需...

974
来自专栏木头编程 - moTzxx

ThinkPHP5 对html页面中的url传参操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

743

扫描关注云+社区