Btrfs (简体中文) - ArchWiki

Jump to content

相关文章

- File systems
- Btrfs - Tips and tricks
- Mkinitcpio-btrfs
- Snapper
- Installing on Btrfs root

翻译状态：本文是 Btrfs 的翻译。上次翻译日期：2020-10-19。如果英文版本有所更改，则您可以帮助同步翻译。

引自 Btrfs Wiki：

  Btrfs 是一种现代的写时复制（CoW）Linux 文件系统，已经并入内核主线。Btrfs 致力于实现一些高级功能，同时着重于容错性、修复性以及易于管理性。它由多家企业共同开发，以 GNU GPL 协议授权，并欢迎任何人的贡献。

警告：

- Btrfs 有一些功能尚不稳定，可参见内核百科的 Btrfs 稳定性状态报告（英文）、Btrfs 足够稳定了吗？（英文） 和 开始使用 Btrfs（英文）。
- 了解当前的 #已知问题。

## 准备工作

要使用一些用户空间工具的话，需要 安装 基础操作必须的 btrfs-progs 软件包。

如果需要从 Btrfs 文件系统引导（比如说内核和内存盘在一个 Btrfs 的分区上），请检查 启动引导器 是否支持 Btrfs。

## 创建文件系统

下文展示了如何创建一个新的 Btrfs 文件系统。要将一个 ext3/4 分区转换为 Btrfs，请参考 #从 Ext3/4 转换。要使用无分区的配置，请参考 #无分区 Btrfs 磁盘。

查阅 mkfs.btrfs(8) 以获取更多信息。

### 单一设备上的文件系统

要在分区 `/dev/partition` 上创建一个 Btrfs 文件系统，执行：

    # mkfs.btrfs -L mylabel /dev/partition

Btrfs 用于元数据的默认节点大小 (nodesize) 为 16KB，而用于数据的默认扇区大小 (sectorsize) 等于页面大小 (page size) 并会自动检测。 要对元数据使用较大的节点大小 (必须为扇区大小的倍数，最大允许 64KB)，请通过 `-n` 开关为 `nodesize` 指定一个值。如下例所示，使用 32KB 块大小：

    # mkfs.btrfs -L mylabel -n 32k /dev/partition

注意： 根据 mkfs.btrfs(8) § OPTIONS 手册页内容：“较小的节点大小会增加碎片，但也会让 B-trees 更高，进而使得锁定争用（locking contention）更少。较高的节点大小则能有更好的打包（packing）和更少的碎片，但代价是，更新元数据块时会使用更多的内存”。

### 多设备文件系统

警告： Btrfs 的 RAID 5 和 RAID 6 模式存在致命缺陷，除非用来做数据丢失测试，否则不应当用于任何场景。这里有已知问题和部分解决方法的列表。 查阅 Btrfs Wiki 网页上关于 RAID 5 和 RAID 6 的说明 以获取最新动态（似乎不更新了）。

多个设备可以用来创建一组 RAID。支持的 RAID 级别有 RAID 0、RAID 1、RAID 10、RAID 5 和 RAID 6。从 5.5 版本内核开始，新增对 `RAID1c3` 和 `RAID1c4` 的支持，分别是 3 份冗余和 4 份冗余的 RAID 1。可以使用 `-d` 和 `-m` 参数分别为数据和元数据配置 RAID 等级。默认情况下，数据有一份副本（`single`），元数据则被镜像（`RAID1`）。这就像创建一个 JBOD 配置，多个磁盘会被看做成一个文件系统，但文件不会重复。更多有关如何创建一个 Btrfs RAID 卷的信息请参阅 Btrfs Wiki:在多个设备上使用 Btrfs。

    # mkfs.btrfs -d single -m raid1 /dev/part1 /dev/part2 ...

必须在 `/etc/mkinitcpio.conf` 中加入 `udev` 钩子或 `btrfs` 钩子才能在一个池中使用多个 Btrfs 设备。查阅 Mkinitcpio (简体中文)#常用钩子 以获取更多信息。

注意：

- 可以稍后再将设备添加到多设备文件系统中。详情请参见 Btrfs wiki 文章。
- 多个设备可以大小各异。但是，如果在 RAID 配置中一个硬盘的大小比其他的都大，那么它多出的空间将不会被使用。
- 有些 引导加载程序 不支持多设备文件系统，比如 Syslinux。
- Btrfs 不会自动从速度最快的设备读取，因此混合使用不同类型的磁盘会导致性能表现不恒定。详情请参阅 Stack Overflow 上的这个回答。

#RAID 小节中有关于维护多设备上的 Btrfs 文件系统的一些建议。

## 配置文件系统

