文件的元数据
在 Linux 文件系统中,在创建文件系统时,就将存储区域划分为两个部分,一部分用 来保存文件系统的元数据(文件的属性信息,由 inode( index node)组成的一个表),另一个是用来保存文件数据(文件的实际内容)。每个 inode 都有一个唯一的 ID,被称为 inode number,用于标识系统中的文件。
inode 包含以下信息:
文件类型: 用于表示文件的类型,如,普通文件,目录,链接文件,等等;
权限: 用户或组对文件可以执行的操作(读,写,执行);
连接数: 该文件的硬链接数;
UID: 文件所有者的 ID;
GID: 文件所有组的 ID;
文件大小: 文件占用的存储空间
时间戳: 文件最后一次被访问的时间(Access time);文件最后一次被修改时间(Modify time);文件 inode 最后一次被修改的时间(Change time);
访问控制列表: 特殊的用户或组权限,如,某个用户对该文件所拥有的权限;
文件指针: 指向存储文件实际数据的存储块的地址;
其他相关的元数据
文件指针分为:
直接指针(Direct Pointers) : 直接指向数据存的存储地址(数据块);直接指针有 12 个,如果文件系统的每个数据块(blocks)大小为 4K,则直接指针可以保存 48K(12 * 4K)的文件;
间接指针(Single Indirect Pointers): 指向一个指针块,该指针块指向数据的存储地址;假设每个指针的大小为 4 个字节,那么这个间接指针指向的地址块可以保存 1024 ((4K * 1024)/4B) 个指针,每个数据块的大小为 4K,则可以保存的文件数量大小为 4M(1024 * 4K);
双重间接指针(Double Indirect Pointers): 指向指针块,该指针块会指向另一个指针块(第二重),然后再指向到数据的存储地址;同样每个指针的大小为 4B,则这个双重间接指针指向的地址块可以保存 1048576(((4k *1024)/4B)*((4k *1024)/4B)= 1024 * 1024)个指针,每个数据块大小为 4K,则可以保存的文件大小数量为 4G(1024 * 1024 * 4);
三重间接指针(Triple Indirect Pointers): 指向指针块,该指针考块指向另一个指针块(第二重),另一个指针块再指向另一个指针块(第三重),然后再指向到数据的存储地址;以同样的方法计算,每个指针大小为 4B,则三重间接指针指向的地址块可以保存 1073741824(1024 *1024 *1024)个指针,每个数据块大小为 4K,则可以保存的文件大小数量为 4T。
在文件系统中,有一个特殊的文件:目录;目录由目录项构成。目录项中保存了文件名,文件的 inode number 以及文件名与文件 inode number 之间的关系。这样我们就可以通过目录项找到文件的 inode 信息,然后就可以找到对应的数据(文件内容)。
我们可以通过 ls -l 或 stat 命令查看这些信息。
it@testsvra:~$ ls -l f1
-rw-rw-r-- 1 root root 17 Feb 2 10:12 f1
it@testsvra:~$ stat f1
File: f1
Size: 17 Blocks: 8 IO Block: 4096 regular file
Device: 804h/2052dInode: 1966094 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-02-02 10:09:21.304595508 +0800
Modify: 2021-02-02 10:12:41.124606395 +0800
Change: 2021-02-02 10:12:41.124606395 +0800
Birth: -
* stat 看到的信息更多。
stat 看到的信息:
file: 文件的名称
Size: 文件的大小,以字节为单位
Blocks: 文件占用的块的数量
IO Block: 块的大小
File type: 文件的类型,如,示例中的 regular file,还有其他的文件类型,如,directory,symbolic link 等等;
Device: 文件存储在硬盘的位置(柱面)
Inode: 节点编号
Links: 链接数
Access: 访问权限
Uid: 该文件的所有者以及它的 ID
Gid: 文件的所有组以及它的 ID
时间戳
Access: 文件最后一次被访问的时间
Modify: 文件最后一次被修改的时间
Change: 文件属性最后一次被修改的时间
Birth: 文件创建的时间(Linux 不支持,所以为空)
移动文件或文件夹到其它分区,节点编号会变,因为每个分区都会有自己的节点编号分配池,为了防止出现重复,当你复制文件或文件夹到新的分区时,将使用新分区为其分配的节点编号:
it@testsvra:~$ ls -il f1
1966090 -rw-rw-r-- 1 it it 0 Feb 2 14:25 f1
it@testsvra:~$ sudo mv f1 /boot/
[sudo] password for it:
it@testsvra:~$ ls -il /boot/f1
312 -rw-rw-r-- 1 it it 0 Feb 2 14:25 /boot/f1
节点编号是有限的,因此可以重复利用,当文件或文件夹被删除时,节点编号就会被回收,当需要时,再分配给新的文件或文件夹:
it@testsvra:~$ touch f3
it@testsvra:~$ ls -il f3
1966090 -rw-rw-r-- 1 it it 0 Feb 2 14:28 f3
* f3 的节点编号,是之前分配给 f1 的
我们可以通过 df -i 命令查看每个分区节点编号的使用情况:
it@testsvra:~$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 243446 427 243019 1% /dev
tmpfs 254429 709 253720 1% /run
/dev/sda4 3571712 80255 3491457 3% /
tmpfs 254429 1 254428 1% /dev/shm
tmpfs 254429 3 254426 1% /run/lock
tmpfs 254429 18 254411 1% /sys/fs/cgroup
/dev/sda2 98304 313 97991 1% /boot
/dev/loop0 10756 10756 0 100% /snap/core18/1880
/dev/loop2 463 463 0 100% /snap/snapd/8542
tmpfs 254429 22 254407 1% /run/user/1000
/dev/loop3 472 472 0 100% /snap/snapd/10707
/dev/loop4 10809 10809 0 100% /snap/core18/1944
/dev/loop5 1578 1578 0 100% /snap/lxd/19032
/dev/loop6 1578 1578 0 100% /snap/lxd/19188
nap/core18/1944
/dev/loop5 1578 1578 0 100% /snap/lxd/19032
/dev/loop6 1578 1578 0 100% /snap/lxd/19188