记录对软链接硬链接的探索。
linux文件系统基础
linux中每个分区包含一个文件系统。一个完整的文件系统包含自举块,超级块,多个柱面组。其中每个柱面分别包含超级块副本,配置信息,i节点图,block位图,i节点和block。
超级块记录文件系统的整体信息,包括文件系统的元信息,inode和block的总量、使用量、剩余量,block和inode的大小,挂载时间,最近一次写入时间,最近一次磁盘检查时间等
inode,固定大小的数据结构(默认128byte,新的文件系统支持256byte),用来存放对应文件的详细信息,每个inode对应一个文件。inode存放的信息至少包含以下
- 文件的存取模式
- 文件的拥有者与群组
- 文件的容量
- 文件的创建或状态改变时间
- 最近一次读取时间
- 最近修改时间
- 文件特性flag
- 文件真正的内容指向
inode记录一个block号码花费4byte,一个inode中有12个byte用来记录block号码,其中包含12个直接索引,1个2级索引,1个3级索引。采用此方法,在inode大小为128byte,block大小为1K的情况下,单个inode支持的最大文件为16GB。
block又可以分为两种:数据块和目录块。数据块存储文件内容,被inode节点索引。一个目录块则对应文件系统中的一个目录。创建一个目录时,文件系统为该目录分配一个inode和至少一个block给该目录,block用来记录该目录下的所有目录项,每个目录项包含两个部分:文件名和文件的inode号码。
一个新建的目录包含两个目录项,. 和 ..,分别指向当前目录和父目录。
linux下创建一个文件即是创建一个目录项的过程,会把新创建的文件名和inode节点作为目录项写入目录中。
硬链接
正常情况下一个文件对应一个inode,但是linux允许多个文件使用同一个inode,这就是硬链接。硬链接可以通过不同的文件名来访问同样的内容,通过下面的实验可以看到文件a和文件b具有相同的inode号码,也即文件a和b实际上是同一个文件。
touch a // 创建一个文件a
stat a // 查看文件的状态信息,看到links为0,与后面对比
> File: 'a'
> Size: 0 Blocks: 0 IO Block: 4096 regular empty file
>Device: 802h/2050d Inode: 33826011 Links: 1
>Access: (0664/-rw-rw-r--) Uid: ( 1000/ sun) Gid: ( 1000/ sun)
>Access: 2020-01-21 11:38:12.250124995 +0800
>Modify: 2020-01-21 11:38:12.250124995 +0800
>Change: 2020-01-21 11:43:18.247896847 +0800
> Birth: -
ln a b // 为文件a建立一个硬链接b
// 查看文件a和b的inode号码
ls -i a b
> 33826011 a 33826011 b
// 查看文件a和b的详细信息,注意links变为2
stat命令输出links指的是此inode的links。links变为2,说明文件系统中有两个目录项指向该inode
软链接
软链接和硬链接的不同之处在于,软链接会创建新的inode,而不是和源文件使用同一个inode。软链接创建的新的inode的代表了软链接是一个独立的文件。软链接之所以能链接到源文件,是因为创建的inode中包含了源文件的路径。
以下通过实验来证明
// 创建文件a的软链接
ln -s a c
// 查看a,b,c文件的信息
stat a b c
> File: 'a'
> Size: 0 Blocks: 0 IO Block: 4096 regular empty file
>Device: 802h/2050d Inode: 33826011 Links: 2
>Access: (0664/-rw-rw-r--) Uid: ( 1000/ sun) Gid: ( 1000/ sun)
>Access: 2020-01-21 11:38:12.250124995 +0800
>Modify: 2020-01-21 11:38:12.250124995 +0800
>Change: 2020-01-21 13:27:47.638658863 +0800
> Birth: -
> File: 'b'
> Size: 0 Blocks: 0 IO Block: 4096 regular empty file
>Device: 802h/2050d Inode: 33826011 Links: 2
>Access: (0664/-rw-rw-r--) Uid: ( 1000/ sun) Gid: ( 1000/ sun)
>Access: 2020-01-21 11:38:12.250124995 +0800
>Modify: 2020-01-21 11:38:12.250124995 +0800
>Change: 2020-01-21 13:27:47.638658863 +0800
> Birth: -
> File: 'c' -> 'a'
> Size: 1 Blocks: 0 IO Block: 4096 symbolic link
>Device: 802h/2050d Inode: 33826012 Links: 1
>Access: (0777/lrwxrwxrwx) Uid: ( 1000/ sun) Gid: ( 1000/ sun)
>Access: 2020-01-21 13:28:01.506706038 +0800
>Modify: 2020-01-21 13:27:58.886697145 +0800
>Change: 2020-01-21 13:27:58.886697145 +0800
> Birth: -
可以看到a和b指向相同的inode,且文件类型都是regular file,而c则指向自己的inode,文件类型是symbolic link。创建新的软链接并不会增加源文件的links值。
通过stat命令看到软链接占用的block为0,说明软链接并不存放数据,也即源文件的路径是存放在inode里面的。
硬链接的限制
- 普通用户不能对目录做硬链接。因为任何一个目录至少有两个硬链接分别指向当前目录和父目录,即.和..。如果对目录做硬链接,在当前目录下硬链接到自己的某个父目录,则在当前目录文件夹下打开父目录并且遍历,会造成死循环。
- 硬链接不能跨文件系统,软链接可以。因为软链接存储的是文件的路径名。
网友评论