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)依赖目录树的严格父子关系检测错误。
  • 硬链接目录会破坏这种关系,导致恢复困难。

当然,... 是硬链接

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