译:Linux 文件系统介绍

2017-12-25 11:01:49来源:segmentfault作者:Tony_Zby人点击

分享
原文地址:https://opensource.com/life/1...
原翻译地址:http://www.tony-yin.top/2017/...

本文旨在对Linux文件系统概念进行深层次的讨论。本文既不准备对某个特定类型的文件系统(比如ext4)进行基础性的描述,也不打算作为一个讲解文件系统命令的教程。


每台通用的计算机都需要把各种类型的数据存储在硬盘驱动器(HDD)或者一些同样功能的设备上,比如USB。存储在这些设备上有几个原因,首先,RAM会在计算机电源关闭时丢失内容,虽然也有非易失性类型的内存,可以在电源关闭后维持数据存储不丢失(如flash内存也就是闪存使用的USB和固态硬盘),但flash内存要比一些标准的、挥发性的内存比如DDR3和其他类似的类型昂贵的多。


数据需要存储在硬盘驱动器上的第二个原因是,即使是标准的RAM也要比磁盘空间更昂贵。RAM和磁盘成本都在迅速下降,但如果按每字节的成本来算的话还是RAM更高。我们就基于16GB RAM和2TB硬盘的成本,快速计算其每个字节的成本,结果显示RAM比硬盘驱动器的价格高约71倍。目前,RAM的典型成本大约每字节0.0000000043743750。


更加直截了当说的话,在计算机的早期,一种内存是基于CRT屏幕上的点的,每一比特大约1美元,这是非常非常昂贵的!


定义

你也许会听到人们经常以不同的或者混淆的方式谈论文件系统这个词。这个词本身可能有多重含义,你可能需要从讨论或文档的语境中辨别真正的意思。


我将尝试根据我在不同情况下使用它的方式来定义“文件系统”的各种含义。注意,在试图遵循标准的“official”含义时,我的意图是根据它的各种用法定义术语。在本文后面的小节中,将更详细地讨论这些含义。

整个Linux目录结构从顶部(/)根目录开始。
各种特定类型的数据存储格式,如EXT3、EXT4、BTRFS、XFS等。Linux支持近100种类型的文件系统,包括一些非常古老的文件系统,以及一些最新的文件系统。每个文件系统类型都使用自己的元数据结构来定义如何存储和访问数据。
一个分区或被格式化为特定类型文件系统的逻辑卷,可以被挂载到Linux文件系统上的指定挂载点上。基本的文件系统功能

磁盘存储是必需的,它带来了一些有趣且不可避免的细节。显然,文件系统的设计目的是为数据的非易失性存储提供空间,这是它的最根本的功能。但是它还有许多其他重要的功能满足不同的需求。


所有文件系统都需要提供一个命名空间(namespace)——即一个命名和组织的方法。它定义了如何命名文件,具体来说是文件名的长度和可用于文件名的字符的子集,这些字符可以从全部字符集中获取。它还定义了磁盘上数据的逻辑结构,例如使用目录来组织文件,而不是将它们集中在一个单一的、巨大的文件集中。


一旦定义了名称空间,就需要一个元数据结构来为该名称空间提供逻辑基础。其中元数据包括支持分层目录结构所需的数据结构;用于确定磁盘上哪些块空间已经被使用和哪些可用的结构;允许维护文件和目录名称的结构;文件相关的信息,比如它们的大小和时间,比如创建时间、修改时间或最后访问时间等等;以及属于文件的数据在磁盘上面的位置。还有一些其他元数据用于存储关于磁盘划分的高级信息,如逻辑卷和分区。这个更高级别的元数据和它所代表的结构包含了描述存储在驱动器或分区上的文件系统的信息,这些元数据独立于上面提到的一般文件系统元数据。


文件系统还需要API接口为系统函数调用提供访问,这些系统函数调用操作文件和目录等文件系统对象。APIs提供诸如创建、移动和删除文件之类的接口。它还提供了一些算法来确定文件放置在文件系统上的位置。这些算法还有确定速度或最小化磁盘碎片等作用。


现代文件系统还提供了一个安全模式,它是一个为文件和目录定义访问权限的方案。Linux文件系统安全模式有助于确保用户只能访问他们自己的文件,而不是其他人或操作系统本身的文件。


最后的构建块是实现所有这些功能所需的软件。为了改提高系统和程序员效率,Linux使用了一种two-part的软件实现方式。


<center></center>
<center>图1:Linux two-part 文件系统软件实现方式</center>


