Linux 文件软链接与硬链接

Linux 文件软链接与硬链接

七月 19, 2025 次阅读

什么是 inode

Inode(Index Node,索引节点)是类 Unix 文件系统(如 ext4、XFS、Btrfs 等)中用于管理文件元数据和数据块指针的核心数据结构。它是操作系统在磁盘上定位和操作文件的真实凭据(而非文件名)。

Inode 的核心作用

  1. 存储文件元数据**
    • 不包含文件名,但包含所有其他文件属性:
文件类型(普通文件/目录/符号链接/设备文件等)
权限(rwx)
所有者(UID/GID)
大小(字节数)
时间戳(创建/修改/访问时间)
链接计数(硬链接数)
...
  1. 指向文件数据块
    • 记录文件内容在磁盘上的物理存储位置(数据块指针)。
  2. 唯一标识文件
    • 每个 inode 有一个唯一的编号(inode number),操作系统通过 inode 号而非文件名访问文件。

Inode 的底层结构

在 ext4 文件系统中,inode 是一个固定大小的结构(通常为 256 字节),其关键字段如下:

字段 描述
i_mode 文件类型 + 权限(如 0o100644 表示普通文件,权限 rw-r--r--
i_uid / i_gid 所有者用户 ID 和组 ID
i_size 文件大小(字节)
i_atime 最后访问时间
i_mtime 最后修改时间
i_ctime inode 状态变更时间
i_links_count 硬链接计数(删除文件时仅当此值为 0 才释放数据块)
i_block[15] 数据块指针(直接/间接指向磁盘块,符号链接时直接存储目标路径)
i_flags 标志位(如加密/压缩/内联数据等特性)

Inode 如何关联到文件

  1. 目录的作用

    • 目录本质是一个映射表,存储 文件名 -> inode 编号 的对应关系。
    • 例如目录 /home 的内容可能如下:
    .    -> inode 1234  (当前目录)
    ..   -> inode 2     (父目录)
    alice -> inode 5678 (用户目录)
    bob   -> inode 9012
  2. 文件访问流程
    当访问 /home/alice/file.txt 时:

    • 从根目录 /(inode 通常为 2)找到 home 的 inode 编号
    • 读取 home 的 inode,定位其数据块,找到 alice 的 inode 编号
    • 最终找到 file.txt 的 inode,进而访问文件内容。

Inode 的分配与管理

  1. inode Bitmap

    • 文件系统用位图(Bitmap)标记 inode 的使用状态(1=已分配,0=空闲)。
    • 创建文件时扫描 Bitmap 分配空闲 inode。
  2. inode 表(inode Table)

    • 磁盘上的固定区域,存储所有 inode 结构的数组。
    • 通过 inode 编号可直接计算其物理位置:
      inode 物理位置 = inode_table_start + (inode_number * inode_size)
  3. 链接计数(i_links_count

    • 硬链接会增加该计数,删除文件时计数减 1。
    • 当计数归零时,inode 和数据块被释放。

总结如下:

  • Inode 是文件的唯一身份证,文件名只是人类可读的别名。
  • 通过 inode 可以高效管理文件元数据和数据存储位置。
  • 理解 inode 是掌握文件系统工作原理(如软硬链接、文件删除恢复等)的基础。

硬链接的实现

  • 创建过程:当创建硬链接时,系统会在目标目录中添加一个新的文件名条目,这个条目指向与被链接文件相同的 inode。
  • inode 变化:inode 中的”链接计数”(link count)会加1。这个计数器记录有多少个目录项指向该 inode。
  • 特点
    • 硬链接与原文件完全平等,无法区分谁是原始文件
    • 只有当链接计数降为0时,文件数据才会被真正删除
    • 不能跨文件系统(因为不同文件系统有独立的 inode 空间)
    • 不能链接目录(防止循环链接)

示例如下:

╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  ln test.cc test1.cc
╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  ll
total 0
-rw-r--r-- 2 ljx ljx 0 Jul 19 12:34 test1.cc
-rw-r--r-- 2 ljx ljx 0 Jul 19 12:34 test.cc

可以看到,硬链接会使得硬链接引用计数加一,而我们若删掉原来的硬链接原副本,会发现被硬链接的副本引用技术变为1,因此,一个文件真正被删除实际是引用计数从1变成0的时候:

╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  rm test.cc
╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  ll
total 0
-rw-r--r-- 1 ljx ljx 0 Jul 19 12:28 test1.cc

软链接(符号链接)的实现

  • 创建过程:创建软链接时,系统会:
    1. 分配一个新的 inode 和新的文件(这个文件的内容是目标路径字符串)
    2. 在目录中添加一个特殊标记的条目,表示这是一个符号链接
  • inode 变化
    • 原始文件的 inode 不受影响
    • 新创建的符号链接有自己的 inode,其中存储了目标路径信息
  • 特点
    • 是一个独立的文件(有自己的 inode),只是内容存储了目标路径
    • 可以跨文件系统
    • 可以链接目录
    • 如果目标文件被删除,链接会”悬空”(dangling)

示例如下:

╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  ln -s test1.cc test2.cc
╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  ll
total 0
-rw-r--r-- 1 ljx ljx 0 Jul 19 12:34 test1.cc
lrwxrwxrwx 1 ljx ljx 8 Jul 19 12:35 test2.cc -> test1.cc

此时我们若删除原副本,将会导致链接失效:

╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  rm test1.cc
╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  ll
total 0
lrwxrwxrwx 1 ljx ljx 8 Jul 19 12:35 test2.cc -> test1.cc
╭─ljx@VM-16-15-debian ~/linux_review/lesson5
╰─➤  cat test2.cc
cat: test2.cc: No such file or directory

关键区别的底层表现

特性 硬链接 软链接
inode 与原文件相同 分配新的 inode
存储内容 直接指向文件数据 存储目标文件的路径字符串
跨文件系统 不可能 可能
链接目录 通常不允许 允许
目标删除后 仍可访问(直到链接计数为0) 链接失效(”悬空”)
文件大小 与原文件相同 等于路径字符串的长度
权限 与原文件相同 通常是全开放(777)

应用场景

软链接应用场景

在 Window 当中,软链接广泛应用于快捷方式,我们桌面上的图标之所以可以直接被打开,是因为这些图标本质上是将可执行程序的路径软链接到了桌面

soft

硬链接应用场景

Linux 当中的文件管理就使用到了硬链接,每个目录下有两个隐藏文件:“.”,“..”分别代表当前路径和上一个目录的路径,因此,一个文件夹下每多一个目录,该文件夹就会多一个硬链接引用计数

链接目录

硬链接是不允许链接目录的

硬链接的本质是 多个文件名指向同一个 inode,而目录在文件系统中具有特殊结构,允许硬链接目录会导致以下问题:

(1)目录树循环问题

  • 目录结构在文件系统中是一棵 有向无环图(DAG),通过硬链接目录可能形成循环引用:
# 假设允许硬链接目录:
ln /home/user/dir /home/user/dir/link_to_self

此时:

  • /home/user/dir 包含 link_to_self,而 link_to_self 又指向 /home/user/dir
  • 遍历目录时会进入无限循环(如 findls -R 等命令会崩溃)。

(2)父目录引用计数混乱

  • 每个目录的 inode 中都有一个 .. 条目指向父目录。

  • 如果允许硬链接目录,.. 应该指向哪个父目录?

    /dir1/subdir (硬链接到 /dir2/subdir)
    • subdir.. 应该是 /dir1 还是 /dir2?无法确定。

(3)文件系统一致性难以维护

  • 文件系统工具(如 fsck)依赖目录树的严格父子关系检测错误。
  • 硬链接目录会破坏这种关系,导致恢复困难。

当然,... 是硬链接

  • 每个目录的 .(当前目录)和 ..(父目录)是文件系统内部维护的硬链接:
  • 这是唯一合法的目录硬链接,由文件系统自身管理。