文件系统
根据维基百科:
- 文件系统控制数据的读和写。如果没有文件系统,储存介质里的信息就会变成一块无法理解的数据。通过把数据分块、命名,不同的信息就可以被隔离、分辨。每组数据被命名为“文件”是取自纸质信息系统的命名方式。而“文件系统”是指用于管理信息的分组和命名的结构和逻辑规则。
文件系统有很多,每个磁盘分区可以而且只可以使用其中的某一个。每种文件系统有自己的优缺点和独有特性。以下内容是目前所支持的文件系统类型的概述,相应的链接会提供更加详细的信息。
文件系统类型[编辑 | 编辑源代码]
filesystems(5) 包含一个简单介绍,详细比较参考 Wikipedia:Comparison of file systems。内核已经加载和内置的文件系统可以通过 /proc/filesystems
查看。通过 ls /lib/modules/$(uname -r)/kernel/fs
可以查看所有的内核模块。
文件系统 | 创建命令 | 内核补丁 | 用户空间工具 | 说明 |
---|---|---|---|---|
APFS | mkapfs(8) | linux-apfs-rw-dkms-gitAUR | apfsprogs-gitAUR | macOS (10.13 和更新) 文件系统,只读,实验版本. |
Bcachefs | bcachefs(8) | linux-bcachefs-gitAUR | bcachefs-tools-gitAUR | |
Reiser4 | mkfs.reiser4(8) | reiser4progsAUR | ||
ZFS | zfs-linuxAUR, zfs-dkmsAUR | zfs-utilsAUR | OpenZFS port |
文件系统日志[编辑 | 编辑源代码]
以上除了 ext2 、FAT16/32(即VFAT)、Reiser4(可选开启)、Btrfs 和 ZFS 以外的文件系统都使用文件系统日志。文件系统日志通过在数据更改写入储存设备前把变更写入日志来提供故障恢复能力。当出现系统崩溃或电源故障的时候,这些文件系统能够更快的恢复到可用状态,并且在恢复过程中更不容易出现错误。日志活动在文件系统中专用的一部分空间里进行。
并非所有的日志技术都相同。ext3 和 ext4 提供 data-mode journaling,同时记录数据本身和元数据(也有可以只记录元数据变化)。这个模式对性能影响很大,默认是禁用的。
与此类似,Reiser4 的名为 "transaction models" 的模式不仅改变了它所提供的功能,也改变了它的日志模式。这种日志记录模式使用了特别的日志技术,wandering logs,来确定使用哪种写入策略:写入储存器两次; write-anywhere,纯粹的 copy-on-write(和 btrfs 的类似,不过用的是另一种树设计);hybrid,在前两种之间智能切换。
其它文件系统提供仅提供记录元数据日志的 ordered-mode journaling。尽管都能在崩溃后将文件系统恢复到正常状态,data-mode journaling 提供了最大程度的数据安全防护,但代价是性能有所降低,因为数据会被写两次(第一次到日志,第二次到磁盘)——而 Reiser4 通过 “wandering logs" 避免了这样的重复。可以根据数据的重要性选择文件系统。
Reiser4 是仅有的被设计成所有的操作都是完全 atomic 的同时还提供元数据和内联数据的校验和的文件系统——文件操作要么完全完成,要么就根本没有发生,所以不会因为操作执行到一半而导致数据损坏。因此它发生数据丢失的可能性相比其他文件系统要低得多。
基于 copy-on-write (也叫 write-anywhere)的文件系统,比如Reiser4、Btrfs 和 ZFS 不需要用传统的日志保护元数据,因为元数据永远不会被原地更新。虽然 Btrfs 还在使用日志树,但这个树仅仅是为了加快 fdatasync/fsync 的速度。
基于 FUSE 的文件系统[编辑 | 编辑源代码]
参考 FUSE。
堆栈式文件系统[编辑 | 编辑源代码]
- eCryptfs — The Enterprise Cryptographic Filesystem,一个 Linux 磁盘加密软件。它被设计为与POSIX兼容的文件系统级加密层,目标是在操作系统级别提供类似 GnuPG 的功能。
- mergerfs — 基于 FUSE 的联合文件系统。
- mhddfs — 多机械硬盘 FUSE 文件系统, 基于 FUSE 的联合文件系统。
- http://mhddfs.uvw.ru || mhddfsAUR
- overlayfs — OverlayFS 是为 Linux 设计的联合文件系统服务,实现了联合挂载其他文件系统的功能。
- Unionfs:为 Linux、FreeBSD and NetBSD 设计的文件系统服务, 实现了联合挂载其他文件系统的功能。[5]
- unionfs-fuse — Unionfs 的用户空间实现.
只读文件系统[编辑 | 编辑源代码]
- SquashFS — SquashFS 是一个压缩的只读文件系统,它压缩文件、inodes和目录,而且最高支持 1 MB 大小的 block 来实现更强力的压缩。
集群文件系统[编辑 | 编辑源代码]
- Ceph — 统一的分布式存储系统,旨在实现出色的性能,可靠性和可扩展性。
- https://ceph.com/ || cephAUR
- Glusterfs — 支持扩展到几PB的集群文件系统。
- IPFS — 一种点对点超媒体协议,使网络更快,更安全,更开放。 IPFS旨在取代HTTP并为我们所有人构建更好的网络。 它使用 block 来存储文件的一部分,每个网络节点仅存储它感兴趣的内容,提供去重的、分布式的可扩展文件系统。 (alpha阶段)
- https://ipfs.io/ || kubo包
- MooseFS — MooseFS 是一个容错、高可用性和高性能的向外扩展的扩展网络分布式文件系统。
- OpenAFS — AFS分布式文件系统的开源实现
- OrangeFS:OrangeFS 是一个向外扩展的网络文件系统,为透明、并行地访问基于多个服务器的磁盘储存而设计。它为并行分布式应用提供了优化的 MPI-IO。它使 Linux 客户端、Windows、Hadoop 和 WebDAV 使用并列储存器变得简便。它与POSIX兼容,而且是 Linux kernel (4.6+)的一部分。[6]
- Sheepdog:用于卷和容器服务的分布式对象存储系统,能智能地管理磁盘和节点。[7]
- Tahoe-LAFS — Tahoe Least-Authority Filesystem 是一个免费、开放、安全、去中心化、容错、点对点的分布式 data store 和分布式文件系统。
查看现有文件系统[编辑 | 编辑源代码]
用 lsblk 查看:
$ lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT sdb └─sdb1 vfat Transcend 4A3C-A9E9
如果文件系统存在,那 FSTYPE
列会显示它的名字;如果它被mount了,挂载点会显示在 MOUNTPOINT
那一列。
创建文件系统[编辑 | 编辑源代码]
文件系统可以创建在一个分区上、逻辑容器如 LVM,RAID,或者 dm-crypt 上或普通文件上(参考 Loop设备)。这里描述创建在分区上的情况。
- 创建新文件系统之后,之前存放在该分区的数据会丢失且通常无法找回。请备份所有要保留的数据.
- 某个分区用来干什么通常会限制能用什么文件系统,比如 EFI分区 就只能用
mkfs.vfat
创建的 FAT32,而包含/boot
的分区的文件系统要考虑 boot loader 是否支持。
创建文件系统之前,目标分区必须处于未挂载状态。如果你要格式化的分区包含了一个已挂载的文件系统,在 lsblk 命令的 MOUNTPOINT 列中可以看到它。
$ lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT sda ├─sda1 C4DA-2C4D ├─sda2 ext4 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 /mnt └─sda3 56adc99b-a61e-46af-aab7-a6d07e504652
你可以使用 umount 加上分区的挂载点来卸载这个文件系统:
# umount /mountpoint
查看挂载了的所有文件系统,参考#列出挂载的文件系统。
用 mkfs(8) 创建新的文件系统,类型参见#文件系统类型。如果安装了其他特殊的工具,按照它们的说明来做。比如,以下命令在 /dev/sda1
上创建了一个 ext4 文件系统:
# mkfs.ext4 /dev/sda1
此外,你可以使用 mkfs
。这是 mkfs.fstype
工具的统一入口。上面的命令等价于:
# mkfs -t ext4 /dev/sda1
- 用
mkfs.ext4
的时候可以用-L
选项来给文件系统设置一个 标签。e2label
用来对已经存在的文件系统改标签。 - 文件系统在创建之后是有条件地 改变大小(resized)的。比如 XFS 可以扩容,但是不能缩小。参考 Resize capabilities。
创建完成之后新的文件系统就可以挂载到某个目录了。
挂载文件系统[编辑 | 编辑源代码]
如果要手动挂载一个设备上的文件系统到某个目录,用 mount(8)。下面这个例子把 /dev/sda1
挂载到 /mnt
:
# mount /dev/sda1 /mnt
挂载之后,在 /mnt
下面就能看见 /dev/sda1
里面的内容。挂载之前 /mnt
文件夹里的内容在挂载之后将会变得不可见,直到 unmount 掉 /dev/sda1
。
fstab 描述了如果某个设备存在的话系统应该怎么自动挂载它。如果要修改 /etc/fstab
,请阅读 fstab。
如果 /etc/fstab
里描述了一个设备的挂载参数,而用 mount
时只给了设备名字或者挂载点,fstab 里的参数就会自动补上。比如,/etc/fstab
里指示 /dev/sda1
应该挂载到 /mnt
,那下面的命令就会把 /dev/sda1
挂载到 /mnt
,即使你没有显式指明:
# mount /dev/sda1
或者
# mount /mnt
mount 接受很多参数,这些参数依赖于文件系统是否支持。要改变这些参数的话,可以通过以下形式:
列出挂载的文件系统[编辑 | 编辑源代码]
用 findmnt(8) :
$ findmnt
findmnt 支持很多参数,可以利用它们来筛选输出或者获得更多信息。比如把某个挂载点或者设备作为参数,它就会只输出这个下面挂载了什么。
$ findmnt /dev/sda1
findmnt 从 /etc/fstab
、/etc/mtab
和 /proc/self/mounts
文件里收集信息。
卸载文件系统[编辑 | 编辑源代码]
用 umount(8) 来卸载文件系统。参数可以是包含文件系统的设备(比如/dev/sda1
),也可以是挂载点(比如/mnt
):
# umount /dev/sda1
或者
# umount /mnt