这两部分实现的第一部分是Linux虚拟文件系统。这个虚拟文件系统为内核和开发人员提供了访问所有类型文件系统的一组命令。虚拟文件系统软件调用特定的设备驱动程序来连接到各种类型的文件系统。文件系统特定的设备驱动程序是实现的第二部分。设备驱动程序将文件系统命令的标准集根据特定分区或逻辑卷上的文件系统类型做转换和解释。


目录结构

作为一个通常很有条理的处女座,我喜欢把东西放在那些小而有组织的地方,而不是一个大的桶。使用目录可以帮助我存储和定位我想找的文件。目录也被称为文件夹,因为它们可以被看作实际生活中办公桌上保存文件的文件夹。


在Linux和许多其他操作系统中,目录可以以树状的层次结构来构造。Linux目录结构在Linux文件系统层次标准(FHS)中得到了很好的定义和记录。在访问它们时引用这些目录是通过使用由前斜杠(/)连接的顺序较深的目录名称(/)来实现的,例如/ var/ log和/ var/ spool/mail。这些被称为路径。


下表提供了一个非常简短的标准、众所周知的和定义在顶层上的Linux目录及其用途的列表。




































































目录描述

/ (根文件系统)

根文件系统是文件系统的顶级目录。它必须包含在其他文件系统安装之前启动 Linux 系统所需的所有文件。它必须包含引导其余文件系统所需的所有必需的可执行文件和库。在系统启动之后,所有其他文件系统都安装在标准的、定义良好的挂载点上,作为根文件系统的子目录。

/bin

bin目录包含用户可执行文件。

/boot

包含引导Linux计算机所需的静态引导加载程序和内核可执行文件和配置文件。

/dev

这个目录包含系统中每个硬件设备的设备文件。这些不是设备驱动程序,而是代表计算机上每个设备的文件,并方便访问这些设备。

/etc

包含主机的本地系统配置文件。

/home

/home目录用于用户存储文件。每个用户在/home目录下都有一个子目录。

/lib

包含引导系统所需的共享库文件。

/media

一个可以安装外部可移动媒体设备的地方,例如可以连接到主机的u盘驱动器。

/mnt

在管理员修复或处理文件系统时可以使用的常规文件系统(如不可移动媒体)的临时安装点。

/opt

可选的文件,如供应商提供的应用程序应该在这里。

/root

这不是根(/)文件系统。它是root用户的主目录。

/sbin

系统二进制文件。这些是用于系统管理的可执行文件。

/tmp

临时目录。用于操作系统和许多程序来存储临时文件。用户也可以临时存储文件。请注意,此处存储的文件可能在任何时间被删除,而无需事先通知。

/usr

这些是可共享的只读文件,包括可执行的二进制文件和库、man文件和其他类型的文档。

/var

变量数据文件存储在这里。这可以包括日志文件、MySQL和其他数据库文件、web服务器数据文件、电子邮件收件箱等等。

<center>表1:Linux文件系统层次结构的顶层</center>


表1中显示的目录及其子目录及其子目录的子目录,其中背景色为蓝色的目录被认为是根文件系统中不能缺少的组成部分。也就是说,它们不能作为单独的文件系统创建,并且在启动时安装。这是因为它们(特别是它们的内容)必须在引导时出现,以便系统正确引导。


/media和/mnt目录是根文件系统的一部分,但它们不应该包含任何数据。相反,它们只是临时的挂载点。
其余的目录,在表1中没有背景颜色的目录不需要在引导序列中出现,但是会在以后安装,在启动序列中准备主机来执行有用的工作。


可以通过参考官方的Linux文件系统层次标准(FHS)web页面,以了解这些目录及其许多子目录的详细信息。维基百科对FHS的描述也很好。应尽可能密切地遵循这一标准,以确保业务和职能的一致性。不管主机上使用的文件系统类型是什么,这个分层目录结构都是相同的。


Linux 统一目录结构

在一些非linux PC操作系统中,如果有多个物理硬盘或多个分区,每个磁盘或分区都被分配一个驱动器号。想定位到文件或程序所在的硬盘的位置,驱动器号是必需的,比如C:或D:。然后,以命令的形式发出驱动器字母D:例如,要更改到D:驱动器,然后使用cd命令更改到正确的目录来定位所需的文件。每个硬盘都有自己独立的和完整的目录树。


Linux文件系统将所有物理硬盘和分区统一到一个目录结构中。这一切都是从顶部(/)目录开始的。所有其他目录及其子目录都位于Linux根目录下。这意味着只有一个单独的目录树来搜索文件和程序。


