linux文件存储之inode学习

309 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情

inode 是 Linux 操作系统中存储文件时用到的一种数据结构,,它包含了与文件系统中各个文件相关的一些重要信息。先通过几个概念来引出inode的基本知识:

一、学习几个概念

1.扇区(Sector)

硬盘的最小存储单元叫做扇区(Sector),每个扇区大小为512字节(相当于0.5KB)。

Linux查看扇区大小:fdisk -l /dev/sda

$ sudo fdisk -l /dev/sda
Disk /dev/sda:238.47 GiB,256060514304 字节,500118192 个扇区
Disk model: LITEON CV5-8Q256
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:gpt
磁盘标识符:13A954F1-DF3E-4C48-8E67-51F2D0210154

设备           起点      末尾      扇区  大小 类型
/dev/sda1      2048   2099199   2097152    1G EFI 系统
/dev/sda2   2099200  18876415  16777216    8G Linux swap
/dev/sda3  18876416 228591615 209715200  100G Linux 文件系统

2.块(Block)

Windows文件系统的最小逻辑存储单元叫做簇(Cluster),而Unix/Linux系统则将最小逻辑存储单位叫做块(Block),每个块或簇可以包括2、4、8、16、32、64(2的n次方)个相邻的扇区,Linux系统中块的大小一般为8个相邻的扇区,也就是4KB(这个值可以在格式化分区的时候修改)。系统读取数据时是一个块一个块的读取,而不是一个扇区一个扇区的读取。

3.数据区和Inode区

Linux在格式化硬盘时,linux系统在格式化硬盘时,会将硬盘分区分成2个区域。一个是数据区(data area),以块为最小存储单元,用于存放文件数据;另一个是inode区(inode table),以inode节点为最小存储单元,Inode table也叫inode索引表,用于存放文件存储大小、权限、时间戳、链接数等关键的元信息(注意:文件名不属于inode信息)。

二、文件读取方式

先看一张图:

linux文件存储之inode学习 图片.png

1.目录数

首先,Linux文件系统是以目录树的形式来存储和读取的,根节点是”/”,因此所有的文件都必须处于目录内,目录中存放的数据实际上是一个目录表。而目录表中包含2个元素,一个是inode号码,一个是目录内文件名。

2.inode表

Inode表中存储着所有文件的元信息,其中包含inode号码,并有一个指针指向文件的数据存储位置,这个数据存储位置就在数据区中。

3.数据区

数据区中存放着文件的真实数据,因为数据区最小存储单元是块,每个块的大小固定(8个扇区),如Linux系统块的大小一般为4KB,因此一个块只能存放一个文件的内容,无论这个文件有多小,也就是说一个文件占用的空间必然是1个或多个块的大小,也就是4K的倍数。

先创建几个目录和文件进行演示:

hollowman@hollowman-f117:~$ mkdir inodes
hollowman@hollowman-f117:~$ cd inodes
hollowman@hollowman-f117:~/inodes$ ls -ali   
总用量 8
2630100 drwxrwxr-x  2 hollowman hollowman 4096  4月 24 08:29 .
2621442 drwxr-x--- 24 hollowman hollowman 4096  4月 24 08:29 ..
hollowman@hollowman-f117:~/inodes$ touch file1
hollowman@hollowman-f117:~/inodes$ ls -ali
总用量 8
2630100 drwxrwxr-x  2 hollowman hollowman 4096  4月 24 08:30 .
2621442 drwxr-x--- 24 hollowman hollowman 4096  4月 24 08:29 ..
2630487 -rw-rw-r--  1 hollowman hollowman    0  4月 24 08:30 file1
hollowman@hollowman-f117:~/inodes$ echo aaaaa > file1 
hollowman@hollowman-f117:~/inodes$ ls -ali
总用量 12
2630100 drwxrwxr-x  2 hollowman hollowman 4096  4月 24 08:30 .
2621442 drwxr-x--- 24 hollowman hollowman 4096  4月 24 08:29 ..
2630487 -rw-rw-r--  1 hollowman hollowman    6  4月 24 08:30 file1

三、查看文件的inode信息

可通过命令:stat filename来查看文件的inode信息

hollowman@hollowman-f117:~/inodes$ stat file1 
  文件:file1
  大小:6             块:8              IO 块:4096   普通文件
设备:803h/2051d	    Inode:2630487     硬链接:1
权限:(0664/-rw-rw-r--)  Uid:( 1000/hollowman)   Gid:( 1000/hollowman)
最近访问:2022-04-24 08:30:10.001781375 +0800
最近更改:2022-04-24 08:30:47.947246493 +0800
最近改动:2022-04-24 08:30:47.947246493 +0800
创建时间:2022-04-24 08:30:10.001781375 +0800

打印出的信息中,除了文件名不属于inode,其他都是inode中包含的元信息。下面为各个元信息的说明:

