Linux详解 — 文件系统 (inode与软硬链接)

在了解文件系统之前,我们得先知道文件是由什么组成的!

  
文件 = 文件属性 (元信息) + 文件内容

  //文件还分为:内存文件 和 磁盘文件。

  //Linux中会将文件的属性和文件内容
分离存储,都存储在磁盘中。

  
#接下来我们只讨论磁盘文件

inode

  inode是一个文件的属性集合。在linux中,几乎每一个文件都有inode,因此inode数量是很多的,而为了区分inode,我们可以使用inode编号。     //inode也是存储在磁盘上的

	ls -i	#查看文件的inode信息
	ll -i	

在这里插入图片描述
最前面的一串数字就是对应文件的inode编号了。

文件系统

磁盘

问题:什么是磁盘?
  磁盘是在冯诺依曼体系结构中几乎唯一的机械设备。机械设备意味着什么?机械设备意味着它的效率低。那为什么还会使用磁盘?磁盘相比我们所熟知的内存有着一个极大的优势,那就是永久性,它能够永久性的存储数据。而内存是一种掉电易失性存储介质,也就是没电了存储的内容就没了。因此目前所有的普通文件都是存储在磁盘上的。

问题:那么既然所有的普通文件都是存储在磁盘上的,那么就必须要对这些文件进行管理,也就是如何对磁盘进行管理?
  在了解磁盘怎么管理之前,我们得先知道磁盘的结构!以及它是如何进行读写的!

图1 磁盘纵向图

图2 磁盘截面图

介绍一下磁盘中的几个重要部分:
盘片(Platter):磁盘一般是由多个盘片组成的,而每个盘片都有上下2个盘面。
磁头(Head) :每个盘面都有一个对应的磁头,也就是一个盘片都有上下2个磁头。磁头的作用是对磁盘进行写入和读取。
磁道(Track) :当磁盘旋转时,磁头若保持在一个位置上,则每个磁头都会在盘片的表面画出一个圆形轨迹,这个圆形轨迹就称为磁道。
扇区(Sector) :每个磁道都被切分为很多扇形区域,这个扇形区域被称为扇区,每个扇区的大小为512字节。
柱面(Cylinder):不同盘片的相同编号的磁道构成的圆柱面就被称之为柱面。

问题:怎么对磁盘进行管理?
  我们可以将磁盘这个圆形存储介质 看作线性存储介质。(就像磁带一样,卷起来就是圆形的,但是它实际上是线性的结构)
  看作线性存储介质后,就方便我们对磁盘进行管理了。因为磁盘的容量很大,我们可以对磁盘进行分区管理。在分区之后,对每个区域的管理都是相同的,这将很大程度的减少工作量。
  在分区之后,我们可以每个区域进行格式化。

问题:格式化是什么?
  格式化是对磁盘中的分区进行初始化的一种操作。(千万别在自己的电脑上搞哦!)。这种初始化就是以某种格式/标准对区域进行划分。

  在格式化之后,更方便数据去存储和进行管理。而格式化的标准一般由文件系统决定,Linux中采用Ext2/3/4文件系统。

Ext2文件系统分区结构

下面是Ext2的文件系统的一个分区的结构:
在这里插入图片描述
每个分区里面还可以被分成很多组,我们这里主要细谈每个组里面的结构。
Super Block:用来存放文件系统本身的结构信息的。它里面记录的信息主要有:block/inode的总量、未使用量、剩余量 (也就是它知道当前使用了多少inode和block);一个block和inode的大小;最近一次的挂载时间;最近一次的写入数据的时间;最近一次检验磁盘的时间等等。。。当Super Block的信息被破坏,那么整个文件系统的结构就被破坏了。
  //由于super block很重要,因此每个block group都会存一分进行备份。(这也算是冗余的信息)
GDT:Group Descriptor Table,块组描述符。每个块组描述符中都存储着一个块组的描述信息,例如:在这个块组中"从哪里开始是inode table"、“从哪里开始是Data Blocks”、"空闲的inode和数据块还有多少个"等等… 它和Super Block很像,块组描述符在块组的开头也有一份拷贝。
Block Bitmap:块位图,用来描述整个块组中,哪些块是被被使用的,哪些块是空闲的。块位图中的每个bit位,都代表块组中的一个块,bit位的位置决定了块的位置,bit位的值决定了该块是否被使用。1表示被使用,0表示块空闲可用。
Inode Bitmap:和块位图类似,其中的每个bit表示一个inode是否空闲可用。
    注意:在分区之后,inode的个数就是确定的!
Inode Table:用来存放文件的属性信息的,如文件的大小、权限、类型、创建时间、所属组、所属用户等。我们使用ls -l看到的信息,都是从这里获取的。每个文件对应一个inode,因此每个inode中都存储一个inode编号用来区分。
  除此之外,inode中还存储着blocks数组,blocks数组中可以存储data blocks中的块的编号。我们可以通过blocks数组去建立与数据块的映射,也就是我们可以通过inode去找到数据块。
Data Blocks
  对于普通文件:文件的数据都存储在其中。
  对于目录文件:会存放目录下的所有文件名到其中。//文件名保存在它所在目录的数据块中!

文件操作的本质