它们之所以能工作,都是因为文件系统,如/home、/tmp、/var、/opt、/usr可以被创建在单独的物理硬盘上一个不同的分区,或一个不同的逻辑卷/(根)文件系统,然后安装在一个挂载点(目录)作为根文件系统树的一部分。即使是可移动的驱动器,如闪存盘或外部USB或ESATA硬盘驱动器也将安装到根文件系统中,并成为该目录树的一个不可分割的部分。


在从一个版本的Linux发行版升级到另一个版本,或者从一个发行版切换成到另一个发行版时,文件系统有一个很好的理由可以做到这一点。一般来说,除了Fedora的dnf升级之类的升级工具之外,偶尔重新格式化包含操作系统的硬盘驱动器是明智的,因为在升级过程中,硬盘驱动器会清除任何随时间积累的东西。如果/home是根文件系统的一部分,它将被重新格式化,然后必须从备份中恢复。通过将/home格式化为一个单独的文件系统,那么在根文件系统格式化时它将识别成一个单独的文件系统,并且可以跳过当前步骤。这也适用于数据库、电子邮件收件箱、网站和其他可变用户和系统数据存储的目录/var。


维护Linux目录树的某些部分作为单独的文件系统还有其他原因。例如,很久以前,当我还没有意识到围绕着所有需要的Linux目录都作为/(root)文件系统的一部分的潜在问题时,我曾用大量非常大的文件填充了我的主目录。由于/home目录和/tmp目录都不是独立的文件系统,而只是根文件系统的子目录,所以整个根文件系统都被填满了。操作系统没有空间创建临时文件或扩展现有的数据文件。起初,应用程序开始抱怨没有空间保存文件,然后操作系统本身开始变得非常奇怪。引导到单用户模式,并清除我的主目录中的问题文件,这让我可以重新开始。然后,我使用一个相当标准的多文件系统设置重新安装了Linux,并能够防止完全的系统崩溃再次发生。


我曾经还遇到过一个情况,Linux主机继续运行,但是阻止用户使用GUI桌面登录。我能够使用一个虚拟控制台本地使用命令行接口(CLI),并远程使用SSH。问题是,/tmp文件系统已经填满了,而GUI桌面所需的一些临时文件在登录时无法创建。由于CLI登录不需要在/tmp中创建文件,因此缺少空间并没有阻止我使用CLI进行登录。在这种情况下,/tmp目录是一个单独的文件系统,在卷组中有大量可用的空间,/tmp逻辑卷是其中的一部分。我只是将/tmp逻辑卷扩展到一个够大的容量(其实就是LVM扩容),以适应我对该主机所需要的临时文件空间数量的新需求,并解决了问题。请注意,此解决方案不需要重新启动,并且当/tmp文件系统被放大后,用户可以登录到桌面。


逻辑卷扩展也可以参考我之前总结的一篇文章,简洁明了:LVM动态扩展

另一种情况发生在我在一家大型科技公司做实验室管理员的时候。我们的一个开发人员在错误的位置(/var)安装了应用程序(我个人认为不能说是装在错误的位置,只能说装的位置的可用空间不合适)。应用程序崩溃是因为/var文件系统已经满了,而存储在/var/log/上的日志文件由于缺少空间,不能添加新的消息。但是,由于关键的/(root)和/tmp文件系统没有填充,系统仍然保持运行。删除违规应用程序并将其重新安装到/opt文件系统中解决了这个问题。(其实通过LVM动态扩容也是可以解决这个问题,要么扩展空间大小,要么换大空间的文件系统)


文件系统类型

Linux支持读取大约100个分区类型,它只可以在其中的几个而不是所有的分区上创建或写文件。但是,在同一个根文件系统上的不同类型的挂载文件系统是可以做到的,也是非常常见的。在此上下文中,我们讨论的是在硬盘或逻辑卷的分区上存储和管理用户数据所需的结构和元数据。这里提供了Linux fdisk命令识别的文件系统分区类型的完整列表,这样您就可以了解Linux与许多类型的系统之间的高度兼容性。


