0


Linux中的软硬链接文件详解

概述

在Linux文件系统中,软连接(Symbolic Link)和硬连接(Hard Link)是两种重要的文件链接方式。它们都可以创建指向相同文件内容的多个“链接”,但在实现方式和特性上有所不同。

1. 硬连接(Hard Link)

  • 概念:硬连接是同一个文件在文件系统中的多个目录项,本质上是给同一个inode分配多个文件名。所有硬连接都指向同一个inode,即同一份数据。
  • 特点: - 硬连接与目标文件共享同一个inode,因此只在同一文件系统内有效。- 删除目标文件或硬链接文件不会影响其他硬链接,只有当所有硬连接被删除后,文件数据才会真正被删除。- 硬连接只能指向文件,不能指向目录。
  • 创建命令:使用ln [目标文件] [链接文件]来创建硬连接。例如: ln /home/user/file.txt /home/user/hard_link_to_file

2. 软连接(Symbolic Link)

  • 概念:软连接是一种指向文件或目录的引用,类似于Windows中的快捷方式。软连接文件包含目标文件的路径,当访问软连接时,系统会自动跳转到目标文件。
  • 特点: - 软连接是一个独立的文件,具有自己的inode(索引节点)。- 软连接可以跨文件系统创建,即可以链接到不同分区上的文件。- 软连接可以指向文件或目录。- 如果目标文件被删除,软连接会失效,变成“断链”(Broken Link)。
  • 创建命令:使用ln -s [目标文件或目录] [链接文件]来创建软连接。例如: ln -s /home/user/file.txt /home/user/link_to_file

总结

特性软连接硬连接是否共享inode否是跨文件系统支持不支持指向类型文件或目录文件失效情况目标文件删除则失效目标或链接删除不影响其他
软连接适合用于快捷访问不同位置的文件或目录,硬连接则更适合需要在同一文件系统中保留文件副本的场景。

原理

inode源码

以下结构体对应文件的inode的源码,其中不相关的部分已省略

struct ext2_inode {
    ...
    __le32    i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
    ...
};

**

__le32 i_block[EXT2_N_BLOCKS]

**: 文件数据块的指针数组,

EXT2_N_BLOCKS

通常定义为 15。前 12 个是直接指向数据块的指针,后面 3 个分别是单重、双重、三重间接指针,用于存储文件内容的物理地址。

目录结构体源码

struct ext2_dir_entry_2 {
    __le32    inode;            /* Inode number */
    __le16    rec_len;        /* Directory entry length */
    __u8    name_len;        /* Name length */
    __u8    file_type;
    char    name[];            /* File name, up to EXT2_NAME_LEN */
};
  • inode:表示该目录项对应的文件或子目录的 inode 编号。通过该 inode 编号,可以找到文件或子目录的元数据。
  • rec_len:当前目录项所占的总字节数。由于目录项的大小是可变的,rec_len 指定了目录项的长度,使得下一个目录项可以紧接着前一个目录项存储。
  • name_len:文件名的长度。这个字段允许目录项中存储可变长度的文件名。
  • file_type:表示文件的类型,例如普通文件、目录、符号链接等。
  • name:目录项的名称,即文件或目录的名字。名称是一个可变长度的字符串,实际长度由 name_len 字段指定。

硬连接

硬连接文件和源文件使用同一个inode,只是这个inode有两个不一样的文件名称, 对应的ext2_inode结构体中的**

i_block

**

中存放的是数据块的具体地址;在目录的数据块中硬链接为一个inode号与原始文件inode相同的新的条目。

软连接

软连接是一个全新的文件,为不同的inode,通常情况下,**

i_block

** 是用来存储文件数据块地址的。但在 EXT2 文件系统 中,有一个例外:对于小于 60 字节的软链接文件,**

i_block

会直接存储软链接目标路径,而不是数据块地址**。这种设计是为了提高效率,因为短路径的软链接可以直接在 inode 中存储路径信息,从而避免为软链接额外分配数据块;在目录的数据块中体现为一个全新的拥有独立的inode号的文件条目。

具体来说:

  • 普通文件和较大的软链接文件i_block 中保存的是数据块的地址。
  • 小的软链接文件(通常指目标路径少于 60 字节):i_block 中直接保存路径字符串,而不是数据块地址。

这是 EXT2 文件系统的一种优化策略,使得对短路径的软链接访问更快,也减少了磁盘空间的使用。

示例

以下是link目录中这三个文件的详细信息,可以发现软连接和硬连接分别占据了一个条目,软连接的inode号和原文件不同,软连接的inode为1923,原文件inode为1922;硬连接和原文件的inode号相同为1922。

# 查看link目录的inode
[root@ct7_node01 disk]# ll -di link
1921 drwxr-xr-x. 2 root root 1024 Nov  6 15:01 link

# 查看当前目录下各文件的inode,"."目录对应link目录的inode 1921,".."代表上一级目录的inode 2
[root@ct7_node01 link]# ll -ai ./
total 8
1921 drwxr-xr-x. 2 root root 1024 Nov  6 15:01 .
   2 drwxr-xr-x. 5 root root 1024 Nov  6 15:00 ..
1922 -rw-r--r--. 2 root root    3 Nov  6 15:01 hardlinkfile
1923 lrwxrwxrwx. 1 root root   10 Nov  6 15:01 softlinkfile -> sourcefile
1922 -rw-r--r--. 2 root root    3 Nov  6 15:01 sourcefile
[root@ct7_node01 link]# 