Ⅰ、文件的创建
  ① 创建一个新文件就要先给这个文件分配inode和数据块(没写入数据就不需要数据块)。首先扫描Inode Bitmap去查找空闲的Inode,然后将某个空闲位置的inode值修改为1。
  ② 随后,在inode table中找到对应位置的inode,然后填充inode的信息(文件大小、权限、所属组…)。
  ③ 最后将该文件的inode编号与文件名这对映射关系填入到所在目录文件的数据块中。
//添加文件名到目录 (我下面会讲目录的概念)

Ⅱ、文件的写入
  ① 首先扫描Block Bitmap,找到空闲的块。然后将其值改为1。
  ② 随后将该块对应的编号填入对应的inode结构体中的blocks数组中。最后向块中写入内容。

Ⅲ、文件的删除
  直接将该文件对应的Inode Bitmap和Block Bitmap中的值改为0。

Ⅳ、文件的拷贝
  拷贝文件的本质就是新建一个新的文件,然后再填充源文件的数据。

Ⅴ、文件的剪切
  在同一分区下,剪切速度很快!因为本质就是将文件名和inode号换了个目录中存储而已。
  在不同分区下,剪切速度较慢,因为本质就是拷贝新文件,再删除源文件。

目录与文件

  目录也是文件,因此它也是有自己的inode与data blocks的。
  目录的inode与普通文件相同(存储的是目录的属性信息),但是它的数据块中所存储的东西就不太一样了。
  目录的数据块存储的是当前目录下的文件名与inode编号的映射关系
实际上,我们使用ls -i 命令的时候,就是查看目录的数据块中的内容!
在这里插入图片描述

软硬链接

软链接

  软链接类似Windows中的快捷方式。 //软链接创建后,如果移动到了其他路径下,链接会失效

	ln -s [目标文件] [软链接产生的文件名称]		#创建软链接

①:在当前目录下创建软链接
在这里插入图片描述

②:在其它目录下创建软链接
在这里插入图片描述
//我们还可以给软链接创建软链接,无限套娃hhh

硬链接

	ln [目标文件] [硬链接所产生的名字]		#创建硬链接

在这里插入图片描述
  我们在使用 ls -l 后,在文件的权限属性后面的数字,就代表了某个文件的硬链接数
  硬链接的本质新建了一个文件名与已有的inode的映射关系并写入当前目录。所以当你删除原本的文件后,还可以通过硬链接产生的新文件名去进行访问源文件。  //硬链接类似取别名

硬链接与 . 和 . .

   . 实际上就是对当前目录所起的别名(也就是硬链接),因此每个目录创建时都至少有2个硬链接数。
   . . 实际上就是对上级路径的目录所起的别名(也就是硬链接)。所以当前目录下有几个目录,那么就会多几个硬链接 ". ."

目录与硬链接

	ls -d	#只显示当前目录本身

在这里插入图片描述
我们可以发现对于一个刚创建的目录,它的初始状态就是有2个硬链接数。
那么这两个硬链接都是什么呢?
  一个是目录本身,另一个是 “.” 。 "."就是表示当前目录。
  当我们在目录下又创建很多目录时,当前目录的硬链接数还会继续增加。因此当前目录下有几个目录,那么就会多几个硬链接 “. .”

目录的硬链接数 = 2 + 该目录中的目录数量(只考虑邻层的目录,相隔层的目录无法影响)

//相隔层的目录无法影响的原因在于:". ."是上层目录的硬链接,因此它无法表示上上层。

inode与硬链接

   inode结构体中存在着一个成员变量i_nlink, 它可以记录对应文件的硬链接数。

struct inode{
    const usigned int i_nlink;    //磁盘引用计数器,当每产生一个硬链接时,该成员就会++    count
    atomic_t i_count;    //内存引用计数器
}

这里补充一个细节,很关键的细节!帮助理解硬链接与文件的删除
 对于一个文件而言,当你给它创建硬链接后,再删除源文件,此时你仍然可以去通过硬链接访问文件的内容。这是因为在inode中,有一个变量叫i_nlink,每次删除文件时,系统会去检测i_nlink的值,如果值减为0的话,才会去删除这个文件,否则不会删除。

软链接与硬链接的区别

在这里插入图片描述

  1. 软链接创建的是一个独立的文件,它有自己的inode
    硬链接没有独立的inode,它与源文件共享inode
  2. 软链接移动到其他路径下后,链接会失效;
    硬链接移动到其他路径下后,仍可以正常工作。
  3. 软链接可以跨文件系统进行连接
    硬链接不可以跨文件系统
  4. 软链接可以对一个不存在的文件名(filename)进行链接
    硬链接不可以
  5. 软链接可以对目录进行链接
    硬链接不可以直接对目录进行链接,目录的硬链接数是取决于目录下的目录个数的

问题3:为什么硬链接不可以跨文件系统?
 因为硬链接的本质是在某个目录下新建一条文件名与inode号的映射关系。不同的分区可能采用不同的文件系统,跨文件系统时的inode号并不通用!所以无法建立正确的映射关系,因此不能跨文件系统。

问题5:为什么硬链接不可以直接链接目录?
 因为目录的硬链接数是通过 . 和 . . 计算出来的。使用硬链接链接目录会导致 . 和 … 的意义混乱。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>