# 3.6.磁盘结构

FreeBSD 用于查找文件的最小组织单位是文件名。文件名是区分大小写的，这意味着 `readme.txt` 和 `README.TXT` 是两个不同的文件。FreeBSD 不使用文件的扩展名来判断该文件是程序、文档还是其他数据类型。

文件存储在目录中。一个目录可以没有文件，也可以包含成百上千的文件。一个目录还可以包含其他目录，从而形成一个层次化的目录结构，以组织数据。

通过给出文件或目录的名称，后跟一个正斜杠 `/`，再加上必要的其他目录名称来引用文件和目录。例如，如果目录 `foo` 中包含目录 `bar`，而 `bar` 中包含文件 `readme.txt`，该文件的完整名称或路径是 `foo/bar/readme.txt`。请注意，这与 Windows® 使用反斜杠 `\` 分隔文件和目录名称不同。FreeBSD 的路径中不使用驱动器字母或其他驱动器名称。例如，在 FreeBSD 中不会输入 `c:\foo\bar\readme.txt`。

## 3.6.1. 文件系统

目录和文件存储在文件系统中。每个文件系统在最顶层包含一个根目录，称为该文件系统的 *根目录*。该根目录可以包含其他目录。一个文件系统被指定为 *根文件系统*，即 `/`。每个其他文件系统都被 *挂载* 到根文件系统下。无论 FreeBSD 系统上有多少磁盘，每个目录都看起来是同一个磁盘的一部分。

假设有三个文件系统，分别为 `A`、`B` 和 `C`。每个文件系统都有一个根目录，其中包含两个子目录，分别为 `A1`、`A2`（同样，`B` 包含 `B1`、`B2`，`C` 包含 `C1`、`C2`）。

将 `A` 作为根文件系统。如果使用 [ls(1)](https://man.freebsd.org/cgi/man.cgi?query=ls\&sektion=1\&format=html) 查看该目录的内容，会显示两个子目录，`A1` 和 `A2`。目录树如下所示：

![根目录和两个子目录的目录树](https://docs.freebsd.org/images/books/handbook/basics/example-dir1.png)

一个文件系统必须挂载到另一个文件系统中的目录上。当将文件系统 `B` 挂载到目录 `A1` 时，`B` 的根目录会替代 `A1`，并且 `B` 中的目录会相应显示出来：

![根目录和两个子目录的目录树](https://docs.freebsd.org/images/books/handbook/basics/example-dir2.png)

任何在 `B1` 或 `B2` 目录中的文件都可以通过路径 `/A1/B1` 或 `/A1/B2` 访问。任何原本在 `/A1` 中的文件现在暂时不可见。如果卸载 `B`，这些文件会重新出现。

如果 `B` 挂载到 `A2`，则目录树将如下所示：

![根目录和两个子目录的目录树](https://docs.freebsd.org/images/books/handbook/basics/example-dir3.png)

相应的路径为 `/A2/B1` 和 `/A2/B2`。

文件系统可以互相叠加挂载。继续上面的例子，文件系统 `C` 可以挂载到 `B` 文件系统中的 `B1` 目录上，形成如下结构：

![复杂的目录树，根目录下有多个子目录](https://docs.freebsd.org/images/books/handbook/basics/example-dir4.png)

或者 `C` 也可以直接挂载到 `A` 文件系统下的 `A1` 目录中：

![复杂的目录树，根目录下有多个子目录](https://docs.freebsd.org/images/books/handbook/basics/example-dir5.png)

完全可以有一个大的根文件系统，而不需要创建其他文件系统。虽然这种方式有一些缺点，但也有一个优点。

多个文件系统的好处：

* 不同的文件系统可以有不同的 *挂载选项*。例如，根文件系统可以以只读方式挂载，防止用户不小心删除或编辑重要文件。将用户可写文件系统（如 `/home`）与其他文件系统分开，并以 *nosuid* 方式挂载，可以防止存储在文件系统中的可执行文件的 *suid*/*guid* 位生效，可能提高安全性。
* FreeBSD 会根据文件系统的使用情况自动优化文件布局。因此，包含许多小文件并频繁写入的文件系统会与包含较少大文件的文件系统有所不同的优化。将所有内容放在一个大文件系统中时，这种优化会失效。
* FreeBSD 的文件系统在断电时具有较强的鲁棒性。然而，在关键时刻的断电仍然可能损坏文件系统结构。通过将数据分布到多个文件系统中，系统更可能仍能启动，从而更容易从备份中恢复。

单一文件系统的好处：

* 文件系统是固定大小的。如果在安装 FreeBSD 时创建了一个特定大小的文件系统，可能会发现以后需要增大分区大小。这通常需要备份数据、重新创建文件系统并恢复数据，操作复杂。

> **重要**
>
> FreeBSD 提供了 [growfs(8)](https://man.freebsd.org/cgi/man.cgi?query=growfs\&sektion=8\&format=html) 命令，可以动态扩展文件系统的大小，从而消除这一限制。文件系统只能扩展到所在分区中的空闲空间。如果分区后面有空闲空间，则可以使用 [gpart(8)](https://man.freebsd.org/cgi/man.cgi?query=gpart\&sektion=8\&format=html) 扩展分区。如果该分区是虚拟磁盘上的最后一个分区，并且磁盘已扩展，则可以扩展该分区。

## 3.6.2. 磁盘分区

文件系统被包含在 *分区* 中。磁盘通过若干分区方案之一被划分为多个分区；参见 [手动分区](https://docs.freebsd.org/en/books/handbook/bsdinstall/#bsdinstall-part-manual)。较新的方案是 GPT；而基于传统 BIOS 的计算机使用的是 MBR。GPT 支持将磁盘划分为具有大小、偏移量和类型的分区。它支持大量的分区及其类型，并在可能的情况下推荐使用。GPT 分区在磁盘名后带有一个后缀，其中 `p1` 表示第一个分区，`p2` 表示第二个，依此类推。相比之下，MBR 仅支持较少数量的分区。在 FreeBSD 中，MBR 分区被称为 *切片（slice）*。切片可被不同操作系统使用。FreeBSD 的切片会使用 BSD 标签进一步划分为多个分区（参见 [bsdlabel(8)](https://man.freebsd.org/cgi/man.cgi?query=bsdlabel\&sektion=8\&format=html)）。

切片编号紧跟在设备名后，并以 `s` 为前缀，从 1 开始。例如 `da0*s1*` 表示第一个 SCSI 磁盘上的第一个切片。一个磁盘只能有四个物理切片，但可以在合适类型的物理切片内部建立逻辑切片。这些扩展切片从编号 5 开始，因此 `ada0*s5*` 是第一个 SATA 磁盘上的第一个扩展切片。这些设备被用于需要占据整个切片的文件系统。

每个 GPT 或 BSD 分区只能包含一个文件系统，因此文件系统通常通过它们在文件系统层级中的典型挂载点，或其所在的分区名称来描述。

FreeBSD 还会使用磁盘空间作为 *交换空间（swap space）* 以提供 *虚拟内存（virtual memory）*。这使得计算机的行为看起来像是拥有远超实际内存的容量。当 FreeBSD 内存耗尽时，它会将一部分当前未使用的数据移入交换空间，并在需要时将其移回（将其他内容移出）。这称为 *换页（paging）*。

一些 BSD 分区具有特定的惯例用法：

| 分区  | 惯例用途                                                             |
| --- | ---------------------------------------------------------------- |
| `a` | 通常包含根文件系统。                                                       |
| `b` | 通常用于交换空间。                                                        |
| `c` | 通常大小与所在的切片相同。这使得需要操作整个切片的工具（如坏块扫描器）可以作用于 `c` 分区。通常不会在该分区上创建文件系统。 |
| `d` | 分区 `d` 过去具有特殊含义，但现在已被视作普通分区使用。                                   |

切片和 “危险专用（dangerously dedicated）” 的物理磁盘包含 BSD 分区，使用从 `a` 到 `h` 的字母表示。这个字母会附加在设备名后，例如 `da0a` 表示第一个 `da` 磁盘（危险专用）的 `a` 分区。`ada1s3e` 则表示第二个 SATA 磁盘上第三个切片中的第五个分区。

最后，系统中的每个磁盘都有一个标识符。磁盘名称以表示磁盘类型的代码开头，后跟一个表示磁盘序号的数字。与分区和切片不同，磁盘编号从 0 开始。常见的代码列在下表中：

**表 3：磁盘设备名对照表**

| 驱动器类型             | 设备名称                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| SATA 与 IDE 硬盘     | `ada`                                                                                                                          |
| SCSI 硬盘与 USB 存储设备 | `da`                                                                                                                           |
| NVMe 存储           | `nvd` 或 `nda`                                                                                                                  |
| SATA 与 IDE 光驱     | `cd`                                                                                                                           |
| SCSI 光驱           | `cd`                                                                                                                           |
| 软盘驱动器             | `fd`                                                                                                                           |
| SCSI 磁带机          | `sa`                                                                                                                           |
| RAID 驱动器          | 示例包括 `aacd`（Adaptec® AdvancedRAID）、`mlxd` 和 `mlyd`（Mylex®）、`amrd`（AMI MegaRAID®）、`idad`（Compaq Smart RAID）、`twed`（3ware® RAID） |

**表 4：示例磁盘、切片与分区名**

| 名称        | 含义                                          |
| --------- | ------------------------------------------- |
| `ada0s1a` | 第一个 SATA 磁盘（`ada0`）上第一个切片（`s1`）中的第一个分区（`a`） |
| `da1s2e`  | 第二个 SCSI 磁盘（`da1`）上第二个切片（`s2`）中的第五个分区（`e`）  |

**示例 12：磁盘的概念模型**

下图展示了 FreeBSD 对系统中第一个 SATA 磁盘的视图。假设该磁盘大小为 250 GB，其中包含一个 80 GB 的切片和一个 170 GB 的切片（MS-DOS® 分区）。第一个切片包含一个 Windows® 的 NTFS 文件系统（`C:`），第二个切片则用于 FreeBSD 安装。本例中的 FreeBSD 安装包含四个数据分区和一个交换分区。

这四个分区各自包含一个文件系统。分区 `a` 用于根文件系统，`d` 用于 `/var/`，`e` 用于 `/tmp/`，`f` 用于 `/usr/`。分区字母 `c` 代表整个切片，因此不会用于常规分区。

![FreeBSD 与 Windows 共享磁盘的布局示意图](https://docs.freebsd.org/images/books/handbook/basics/disk-layout.png)