文件大小(size): 6字节,这是文件的实际大小
分配的区块数(Blocks): 8,也就是分配1个块=连续的8个扇区,这是文件实际占用空间大小:8*512=4KB
IO 块(IO Block): 4096,表示该文件系统的最小寻址单元,对应Blocks也就是4096字节(4KB),恒定数字
文件类型: 普通文件regular file
所在设备(device): 803h/2051d
Inode号: 2630487
硬链接数(Links): 1
权限(Access): 0664/-rw-rw-r--,文件的读取权限,不解释
Uid: 1000/hollowman,文件的属主为hollowman用户
Gid: 1000/hollowman,文件的属组为hollowman用户组
最近访问时间(access time): 2022-04-24 08:30:10.001781375 +0800
最近更改时间(modify time): 2022-04-24 08:30:47.947246493 +0800,指的文件内容变动时间
最近改动时间(change time): 2022-04-24 08:30:47.947246493 +0800,指的inode变动时间
创建时间(birth): 2022-04-24 08:30:10.001781375 +0800

在Linux系统中仅仅通过inode号码来标识不同文件,而文件名只是文件的一个别称,在Linux系统中还可以通过硬链接的方式用不同文件名指向同一个inode号码,这样两个文件名的数据完全相同。

四、inode的大小

既然在格式化硬盘的时候,系统会将硬盘分成两个区域:数据区(data area)和inode区(inode table),那inode也是需要占用硬盘空间的,数据区和inode区中任意一个区存储满了,硬盘也就无法再存储文件了,哪怕另一个区中还有空间。

每个inode的大小,一般是128字节或256字节。而inode的总数则在格式化时就会给定,一般每1KB或每2KB或4KB设置一个inode。例如一块硬盘分区时,每分配4KB给data area,就分配一个inode(假设每个inode大小为128b),那么inode table与data area的比例就是128:4096=1:32。

可以用df -i命令查看硬盘分区的inode总数和已经使用的数量

hollowman@hollowman-f117:~/inodes$ df -i /dev/vda

五、硬链接

用户找到和打开文件的步骤:找到这个文件名对应的inode号码--->通过inode号码获取inode信息--->据inode信息找到文件数据所在的block并读取数据。

虽然文件读取都是通过inode号码,但我们日常却是对文件名来操作的,对文件名的操作则用到了硬链接。

硬链接是文件名直接指向inode号码,一个inode号码可以对应多个硬链接,创建文件的过程其实也是一个硬链接的过程,刚创建的文件硬链接数量是1。

创建硬链接用ln命令

hollowman@hollowman-f117:~/inodes$ touch file2
hollowman@hollowman-f117:~/inodes$ ls -l file2          #可以看出创建文件后,有1个硬链接
-rw-rw-r-- 1 hollowman hollowman 0  4月 24 13:13 file2
hollowman@hollowman-f117:~/inodes$ ln file2 file3       #创建硬链接后,硬链接数+1,且file2和file3实际指向的是同一个文件
hollowman@hollowman-f117:~/inodes$ ls -l file2
-rw-rw-r-- 2 hollowman hollowman 0  4月 24 13:13 file2
hollowman@hollowman-f117:~/inodes$ echo abcd > file3    #修改file3文件,也等于是修改file2文件
hollowman@hollowman-f117:~/inodes$ cat file2
abcd

六、软链接

除了硬链接,还有一个软链接,软链接也是符号链接的意思,其文件名直接指向的是软链接文件名。软链接创建了一个新的文件,有自己的inode号码。 创建软链接用ln -s命令

hollowman@hollowman-f117:~/inodes$ ln -s file2 file4     #创建软链接file4
hollowman@hollowman-f117:~/inodes$ ls -il                #观察发现,file4的inode号码与file2和file3不同,硬链接数也不同
总用量 12
2630487 -rw-rw-r-- 1 hollowman hollowman 8  4月 24 11:40 file1
2634728 -rw-rw-r-- 2 hollowman hollowman 5  4月 24 13:16 file2
2634728 -rw-rw-r-- 2 hollowman hollowman 5  4月 24 13:16 file3
2635043 lrwxrwxrwx 1 hollowman hollowman 5  4月 24 13:21 file4 -> file2

七、目录的创建

linux系统一切皆文件,目录也是一个文件,只不过目录是一个特殊的文件,创建目录的同时,会同时创建1个当前目录以及1个父目录的硬链接。

hollowman@hollowman-f117:~/inodes$ mkdir 1   #创建目录1

hollowman@hollowman-f117:~/inodes$ stat 1   #观察得知其硬链接为2
  文件:1
  大小:4096      	块:8          IO 块:4096   目录
设备:803h/2051d	Inode:2630487     硬链接:2
权限:(0775/drwxrwxr-x)  Uid:( 1000/hollowman)   Gid:( 1000/hollowman)
最近访问:2022-04-24 13:28:55.301912193 +0800
最近更改:2022-04-24 13:28:11.975166355 +0800
最近改动:2022-04-24 13:28:11.975166355 +0800
创建时间:2022-04-24 13:28:11.975166355 +0800
hollowman@hollowman-f117:~/inodes$ ls -al 1   #查看得知,该目录下还自动创建了当前目录(.)和当前目录父目录(..)这2个硬链接
总用量 8
drwxrwxr-x 2 hollowman hollowman 4096  4月 24 13:28 .
drwxrwxr-x 3 hollowman hollowman 4096  4月 24 13:28 ..

得知:目录的硬链接数 = 1(本身) + 1(目录内自动创建的硬链接) + 子目录数(每个子目录内会创建其父目录硬链接) =子目录数 + 2