# 查看目录link对应的block地址
[root@ct7_node01 link]# debugfs /root/disk.img 
debugfs 1.42.9 (28-Dec-2013)
debugfs:  blocks link
8556 
debugfs:  

# 通过查询到的地址块8556查看目录link中的内容
[root@ct7_node01 link]# hexdump -s 8556K -n 1k /root/disk.img -C
0085b000  81 07 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|
0085b010  0c 00 02 02 2e 2e 00 00  82 07 00 00 14 00 0a 01  |................|
0085b020  73 6f 75 72 63 65 66 69  6c 65 00 00 82 07 00 00  |sourcefile......|
0085b030  14 00 0c 01 68 61 72 64  6c 69 6e 6b 66 69 6c 65  |....hardlinkfile|
0085b040  83 07 00 00 c0 03 0c 07  73 6f 66 74 6c 69 6e 6b  |........softlink|
0085b050  66 69 6c 65 00 00 00 00  00 00 00 00 00 00 00 00  |file............|
0085b060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0085b400
[root@ct7_node01 link]# 

# 可以看到当前目录对应的内容1921代表link目录的inode,2代表上一级目录的inode
# 1922、1922、1923分别代表原文件、硬连接文件、软连接文件
[root@ct7_node01 disk]# hexdump -s 8556K -n 1k /root/disk.img -d
085b000   01921   00000   00012   00513   00046   00000   00002   00000
085b010   00012   00514   11822   00000   01922   00000   00020   00266
085b020   28531   29301   25955   26982   25964   00000   01922   00000
085b030   00020   00268   24936   25714   26988   27502   26982   25964
085b040   01923   00000   00960   01804   28531   29798   26988   27502
085b050   26982   25964   00000   00000   00000   00000   00000   00000
085b060   00000   00000   00000   00000   00000   00000   00000   00000
*
085b400
[root@ct7_node01 disk]# 

接下来看一下软连接文件的数据块中的内容

[root@ct7_node01 link]# ll -i softlinkfile 
1923 lrwxrwxrwx. 1 root root 10 Nov  6 15:01 softlinkfile -> sourcefile

# inode 1923的偏移bit位置,结合dumpe2fs进行计算
# 8316*1024+128*2=8515840

[root@ct7_node01 link]# hexdump -s 8515840 -n 128 /root/disk.img -C
0081f100  ff a1 00 00 0a 00 00 00  64 14 2b 67 53 14 2b 67  |........d.+gS.+g|
0081f110  53 14 2b 67 00 00 00 00  00 00 01 00 02 00 00 00  |S.+g............|
0081f120  00 00 00 00 01 00 00 00  73 6f 75 72 63 65 66 69  |........sourcefi|
0081f130  6c 65 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |le..............|
0081f140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0081f160  00 00 00 00 ba cf 18 c5  f3 40 00 00 00 00 00 00  |.........@......|
0081f170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0081f180
[root@ct7_node01 link]#

通过上面的截图可以看到在softlinkfile的inode1923中本应该存放data blocks地址的地方现在直接存放了软连接的名称;而硬连接文件hardlinkfile的inode 1922中data blocks内存放的是地址,如以下代码所示。

[root@ct7_node01 link]# ll -i hardlinkfile 
1922 -rw-r--r--. 2 root root 3 Nov  6 15:01 hardlinkfile

# inode 1922的偏移bit位置,结合dumpe2fs进行计算
# 8316*1024+128=8515712

[root@ct7_node01 link]# hexdump -s 8515712 -n 128 /root/disk.img -C
0081f080  a4 81 00 00 03 00 00 00  33 14 2b 67 38 14 2b 67  |........3.+g8.+g|
0081f090  33 14 2b 67 00 00 00 00  00 00 02 00 04 00 00 00  |3.+g............|
0081f0a0  00 00 00 00 01 00 00 00  01 22 00 00 00 00 00 00  |........."......|
0081f0b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0081f0e0  00 00 00 00 b9 cf 18 c5  f3 40 00 00 00 00 00 00  |.........@......|
0081f0f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0081f100

# 通过十进制重新展示,自动计算data block中的值为8705
[root@ct7_node01 link]# hexdump -s 8515712 -n 128 /root/disk.img -d
081f080   33188   00000   00003   00000   05171   26411   05176   26411
081f090   05171   26411   00000   00000   00000   00002   00004   00000
081f0a0   00000   00000   00001   00000   08705   00000   00000   00000
081f0b0   00000   00000   00000   00000   00000   00000   00000   00000
*
081f0e0   00000   00000   53177   50456   16627   00000   00000   00000
081f0f0   00000   00000   00000   00000   00000   00000   00000   00000
081f100
[root@ct7_node01 link]#

# 查看对应数据块中的内容
[root@ct7_node01 link]# hexdump -s 8705K -n 1k /root/disk.img -C
00880400  61 61 0a 00 00 00 00 00  00 00 00 00 00 00 00 00  |aa..............|
00880410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00880800
[root@ct7_node01 link]# 

# 也通过debugfs验证硬链接的block data的地址
[root@ct7_node01 link]# debugfs /root/disk.img 
debugfs 1.42.9 (28-Dec-2013)     
debugfs:  blocks link/hardlinkfile
8705 
debugfs:  

本文转载自: https://blog.csdn.net/zyqash/article/details/143489881
版权归原作者 巭犇 所有, 如有侵权,请联系我们删除。

“Linux中的软硬链接文件详解”的评论:

还没有评论