### 写时复制 (CoW)

默认情况下 Btrfs 对所有文件使用 写时复制 (CoW)。参阅 Btrfs 系统管理指南相关章节 以获取实现细节以及它的优点和缺点。

#### 停用 CoW

要对某个子卷上的新文件停用写时复制，使用 `nodatacow` 挂载选项。这只会影响新创建的文件，写时复制仍然会在已存在的文件上生效。`nodatacow` 参数同样会禁用压缩。参阅 btrfs(5) 以了解细节。

注意： 引自 btrfs(5) § MOUNT OPTIONS:“在单个文件系统中，无法使用 `nodatacow` 参数挂载某些子卷，而其他的使用 `datacow` 参数。第一个被挂载子卷的挂载参数将会应用于其他所有子卷。”

要单文件或目录禁用写时复制特性，请使用下面的命令：

    $ chattr +C [文件/目录的地址(path)]

这会为这个文件的单个引用停用写时复制,如果这个文件不只有一个引用(例如通过 `cp --reflink=always` 生成或者在文件系统快照中)，写时复制依然生效。

注意： 引自 chattr 的手册页:“在 Btrfs 上，'C' 标志应该被设置在新建的或者是空白的文件/目录，如果被设置在已有数据的文件，当块分配给该文件时，文件将不确定是否完全稳定。如果 'C' 标志被设置给一个目录，将不会影响目前的目录，但在该目录创建的新文件将具有 No_COW 属性。”
提示： 可以用下面的方法为已存在的文件或目录停用写时复制:

    $ mv /path/to/dir /path/to/dir_old
    $ mkdir /path/to/dir
    $ chattr +C /path/to/dir
    $ cp -a /path/to/dir_old/* /path/to/dir
    $ rm -rf /path/to/dir_old

需要保证这个过程中目标文件不会被使用，同时注意下面描述的 `mv` 或 `cp --reflink` 并不起作用。

#### 创建轻量副本

默认情况下，使用 `cp` 复制 Btrfs 文件系统上的文件时，会创建实际副本。要创建引用原始数据的轻量级副本，请使用 reflink 选项：

    $ cp --reflink source dest

参阅 `cp` 的手册页获得关于 `--reflink` 标志的更多信息。

### 压缩

Btrfs 支持 透明和自动压缩。这就减小了文件的大小，通过减少文件写入增幅来显著延长闪存介质（flash-baesd media）的寿命 [1][2][3]。在某些特定的场景下（比如单线程、重负荷的文件 I/O)）还 提高了性能。尽管在其他的场景下（比如多线程和/或大文件 I/O 高强度 CPU 任务）还是明显影响了性能。通常使用更快的压缩算法，比如 zstd 和 lzo 可以获得更好的性能，这个 性能测试 提供了详细的对比。

承上文，`compress=alg` 挂载选项可自动考虑为每个文件启用压缩，其中的 `alg` 处可以选填为 `zlib`, `lzo`, `zstd`, 或者 `no`（即不压缩）。由此，Btrfs 将检查压缩数据的第一部分是否能将其缩减。如果能，则会压缩该文件的整个写入；否则不会压缩任何内容。所以，如果数据的第一部分没有被缩减，那么即使数据的其余部分可以大大缩减，写入时也不会被压缩。[4] 这样做是为了防止让磁盘一直等待写入，直到所有要写入的数据传递给 Btrfs 并被压缩后为止。

另外可以改用 `compress-force=alg` 挂载选项，这会让 Btrfs 跳过对数据第一部分的压缩检查，并尝试对每个文件启用自动压缩。最不济的情况，这会 (稍微) 导致 CPU 占用率无故升高。不过，在多个混合使用系统的经验测试显示，与仅使用 `compress=zstd` (其也有 10％ 的磁盘压缩率) 相比，使用 `compress-force=zstd` 可以显著提高约 10％ 的磁盘压缩率。

只有在加入挂载选项后创建或修改的文件才会被压缩。

给现存文件启用压缩，可使用 `btrfs filesystem defragment -calg` 命令，`alg` 处可选填为 `zlib`，`lzo` 或 `zstd`。举例来说，要用 zstd 方式给整个文件系统重新压缩，执行下列命令：

    # btrfs filesystem defragment -r -v -czstd /

警告： 对具有 CoW 副本（快照副本或使用`cp --reflink`或 bcp 创建的文件）进行碎片整理以及使用带压缩算法的 `-c` 开关进行碎片整理可能会导致生成两个不相关的文件从而大幅增加磁盘使用量。

要在新的 Btrfs 分区上安装 Arch Linux 时就启用压缩功能 (充分利用压缩特性)，请在 挂载 文件系统时使用 `compress` 选项：`mount -o compress=zstd /dev/sdxY /mnt/`。在配置过程中，请在 fstab 中把 `compress=zstd` 添加到根目录文件系统的挂载选项里。

提示： 通过执行 `chattr +c`，也可以在不使用 `compress` 选项的情况下为每个单文件启用压缩属性。对目录执行会使这个目录下新文件自动被压缩。
警告：

- 如果使用 `zstd` 参数，使用较旧版本内核或者尚不支持 `zstd` 的 btrfs-progs 的系统可能不能读取或修复您的文件系统。
- GRUB 在 2.04 版本中引入了对 zstd 的支持。使用此后版本时，请通过手动运行 `grub-install`（需添加适用于机器 BIOS/UEFI 设置的选项参数）确保安装在 MBR/ESP 中的引导加载程序已确实升级，因为这些事情不会自动完成。可参阅 FS#63235。

#### 查看压缩类型和压缩比

compsize 软件包能获取一个文件列表 (或一整个 Btrfs 文件系统)，并测量出它们使用的压缩类型和其有效压缩比。不过，其给出的未压缩时大小数值不一定能和其他程序 (比如 `du`) 给出的数值吻合，因为每一文件所占空间范围都会计数一次，即使文件被链接了多次，即使文件的一部分不再被使用 (但其未被垃圾回收)。 `-x` 选项可让程序运行保持在单一个文件系统上，这在 `compsize -x /` (检查根目录) 之类的情况下很有用，可以避免程序去尝试访问非 Btrfs 子目录从而导致整个程序运行失败。

### 子卷

"btrfs 子卷不是 (也不能看作) 块设备,一个子卷可以看作 POSIX 文件名字空间.这个名字空间可以通过子卷上层访问,也可以独立挂载."[5]

每个 btrfs 文件系统都有一个 ID 为 5 的顶层子卷。它可以挂载为 `/`（默认情况下），或者可以挂载为另一个子卷。子卷可以在文件系统中移动，它们通过其 ID 而不是路径来标识。

参阅下面的链接获得更多信息:

- Btrfs Wiki SysadminGuide#Subvolumes
- Btrfs Wiki Getting started#Basic Filesystem Commands
- Btrfs Wiki Trees

#### 创建子卷

要创建一个子卷:

    # btrfs subvolume create /path/to/subvolume

#### 列出子卷列表

要列出当前路径 (`path`) 下的子卷和它们的 ID:

    # btrfs subvolume list -p path

#### 删除子卷

要删除一个子卷:

    # btrfs subvolume delete /path/to/subvolume

自 Linux 4.18 起, 用户可以像移除常规目录一样删除一个子卷 (用 `rm -r`, `rmdir` 命令)。

#### 挂载子卷

可以使用 `subvol=/path/to/subvolume` 或 `subvolid=objectid` 挂载标志来安装子卷，就像文件系统分区一样。例如，您可以拥有一个名为 `subvol_root` 的子卷，并将其挂载为 `/`。通过在文件系统的顶层创建各种子卷，然后将它们挂载到适当的挂载点，可以模仿传统的文件系统分区。 因此，可以使用 #快照 轻松地将文件系统（或其一部分）恢复到先前的状态。

提示： 不使用顶层子卷 (ID=5) 挂载为根目录，可以更方便地修改子卷的布局结构。相反，可考虑创建新的子卷，然后挂载为 `/`。
注意： 引自 btrfs(5) § MOUNT OPTIONS:“大多数挂载选项适用于整个文件系统，并且只有要挂载的第一个子卷的选项才会生效。 这是因为没有实现，未来可能会发生变化。”可参阅 Btrfs Wiki FAQ 以了解哪些挂载参数能够被用于独立的子卷。

参阅 Snapper#Suggested filesystem layout, Btrfs SysadminGuide#Managing Snapshots 和 Btrfs SysadminGuide#Layout 获得子卷应用的示例。

有关 Btrfs 特定的挂载选项的完整列表，请参阅 btrfs(5)。

#### 挂载子卷为根挂载点

要使用一个子卷作为根挂载点，请使用 `rootflags=subvol=/path/to/subvolume` —— 一个 内核参数 指定子卷。在 `/etc/fstab` 中编辑根挂载点并指定挂载选项 `subvol=`。或者可以在 `/etc/fstab` 中用 ID 指定子卷：用 `rootflags=subvolid=objectid` 作为内核参数并用 `subvolid=objectid` 作为挂载选项。

#### 改变默认子卷

如果挂载时不指定 `subvol=` 选项便会挂载默认子卷。要改变默认子卷，执行：

    # btrfs subvolume set-default subvolume-id /

subvolume-id 可以通过#列出子卷列表获得。

注意： 在安装了 GRUB 的系统上，在改变默认子卷以后不要忘记运行 `grub-install`。参见 这个论坛帖子。

通过 `btrfs subvolume set-default` 修改默认子卷将会导致文件系统的最顶层无法访问，除非使用 `subvol=/` 或者 `subvolid=5` 挂载参数。[6]

### 配额

警告： Qgroup 尚且不稳定且在有（过多）快照的子卷上应用配额可能会导致性能问题，比如在删除快照的时候。 此外，这里还有更多 已知问题.

Btrfs中的配额支持是通过使用配额组或 qgroup 在子卷级别实现的：默认情况下，每个子卷都以 0/subvolume_id 的形式分配配额组。 但是，如果需要的话，可以使用任意数字创建配额组。

要使用 Qgroup，你首先需要启用它：

    # btrfs quota enable path

从此时开始，新创建的子卷将由这些配额组控制。 为了能够为已创建的子卷启用配额，首先正常启用配额，然后使用它们的 subvolume_id 为每个子卷创建一个配额组，再重新扫描它们：

    # btrfs subvolume list path | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} path
    # btrfs quota rescan path

Btrfs 中的配额组形成树层次结构，其中 Qgroup 附加到子卷。大小限制由每个 Qgroup 独立配置且在并在包含给定子卷的树中达到任何限制时应用。

配额组的限制可以应用于总数据使用，非共享数据使用，压缩数据使用或全部。文件复制和文件删除可能都会影响限制，因为如果删除原始卷的文件并且只剩下一个副本，则另一个 Qgroup 的非共享限制可能会更改。例如，新快照几乎与原始子卷共享所有块，对子卷的新写入将向专用限制提升，一个卷中的公共数据的删除将升高到另一个卷中的专用限制。

要对 Qgroup 应用限制，请使用命令 `btrfs qgroup limit`。根据你的使用情况，使用总限制，非共享限制（`-e`）或压缩限制（`-c`）。

显示文件系统使用中给定路径的使用情况和限制：

    # btrfs qgroup show -reF path

### 提交间隔

将数据写入文件系统的频率由 Btrfs 本身和系统的设置决定。Btrfs 默认设置为 30 秒检查点间隔，新数据将在 30 秒内被提交到文件系统。 这可以通过在 `/etc/fstab` 增加 `commit` 挂载参数来修改：

    LABEL=arch64 / btrfs defaults,noatime,compress=lzo,commit=120 0 0

系统范围的设置也会影响提交间隔。它们包括 `/proc/sys/vm/*` 下的文件，这超出了本维基文章的范围，因此不再赘述。 它们的内核文档位于 `Documentation/sysctl/vm.txt`。

### SSD TRIM

Btrfs 文件系统能够从支持 TRIM 命令的 SSD 驱动器中释放未使用的块。内核从 5.6 版本开始提供了异步丢弃（asynchronous discard）支持，可使用挂载参数 `discard=async` 启用。已释放的空间范围不会被马上丢弃，它们会被集中起来并在稍后由一个单独的工作线程进行 TRIM，这将能改善提交延迟。

有关启用和使用 TRIM 的更多信息，请参阅 Solid State Drives#TRIM。

## 使用

### 交换文件

自 Linux 内核版本 5.0 起 Btrfs 提供 交换文件 支持 [7]。 创建交换文件的正确方法是首先创建一个非快照子卷以存储文件，然后使用 chattr 为该文件夹设置 `NO_COW` 参数以禁用写时复制。

    # chattr +C /path/to/swapsubvolume

从现在开始，在该子卷内所创建的文件都会被设置上 `NO_COW` 参数。

接下来，按照 Swap (简体中文)#交换文件 中的步骤操作以创建交换文件。Power_management/Suspend_and_hibernate#休眠到 Btrfs 上的交换文件中 一节中则已交代了休眠到交换文件的配置方法。

注意： 对于内核版本 5.0+, Btrfs 有原生但带些许限制的交换文件支持：

- 交换文件不可以放在快照子卷上。正确的过程是创建一个新子卷来存放交换文件。
- Btrfs 不支持跨多设备文件系统上的交换文件。参见 Btrfs wiki: Btrfs 支持交换文件吗？(英文) 和 Arch 论坛上的讨论 (英文)。

警告： Linux 内核 5.0 之前的版本不支持交换文件。在 5.0 之前的内核版本上搭配 Btrfs 使用交换文件可导致文件系统损坏。

### 显示已使用的/空闲空间

像 `df` 这样的用户空间工具可能不会准确的计算剩余空间 (因为并没有分别计算文件和元数据的使用情况) 。推荐使用 `btrfs filesystem usage` 来查看使用情况。比如说：

    # btrfs filesystem usage /

注意： `btrfs filesystem usage` 在 `RAID5/RAID6` 设备上可能无法正常工作。

请参阅 [8] 以获取更多信息。

### 碎片整理

Btrfs 支持通过配置挂载参数 `autodefrag` 来实现在线的碎片整理，参见 btrfs(5) § MOUNT OPTIONS 。要手动整理你的根目录的话，可以使用：

    # btrfs filesystem defragment -r /

使用不带 `-r` 开关的上述命令将导致仅整理该目录的子卷所拥有的元数据。这允许通过简单地指定路径进行单个文件碎片整理。

警告： 对具有 CoW 副本（快照副本或使用`cp --reflink`或 bcp 创建的文件）进行碎片整理以及使用带压缩算法的 `-c` 开关进行碎片整理可能会导致生成两个不相关的文件从而大幅增加磁盘使用量。

### RAID

Btrfs 提供对 RAID 一类的 #多设备文件系统的原生支持.参阅 the Btrfs wiki page 获得更多信息. Btrfs 管理员手册 提供了技术背景信息.

警告： 奇偶校验 RAID（RAID 5/6）代码中存在多个严重的数据丢失错误。 检查 Btrfs Wiki 的 RAID5/6 页面 (英文) 和 BUG 汇报 (linux-btrfs 邮件列表 (英文)) 以获取更多信息。2020 年 6 月, 有人提出了一个 通俗易懂的现存问题列表 (英文) 和一个 有用的恢复指南 (英文)。

### 检修 (Scrub)

Btrfs Wiki 术语表中写到，Scrub 是一种 "在线文件系统检查工具"。它能读取文件系统中的文件和元数据，并使用校验值和 RAID 存储上的镜像区分并修复损坏的数据。

警告： 运行 scrub 会阻止系统待机, 详见 这个讨论。

#### 手动启动

启动一个（后台运行的）包含 `/` 目录的文件系统在线检查任务：

    # btrfs scrub start /

检查该任务的运行状态：

    # btrfs scrub status /

#### 通过服务或者定时器启动

btrfs-progs 软件包带有 `btrfs-scrub@.timer` 系统单元，用来每月运行 scrub 命令。通过添加挂载点的参数来启用它，例如`btrfs-scrub@-.timer` (`/`) 或者 `btrfs-scrub@home.timer` (`/home`).

也可以通过启动 `btrfs-scrub@.service` 来手动运行 scrub (使用同样的挂载点参数)，相较 (以 root 用户身份运行) `btrfs scrub`，这么做的优点是会记录在 Systemd 日志中。

### 数据平衡 (Balance)

“Balance 将会通过分配器再次传递文件系统中的所有数据。它主要用于在添加或删除设备时跨设备重新平衡文件系统中的数据。如果设备出现故障，余额将为冗余 RAID 级别重新生成缺失的副本。”[9]。参阅 上游的 FAQ.

在单设备文件系统上，余额对于（临时）减少分配但未使用（元）数据块的数量也是有用的。有时候这对于解决 "filesystem full" 故障 来说也是必须的。

    # btrfs balance start /
    # btrfs balance status /

### 快照

"快照是和特定子卷共享文件和元数据的特殊子卷, 利用了 btrfs 的写时复制特性." 详见 Btrfs Wiki SysadminGuide#Snapshots.

要创建一个快照:

    # btrfs subvolume snapshot source [dest/]name

`source`为要创建快照的对象，`[dest/]name`为快照安放路径。

加入 `-r` 参数可以创建一个只读快照. 为只读快照创建一个快照可以获得一个只读快照的可写入版本.

注意： 快照不是递归包含的，这意味着子卷内的子卷在快照里是空目录。

### 发送和接收

可以通过 `send` 命令发送一个快照,通常会与 btrfs 中的 `receive` 组成管道.例如将快照 `/root_backup` (也许是`/`的备份) 发送到 `/backup`:

     # btrfs send /root_backup | btrfs receive /backup

只能发送只读快照,上面的命令在将子卷复制到外部设备 (例如备份驱动器) 时会很有用.

也可以只发送两个快照间发生变化的部分,例如如果你已经发送了快照 `root_backup` ,然后又建立了一个新的只读快照 `root_backup_new` ,可以这样完成增量发送:

     # btrfs send -p /root_backup /root_backup_new | btrfs receive /backup

现在你 `/backup` 的快照会是 `root_backup_new`.

参阅 Btrfs Wiki 上关于增量备份的页面 (英文) 获得更多信息 (例如使用工具自动化这一过程)。

### 去重

使用写时复制，Btrfs 能够复制文件或整个子卷而无需实际复制数据。但是，无论何时更改文件，都会创建一个新的“真正的”副本。重复数据删除更进一步，通过主动识别共享公共序列的数据块并将它们组合到具有相同写时复制语义的范围内。

专用于 Btrfs 分区去重的工具包括 duperemove，bedupAUR 和 btrfs-dedup。人们可能还希望仅使用基于文件的级别对数据进行重复数据删除，比如 rmlint、jdupesAUR 或者 dduper-gitAUR。有关这些程序的可用功能的概述和其他信息，请参阅 上游 Wiki 条目 (英文)。

此外，Btrfs开发人员正致力于带内（也称为同步或内联）重复数据删除，这意味着在将新数据写入文件系统时完成重复数据删除。目前，它仍然是一个在 out-of-tree 开发的实验。愿意测试新功能的用户可以阅读相关的内核 Wiki 页 (英文)。

## 已知问题

一些在尝试之前应该知道的限制。

### 加密

Btrfs 目前还没有内建的加密支持，但未来可能加入此功能。可以在运行`mkfs.btrfs`前加密分区，参阅Dm-crypt with LUKS.

(如果已经创建了文件系统，可以使用EncFS或TrueCrypt,但是这样会无法使用 btrfs 的一些功能。)

### 检查 btrfs 文件系统问题

`btrfs check` 工具目前有一些已知问题，在继续深入阅读了解之前，您不应该直接运行它, 参见 #检查 Btrfs 文件系统 小节。

## 提示和技巧

### 无分区 Btrfs 磁盘

警告： 大多数用户不希望这种类型的设置，应该在常规分区上安装 Btrfs。 此外，GRUB 强烈建议不要安装到无分区磁盘。请考虑为 mkfs.btrfs 使用 `--alloc-start` 参数以留出更大空间给 GRUB。

Btrfs 能应用到整个设备上，替代 MBR 或 GPT 分区表，但是并不要求一定这么做，最简单的方法是 在一个已存在的分区上创建 Btrfs 文件系统。 如果选择用 Btrfs 替代分区表, 可以用 #子卷 模拟不同的分区。下列是在单个无分区设备上使用 Btrfs 文件系统的限制:

- 不能在同一磁盘上的不同分区上放置其它的 文件系统。
- 如果使用 5.0 之前版本的 Linux 内核，则不能使用 交换区，因为 Btrfs 在 5.0 前不支持 交换文件，并且也无处创建 交换分区。
- 不能使用 UEFI 启动。

运行下面的命令把整个设备的分区表替换成 Btrfs:

    # mkfs.btrfs /dev/sdX

如果设备上存在分区表，则需要使用：

    # mkfs.btrfs -f /dev/sdX

例如 `/dev/sda` 而不是 `/dev/sda1`。后一种形式会格式化现有的分区而不是替换掉原有的分区表。由于根分区是 Btrfs 文件系统，请确保已将 `btrfs` 编译进内核, 或者将 `btrfs` 放入 mkinitcpio.conf#MODULES 中并且 重新生成 initramfs。

像使用普通的 MBR 分区表存储设备一样安装 启动管理器, 参考 Syslinux#Manual install 或 GRUB/Tips and tricks#Install to partition or partitionless disk。 如果你的内核因为 `Failed to mount /sysroot.` 错误无法启动, 请在 `/etc/default/grub` 里添加 `GRUB_PRELOAD_MODULES="btrfs"` 并生成 GRUB 配置文件 (GRUB#Generate the main configuration file)。

### 从 Ext3/4 转换

警告： 到 2015 年中后期，Btrfs 的邮件列表中报告了多起转换失败的案例。尽管近期的更新可能有所修复，但还是建议谨慎使用。在开始之前请确定您有可用的备份并且愿意承担丢失数据的风险。 详见 Btrfs Wiki:从 Ext3 文件系统转换 (英文)。
警告： 5.6.1 及之前版本的 btrfs-progs 有一个 Bug，它会导致生成的 Btrfs 文件系统的最后一块组 (last block group) 含有大小错误。得益于 这个 commit，这个 Bug 已经在 5.7 版本中修复。请在 5.7-1 及以上版本的 btrfs-progs 上使用 `brtfs-convert` 功能。

从安装 CD 启动，然后转化分区:

    # btrfs-convert /dev/partition

挂载转换后的分区并修改 `/etc/fstab` 文件，指定分区类型 (type 为 btrfs，并且 fs_passno[最后一列] 要修改为0，因为 Btrfs 在启动时并不进行磁盘检查)。 还要注意的是分区的 UUID 将有改变，所以使用 UUID (指定分区) 时，请更新 fstab 中相应的条目。 `chroot` 到系统并重建 GRUB 条目（如果对此过程不熟悉，参考从现有 Linux 系统安装 和 GRUB 中的相应内容)。 如果正在转换根目录，还需要在 chroot 环境中重建初始化内存盘 (`mkinitcpio -p linux`)。 如果 GRUB 不能启动 (例如有 'unknown filesystem' 错误)，则需要重新安装 (`grub-install /dev/partition`) 并重新生成配置文件 (`grub-mkconfig -o /boot/grub/grub.cfg`)。

注意： 如果转换过程中有任何异样，不管是无法挂载新转换的 Btrfs 文件系统或是无法往其中写入数据，只要备份子卷 `/ext2_saved` 还在，就可以进行回滚。请使用 `btrfs-convert -r /dev/partition` 命令进行回滚，这将会丢弃任何对新转换 Btrfs 文件系统的更改。

确认没有问题后，通过删除 `ext2_saved` 备份子卷完成转换的最后一步。请注意，如果没了它 (备份子卷)，你将没办法还原回 ext3/4 文件系统。

    # btrfs subvolume delete /ext2_saved

最后通过 Balance 回收空间。

### 校验和 (Checksum) 硬件加速

CRC32 是英特尔 (Intel) SSE4.2 中的新指令。要验证 Btrfs 校验和是否有硬件加速：

    # dmesg | grep crc32c

    Btrfs loaded, crc32c=crc32c-intel

如果你看到的是 `crc32c=crc32c-generic`，则很有可能是因为您根分区是 Btrfs，并且您须要之后将 `crc32c-intel` 编译进内核中才能使其正常生效。单纯将 `crc32c-intel` 放入 mkinitcpio.conf 是 不会 生效的。

### 损坏恢复

警告： `btrfs check` 工具有一些已知问题，参见 #检查 Btrfs 文件系统 小节。

btrfs-check 不能在一个已挂载的文件系统上工作。为了能够在不从 Live USB 启动的情况下使用 btrfs-check，需要将其添加到初始内存盘：

    /etc/mkinitcpio.conf

    BINARIES=("/usr/bin/btrfs")

然后 重新生成 initramfs。

之后如果启动时出现问题，则可以使用该实用程序进行修复。

注意： 如果 fsck 进程必须使空间缓存 (和/或其他缓存？) 无效 (invalidate cache)，那么随后的引导会挂起一段时间，这是正常的（进程可能会给出关于 btrfs-transaction 挂起的控制台消息）。系统应该在一段时间后从中恢复正常。

查阅 Btrfs Wiki 的 Btrfsck 页 以获取更多信息。

### 引导进入快照

要引导进入快照，因为快照可以像子卷那样被挂载，所以请像挂载子卷为根分区那样进行同样的流程 (已交代于#挂载子卷为根挂载点的一段中)。

如果使用 GRUB，则可以在 grub-btrfs 或 grub-btrfs-gitAUR 的帮助下，在重新生成配置文件时使用 Btrfs 快照自动填充启动菜单。

### 搭配 systemd-nspawn 使用 Btrfs 子卷

可查阅 Systemd-nspawn#Use Btrfs subvolume as container root 和 Systemd-nspawn#Use temporary Btrfs snapshot of container 等文章。

## 疑难解答

请查阅 Btrfs 常见问答集（英文） 以获得排除一般问题的信息。

### GRUB

#### 分区偏移

注意： 当您试图将 `core.img` 嵌入到已分区磁盘上时，可能会发生偏移问题。这意味着可以将 GRUB 的 `corg.img` 直接嵌入到无分区磁盘 (例如 `/dev/sdX`) 上的 Btrfs 存储池中。

GRUB 2 可以引导启动 Btrfs 分区，但是因为模块比其它文件系统大，grub-install 生成的 core.img 文件超过了 MBR 与第一个分区之间的空间大小 (63 扇区/31.5KiB)。最新版的 `fdisk` 和 `gdisk` 等磁盘工具会通过第一个分区前空出 1-2MiB 的空间来避免此问题。

#### Missing root

The factual accuracy of this article or section is disputed.

Reason: Suggests editing a non-configuration file manually. (Discuss in Talk:Btrfs#Should not suggest to edit files in /usr/share)

Users experiencing the following: `error no such device: root` when booting from a RAID style setup then edit /usr/share/grub/grub-mkconfig_lib and remove both quotes from the line `echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"`. Regenerate the config for grub and the system should boot without an error.

### 挂载超时

有时（尤其在大型 RAID1 阵列上）系统启动时会出现挂载超时的现象，并带有如下日志信息：

    Jan 25 18:05:12 host systemd[1]: storage.mount: Mounting timed out. Terminating.
    Jan 25 18:05:46 host systemd[1]: storage.mount: Mount process exited, code=killed, status=15/TERM
    Jan 25 18:05:46 host systemd[1]: storage.mount: Failed with result 'timeout'.
    Jan 25 18:05:46 host systemd[1]: Failed to mount /storage.
    Jan 25 18:05:46 host systemd[1]: Startup finished in 32.943s (firmware) + 3.097s (loader) + 7.247s (kernel)>
    Jan 25 18:05:46 host kernel: BTRFS error (device sda): open_ctree failed

这可以通过 fstab 中特定的 systemd 挂载选项 `x-systemd.mount-timeout` 提供系统以更长的超时时间来轻松解决。例如：

    /dev/sda                /storage    btrfs       rw,relatime,x-systemd.mount-timeout=5min  0 0

### 出现 BTRFS: open_ctree failed 错误

截至 2014 年 11 月，一个似乎存在于 systemd 或 mkinitcpio 中的 Bug 可能会导致在 `mkinitcpio.conf` 中使用 `btrfs` 钩子（hook）的用户在启动多设备文件系统的 Btrfs 卷时遇到以下错误：

    BTRFS: open_ctree failed
    mount: wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error

    In some cases useful info is found in syslog - try dmesg|tail or so.

    You are now being dropped into an emergency shell.

一种解决办法是，从 `HOOKS` 中将 `btrfs` 移入 `MODULES` 中，然后通过 `mkinitcpio -p linux` 命令重新生成 initramfs 并重新启动。

请查阅 原论坛讨论 和 FS#42884 获得更多的讨论内容和信息。

另外，如果在挂载 RAID 卷组缺少某个卷时，也有可能会发生这个错误。这种情况下，需要把 `degraded` 加入到 `/etc/fstab` 中；如果根目录在卷组上，需要同时加入内核参数 `rootflags=degraded`。

接上文，截至 2016 年 8 月，针对这一问题，一个可能的解决方案是在 `/etc/fstab` 中仅靠单个硬盘来挂载阵列，然后让 Btrfs 自动发现并追加其它硬盘。UUID 和 LABEL 等基于组的标识符似乎是导致出现错误的原因。比如说，由“disk1”（磁盘 1） 和“disk2”（磁盘 2）组成的双设备 RAID1 阵列会被分配到一个 UUID。但是请在 `/etc/fstab` 中只使用 `/dev/mapper/disk1` 来指定磁盘阵列，而不要使用 UUID。更多解释，参见这个博客文章。

另一个可能的解决方法是在 mkinitcpio.conf 中移除 `udev` 钩子并替换为 `systemd` 钩子。此时 `btrfs` 不应出现在 `HOOKS` 或 `MODULES` 列表中。

### 检查 Btrfs 文件系统

警告： Btrfs（特别是 `btrfs check` 命令工具）仍处在大开发阶段，强烈建议在加上 `--repair` 参数运行 `btrfs check` 前先做一个备份，并提前阅读 Btrfsck 文档（英文）。

btrfs check 可以检查并修复一个未挂载的 Btrfs 文件系统。但是由于它尚未开发完成，它并不能修复某些错误（即使这些错误没有导致无法挂载的情况发生）。

## 另请参阅

- 官方网站
  - Btrfs Wiki
  - Btrfs Wiki Glossary
- 官方常见问答
  - Btrfs Wiki FAQ
  - Btrfs Wiki Problem FAQ
- Btrfs 拉取请求（Pull Requests）
  - 3.14
  - 3.13
  - 3.12
  - 3.11
- 性能相关
  - Btrfs on raw disks?
  - Varying leafsize and nodesize in Btrfs
  - Btrfs support for efficient SSD operation (data blocks alignment)
  - Is Btrfs optimized for SSDs?
  - Phoronix 的挂载选项测试
    - Linux 3.14
    - Linux 3.11
    - Linux 3.9
    - Linux 3.7
    - Linux 3.2
  - Lzo vs. zLib
- 杂项
  - Funtoo:BTRFS Fun
  - Avi Miller presenting Btrfs at SCALE 10x, January 2012.
  - Summary of Chris Mason's talk from LFCS 2012
  - Btrfs: stop providing a bmap operation to avoid swapfile corruptions 2009-01-21
  - Doing Fast Incremental Backups With Btrfs Send and Receive

Category:

- File systems (简体中文)

Hidden category:

- Pages or sections flagged with Template:Accuracy