0 Empty 24 NEC DOS 81 Minix / old Lin bf Solaris 1 FAT12 27 Hidden NTFS Win 82 Linux swap / So c1 DRDOS/sec (FAT- 2 XENIX root 39 Plan 9 83 Linux c4 DRDOS/sec (FAT- 3 XENIX usr 3c PartitionMagic 84 OS/2 hidden or c6 DRDOS/sec (FAT- 4 FAT16 <32M 40 Venix 80286 85 Linux extended c7 Syrinx 5 Extended 41 PPC PReP Boot 86 NTFS volume set da Non-FS data 6 FAT16 42 SFS 87 NTFS volume set db CP/M / CTOS / . 7 HPFS/NTFS/exFAT 4d QNX4.x 88 Linux plaintext de Dell Utility 8 AIX 4e QNX4.x 2nd part 8e Linux LVM df BootIt 9 AIX bootable 4f QNX4.x 3rd part 93 Amoeba e1 DOS access a OS/2 Boot Manag 50 OnTrack DM 94 Amoeba BBT e3 DOS R/O b W95 FAT32 51 OnTrack DM6 Aux 9f BSD/OS e4 SpeedStor c W95 FAT32 (LBA) 52 CP/M a0 IBM Thinkpad hi ea Rufus alignment e W95 FAT16 (LBA) 53 OnTrack DM6 Aux a5 FreeBSD eb BeOS fs f W95 Ext'd (LBA) 54 OnTrackDM6 a6 OpenBSD ee GPT 10 OPUS 55 EZ-Drive a7 NeXTSTEP ef EFI (FAT-12/16/ 11 Hidden FAT12 56 Golden Bow a8 Darwin UFS f0 Linux/PA-RISC b 12 Compaq diagnost 5c Priam Edisk a9 NetBSD f1 SpeedStor 14 Hidden FAT16 <3 61 SpeedStor ab Darwin boot f4 SpeedStor 16 Hidden FAT16 63 GNU HURD or Sys af HFS / HFS+ f2 DOS secondary 17 Hidden HPFS/NTF 64 Novell Netware b7 BSDI fs fb VMware VMFS 18 AST SmartSleep 65 Novell Netware b8 BSDI swap fc VMware VMKCORE 1b Hidden W95 FAT3 70 DiskSecure Mult bb Boot Wizard hid fd Linux raid auto 1c Hidden W95 FAT3 75 PC/IX bc Acronis FAT32 L fe LANstep 1e Hidden W95 FAT1 80 Old Minix be Solaris boot ff BBT

拥有支持读取这么多分区类型的能力的主要目的是允许兼容性和与其他计算机系统的文件系统的某些互操作性。使用Fedora创建新文件系统时可用的选项如下所示。

btrfs
cramfs
ext2
ext3
ext4
fat
gfs2
hfsplus
minix
msdos
ntfs
reiserfs
vfat
xfs

其他发行版支持创建不同的文件系统类型。例如,CentOS 6只支持创建上面列表中粗体显示的文件系统。


挂载

在Linux中,to mount一词指的是早期的计算机中,当一个磁带或可移动的磁盘包需要在适当的驱动器上进行物理安装时。在物理上放置磁盘之后,磁盘包上的文件系统将由操作系统逻辑上挂载,以使操作系统、应用程序和用户能够访问这些内容。


挂载点仅仅是一个目录,就像任何其他的目录一样,它是作为根文件系统的一部分创建的。例如,home文件系统安装在目录/home上。文件系统可以安装在其他非根文件系统上的挂载点上,但这并不常见。
Linux根文件系统安装在根目录上(/)非常早的引导序列。其他文件系统会被安装在后面,由Linux启动程序,无论是在SystemV下的rc,还是在新的Linux版本中的systemd,在启动过程中挂载文件系统是由/ etc/fstab配置文件管理的。一个容易记住的方法是fstab表示“文件系统表”,它是要挂载的文件系统的列表,还有它们指定的挂载点,以及特定文件系统可能需要的任何选项。


文件系统安装在现有的目录(挂载点)上,使用mount命令。一般来说,任何被用作挂载点的目录都应该是空的,并且没有包含其中的任何其他文件。Linux不会阻止用户将一个文件系统安装到一个已经存在的文件系统上,或者在一个包含文件的目录上。如果你在现有的目录或文件系统上安装了一个文件系统,那么原始的内容将会被隐藏,只有新挂载的文件系统的内容才会可见。


结论

我希望本文能够把围绕“文件系统”这个术语的一些可能的混淆给理清楚。我花了很长时间才真正理解并理解Linux文件系统的复杂性、优雅和功能。


如果你有问题,请把它们加到下面的评论中,我会尽量回答。


下个月

另一个重要的概念是,对于Linux,一切都是文件。这个概念为用户和系统管理员提供了一些有趣且重要的实际应用程序。我之所以提到这一点,是因为您可能想在我下个月的/dev目录下的文章前阅读我的一切都是文件的文章。

微信扫一扫

第七城市微信公众平台