三、虚拟文件系统(Virtual File System)(VFS)
文件系统(File System)是一种用于在计算机存储设备上组织和管理文件和数据的方式。它提供了一种结构化的方法,使得计算机可以有效地存储、检索和管理文件。
文件系统通常包括以下几个方面的功能和特性:
文件和目录结构: 文件系统通过文件和目录的组织结构来管理数据。文件表示存储在设备上的数据单元,而目录用于组织和存储文件。
文件的命名规则: 文件系统定义了文件的命名规则,这包括文件名的长度、允许使用的字符类型等。文件名通常用于唯一标识文件。
存储和检索: 文件系统负责将文件存储在物理存储设备(如硬盘、固态硬盘、光盘等)上,并提供检索文件的机制。
权限和访问控制: 文件系统通常提供了对文件和目录的权限控制机制,确保只有授权用户能够访问、修改或删除文件。
文件系统元数据: 文件系统维护关于文件和目录的元数据,包括创建时间、修改时间、所有者信息等。元数据是文件系统的重要组成部分,用于管理文件的属性。
磁盘空间管理: 文件系统负责管理物理存储设备上的磁盘空间,包括分配和回收空间,以及处理文件的碎片化问题。
文件系统类型: 不同的文件系统采用不同的组织结构和算法,例如常见的文件系统类型包括FAT32、NTFS、ext4等。每种文件系统都有其自己的特性和优势。
容错和恢复: 一些文件系统具备容错和恢复机制,能够在发生错误或系统崩溃时,自动修复损坏的文件系统或数据。
网络文件系统(NFS): 文件系统还可以通过网络进行访问和共享,允许多台计算机之间共享文件。
文件系统是操作系统中一个关键的组成部分,提供了对数据的有序管理,使得用户和应用程序能够方便地存储、检索和操作文件。不同的操作系统支持不同的文件系统,但它们都遵循了类似的基本原则。
文件系统是操作系统用于组织和存储文件以及对文件进行管理的一种机制。它提供了一种结构化的方式,使得计算机系统能够有效地存储、检索和管理文件数据。
常规认知中,文件系统包括以下重要的概念:
根目录: 文件系统的最顶层目录,包含了所有其他目录和文件的起始点。在根目录下可以有多个子目录和文件。
目录: 文件系统中的目录类似于文件夹,用于组织和存储文件。目录可以包含其他子目录和文件。
文件: 文件是存储数据的基本单位。文件可以包含文本、图像、音频、视频等各种类型的数据。
路径: 文件系统中,每个文件和目录都有一个唯一的路径,用于描述其在文件系统中的位置。路径可以是绝对路径(从根目录开始的完整路径)或相对路径(相对于当前工作目录的路径)。
权限: 文件系统通常具有对文件和目录的访问权限控制机制,以确定哪些用户或系统进程可以执行特定操作(读、写、执行等)。
文件属性: 文件系统中的文件和目录可以具有各种属性,如创建时间、修改时间、大小等。
文件系统类型: 不同的操作系统支持不同类型的文件系统,例如,Linux 中常见的文件系统类型有 ext4、FAT32、NTFS 等。
挂载: 文件系统可以被挂载到操作系统的目录上,使得该文件系统中的文件和目录可以被访问。例如,在 Linux 中,可以将一个硬盘上的分区挂载到 /mnt
目录下。
文件系统的设计和实现可以有多种方式,取决于操作系统的要求和特性。它提供了一种有序的结构,使得用户和应用程序能够方便地组织和管理文件,同时提供了对文件的高效访问和存储。
文件系统有很多种类,每种都有其独特的特性和用途。以下是一些常见的文件系统类型:
FAT (File Allocation Table): FAT是一种简单而古老的文件系统,最早用于MS-DOS和Windows操作系统。它具有广泛的兼容性,但是在处理大容量磁盘和文件时效率相对较低。
VFAT (Virtual FAT): VFAT是对FAT的扩展,支持长文件名和其他改进。它主要用于支持Windows中的长文件名。
NTFS (New Technology File System): NTFS是Windows操作系统中常见的文件系统,具有高级的安全性、恢复性和性能特性。它支持大文件和大容量硬盘。
ext (Extended File System): ext是Linux操作系统系列中使用的文件系统。不同的版本有 ext1、ext2、ext3、ext4。每个版本都引入了新的特性,如日志文件系统(ext3和ext4),以提高稳定性和性能。
HFS (Hierarchical File System): HFS是苹果公司早期Macintosh计算机上使用的文件系统,后来演变为HFS+和APFS。HFS+用于较老的Mac系统,而APFS是Apple File System,用于最新的macOS。
Btrfs (B-Tree File System): Btrfs是Linux中的一种先进的文件系统,具有高级的快照、校验和、压缩等特性。
exFAT (Extended File Allocation Table): exFAT是一种用于闪存存储设备和大容量存储设备的文件系统,它是FAT32的扩展。
ZFS (Zettabyte File System): ZFS是一种先进的文件系统,最初由Sun Microsystems开发,用于Solaris操作系统。它具有强大的存储管理和数据完整性保护特性。
tmpfs: tmpfs是一种基于内存的文件系统,将文件存储在RAM中而不是磁盘上。它通常用于存储临时文件系统,对于需要快速访问的数据非常有用。
XFS: XFS是一种高性能的文件系统,最初由SGI(Silicon Graphics, Inc.)开发,用于UNIX系统。
在树莓派上使用 df -T
命令可以查看已挂载文件系统的类型。上述命令显示的文件系统类型中,vfat通常用于启动分区(boot),而ext4用于根目录等。
在计算机存储中,分区是指将物理硬盘划分为一个或多个逻辑单元,每个单元独立管理和使用。不同的操作系统和用途可能对分区有不同的需求和规划。
在Windows系统中,用户通常将硬盘分为不同的卷(Volume),每个卷可以对应一个分区。这些卷通常被赋予一个盘符(如C:\、D:\等),用户可以在每个卷上存储文件和应用程序。Windows用户更倾向于以卷为单位进行管理,而不太关心分区的细节。
在Linux系统中,分区的概念更为突出,而且按照功能和用途进行分区的做法更为普遍。常见的分区包括:
Bootloader 分区: 存放引导加载程序(Bootloader)的位置,这个分区通常比较小。
Parameter 分区: 用于存放启动代码向内核传递参数的位置。这个分区存储一些启动时需要的配置信息。
Kernel 分区: 存放操作系统内核的位置。内核是操作系统的核心部分,负责管理硬件和提供系统调用接口。
Root 分区: 根分区包含文件系统的根目录,也就是整个文件系统的起始点。在Linux中,根分区是文件系统的基础。
这种按照功能和用途划分的方式更有助于系统管理和维护。在嵌入式系统中,由于资源有限,对分区的合理规划变得尤为重要。每个分区在整个系统的启动、配置和运行过程中都有特定的作用。
文件系统目录结构是文件系统中用于组织和存储文件的一种层次化结构。在不同的操作系统中,文件系统目录结构可能有所不同。以下是常见的Linux文件系统目录结构:
根目录(/): 所有目录和文件的起始点。根目录包含了整个文件系统的基本结构。
/bin: 存放系统命令(二进制文件)的目录。这里包含了许多用户和系统都需要使用的基本命令,如ls
、cp
、mv
等。
/boot: 存放启动系统所需的文件,包括内核文件和引导加载程序(Bootloader)。
/dev: 包含设备文件,每个硬件设备在这个目录下都有相应的文件表示。
/etc: 存放系统配置文件的目录。这里包含了许多系统的配置文件,如网络配置、用户配置等。
/home: 用户的主目录。每个用户在这个目录下都有一个独立的子目录,用于存放个人文件和配置。
/lib和/lib64: 存放系统和应用程序所需的共享库文件。
/mnt: 用于挂载其他文件系统的临时挂载点。
/opt: 用于存放第三方软件的安装目录。
/proc: 虚拟文件系统,提供了内核和进程的信息,可以通过读取这里的文件获取系统状态。
/root: 超级用户(root)的主目录。
/sbin: 存放系统命令(二进制文件),与/bin类似,不过这里的命令通常是供超级用户使用的。
/tmp: 用于存放临时文件的目录。
/usr: 存放系统用户和系统管理器命令的目录,也包含了一些共享的系统资源。
/var: 存放经常变化的文件,如日志文件、缓存文件等。
这只是Linux系统中的典型目录结构,不同的Linux发行版可能会有些许差异。目录结构的设计旨在使系统文件有条理地分布在不同的目录下,方便用户和系统进行管理。
虚拟文件系统(Virtual File System,VFS)是操作系统中的一个抽象层,为不同的文件系统提供了一个统一的接口,使得用户和应用程序可以透明地访问各种不同类型的文件系统,而不用关心底层的实现细节。
在Linux等类Unix系统中,VFS的设计允许不同的文件系统(如ext4、FAT32、NTFS等)以插件的形式集成到操作系统中。这样,用户和应用程序可以使用相同的系统调用和接口来进行文件的读取、写入和管理,而无需关心文件系统的具体类型。
VFS 提供了一组标准的系统调用,如 open
、read
、write
、close
等,以及文件操作的标准接口,使得应用程序在不同的文件系统上能够保持一致的操作方式。这也为操作系统的可移植性提供了便利,因为应用程序不需要依赖于特定文件系统的实现细节。
虚拟文件系统的主要功能包括:
抽象化文件操作: VFS定义了文件操作的通用接口,屏蔽了底层文件系统的差异,使得应用程序可以在不同的文件系统上运行而无需修改代码。
支持多种文件系统: VFS允许多个文件系统并存,每个文件系统都可以注册到VFS中。这样,系统就可以支持不同类型的文件系统,如硬盘上的ext4、FAT32,网络上的NFS等。
提供文件系统挂载: VFS支持文件系统的挂载(mount)和卸载(umount),使得用户可以将不同的文件系统挂载到指定的目录下,实现文件系统的切换和管理。
统一文件访问: 用户和应用程序通过VFS进行文件访问,无论底层文件系统是什么类型,都使用相同的系统调用和接口。
通过VFS的设计,操作系统实现了对不同文件系统的透明支持,为用户提供了更加灵活和统一的文件管理方式。
虚拟文件系统(VFS)的一个主要作用是简化应用程序的开发,提供了一个统一的文件访问接口,使得应用程序员无需关心底层文件系统的差异和细节。
以下是虚拟文件系统的一些主要作用:
统一文件操作接口: VFS定义了一组标准的系统调用和文件操作接口,如 open
、read
、write
、close
等,使得应用程序员可以使用相同的接口对文件进行读写操作,而无需关心底层文件系统的实现。
屏蔽底层文件系统差异: 应用程序通过VFS进行文件操作,不需要知道底层文件系统的具体类型,如ext4、FAT32等。这种抽象层的存在使得应用程序更具可移植性,可以在不同的文件系统上运行而无需修改代码。
支持多种文件系统: VFS允许多个文件系统并存,每个文件系统都可以注册到VFS中。这样,系统可以同时支持不同类型的文件系统,包括本地文件系统、网络文件系统等。
文件系统挂载和卸载: VFS提供了文件系统挂载和卸载的功能,允许用户将不同的文件系统挂载到指定的目录下。这使得用户可以方便地管理不同的文件系统,并在需要时切换文件系统。
提供文件系统抽象: VFS为文件系统提供了一个抽象层,使得文件不仅可以存在于硬盘上,还可以是设备、内存等。这样,应用程序可以通过相同的接口访问不同类型的文件。
总体而言,虚拟文件系统为操作系统提供了一种通用的、统一的文件管理方式,为应用程序提供了更好的可移植性和灵活性。
在Linux系统中,目录被组织成一个:单根倒置树结构,文件系统从根目录开始,用/来表示。文件名称区分大小写( 大小写敏感还需要看具体的文件系统格式 ),以.开头的为隐藏文件,路径用/来进行分割(windows中使用\来分割),文件有两个种类:元数据与数据本身.在操作linux系统时,通常会遵循以下的分层结构规则:
LSB (Linux Standard Base) / FHS(Filesystem Hierarchy Standard)
/
:根目录,位于Linux文件系统目录结构的顶层,一般根目录下只存放目录,不要存放文件,/etc、/bin、/dev、/lib、/sbin应该和根目录放置在一个分区中。
/bin
: 提供用户使用的基本命令, 存放二进制命令,不允许关联到独立分区,OS启动会用到里面的程序。
/boot
:用于存放引导文件,内核文件,引导加载器.
/sbin
:管理类的基本命令,不能关联到独立分区,OS启动时会用到的程序(重要的命令通常处于bin,不重要的则安装在sbin)。
/lib
:存放系统在启动时依赖的基本共享库文件以及内核模块文件. 系统使用的函数库的目录 也存放了大量的脚本库文件 ,程序在执行过程中,需要调用时会用到
/lib64
:存放64位系统上的辅助共享库文件.
/etc
: 系统配置文件存放的目录,该目录存放系统的大部分配置文件和子目录,不建议在此目录下存放可执行文件 。
/home
:普通用户主目录,当新建账户时,都会分配在此,建议单独分区,并分配额外空间用于存储数据。
/root
: 系统管理员root的宿主目录,系统第一个启动的分区为/,所以最好将/root和/放置在一个分区下。
/media
:便携式移动设备挂载点目录.
/mnt
:临时文件系统挂载点.
/dev
: 设备(device)文件目录,存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,存放连接到计算机上的设备(终端、磁盘驱动器、光驱及网卡等)的对应文件 (b 随机访问,c 线性访问)
/opt
:第三方应用程序的安装位置.
/srv
: 服务启动之后需要访问的数据目录,存放系统上运行的服务用到的数据,如www服务需要访问的网页数据存放在/srv/www内。
/tmp
:存储临时文件, 任何人都可以访问,重要数据一定不要放在此目录下。
/usr
: 应用程序存放目录,/usr/bin 存放保证系统拥有完整功能而提供的应用程序, /usr/share 存放共享数据,/usr/lib 存放不能直接运行的,却是许多程序运行所必需的一些函数库文件,_/usr/local 存放软件升级包,第三方应用程序的安装位置,/usr/share/doc _系统说明文件存放目录。
/var
:放置系统中经常要发生变化的文件,如日志文件。/var/log 日志目录及文件./var/tmp:保存系统两次重启之间产生的临时数据.
/proc
: 用于输出内核与进程信息相关的虚拟文件系统,目录中的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间
/sys
: 用于输出当前系统上硬件设备相关的虚拟文件系统.
/selinux
:存放selinux相关的信息安全策略等信息.
文件类型
在Linux中,使用命令查看文件,首字母会标记该文件的文件类型,一般有以下几种类型:
文件名最长为255字节(字节,不是字符)。包括路径在内的文件名称最长为4095字节。
文件颜色显示不同,代表了不同的文件格式。(以下为默认格式,可以自定义)
蓝色 -> 文件夹
绿色 -> 可执行文件
红色 -> 压缩文件
浅蓝色 -> 链接文件
灰色 ->其他文件
在Linux中,除了斜杠和NUL字符,都是合法的。不推荐使用特殊符号来命名文件或者目录,容易引发混淆.比如空格, -,非要创建就用””引用起来,但如果遇到用特殊字符命名的特殊文件,在该文件上加上:文件路径后即可进行查看,创建,删除。
… 表示父目录 .表示当前目录
绝对路径 :以正斜杠开始,表示该文件从根目录开始的完整位置路径,必须以根开始。
相对路径 :不以斜杠开始,**指该文件相对于该目录的路径或某个目录的路径,不以根开始。**可以作为一个简短的形式来指定一个文件名。
两个常用的小命令:
basename : 取文件本身的名称 不带目录
dirname : 取文件目录 ,不带文件名
虚拟文件系统(Virtual File System,简称 VFS)是操作系统中的一个抽象层,为不同的文件系统提供了一个统一的接口。它允许应用程序使用相同的系统调用来访问各种不同类型的文件系统,无论这些文件系统是本地的还是远程的。
以下是 VFS 的主要特点和作用:
抽象文件系统接口: VFS 提供了一个抽象文件系统接口,使得应用程序无需关心底层的具体文件系统类型。通过使用相同的系统调用,应用程序可以在不同的文件系统上执行操作,例如打开、读取、写入、关闭等。
支持多种文件系统: VFS 支持多种文件系统,包括但不限于 ext4、FAT32、NTFS、ISO 9660 等。这意味着系统可以同时挂载并使用不同类型的文件系统,而应用程序无需修改代码。
文件系统模块化: VFS 允许在运行时加载和卸载文件系统模块。这使得系统能够根据需要动态地添加或移除文件系统支持,而无需重新启动操作系统。
逻辑目录结构: VFS 定义了一个逻辑的目录结构,与具体的物理文件系统实现无关。这使得文件和目录的操作在逻辑上是一致的,而不受底层文件系统的限制。
网络文件系统支持: VFS 使得操作系统能够支持网络文件系统(NFS)等远程文件系统。这意味着用户可以通过网络访问位于远程服务器上的文件,就像访问本地文件一样。
总体而言,VFS 提供了一个标准的、统一的接口,使得应用程序可以更加灵活地与不同类型的文件系统交互,而无需关心底层细节。这对于支持多种文件系统的操作系统非常重要。
我们知道文件系统的种类有很多。除了Linux标准的文件系统Ext2/Ext3/Ext4外,还有很多种文件系统 。linux通过叫做VFS的中间层对这些文件系统提供了完美的支持。在大部分情况下,用户通过libc和kernel的VFS交互,不需要关心底层文件系统的具体实现。
我的理解,vfs就是对各种文件系统的一个抽象,它为各种文件系统提供了一个通用的接口,类似于c++中虚基类的作用,而每一种具体的文件系统则将其物理组织结构转换为虚拟文件系统的通用模型。
VFS是对各种文件系统的一个抽象,它为各种文件系统提供了一个通用接口
文件对应的分区可能不一样,有的来自ext4,或者tmps。即为文件系统的类型可能不一样,数据存储的方式不一样,访问方式也就不一样,没办法做到操作统一化,给编程开发带来困难。
而虚拟文件系统的存在正是解决了这个问题:简化上层应用程序员的开发,不管是什么文件类型,磁盘还是设备,通通都是用open,read,write统一操作。
虚拟文件系统(VFS)的作用正是为了简化上层应用程序员的开发,提供一个统一的接口,使得不同类型的文件系统能够通过相同的系统调用来进行操作。这种设计有几个关键的优点:
抽象不同文件系统的细节: VFS 将底层文件系统的具体实现细节进行了抽象,使得应用程序不需要关心文件系统的类型。应用程序可以使用统一的接口,而无需担心底层文件系统的差异。
统一的文件操作接口: 通过使用统一的系统调用,如 open
、read
、write
等,应用程序能够在不同的文件系统上执行相同的操作。这简化了应用程序的编写和维护,同时提高了代码的可移植性。
支持多种文件系统: VFS 支持多种文件系统,包括本地文件系统和远程文件系统。这使得操作系统能够适应不同的应用场景,例如支持网络文件系统(NFS)等。
动态加载和卸载文件系统模块: VFS 允许在运行时动态加载和卸载文件系统模块,从而支持灵活的文件系统扩展和配置。这使得系统可以根据需要动态地添加或移除文件系统支持,而无需重新启动操作系统。
总体而言,VFS 的设计提供了一种高度抽象的文件系统框架,使得不同文件系统能够以一致的方式与操作系统交互,为应用程序提供了便利性和灵活性。
vfs所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核;其中有一个字段或函数来支持Linux所支持的所有实际文件系统所提供的任何操作。对所调用的每个读、写或其他函数,内核都能把它们替换成支持本地Linux文件系统、NTFS文件系统,或者文件所在的任何其他文件系统的实际函数。
有了vfs,就能很容易实现不同文件系统之间的数据读写,因为它们对外接口都是一样的,都是vfs导出的通用接口。
以下ulk3书上的例子:
例如,假设一个用户输入以下shell命令:
cp /floppy/TEST /tmp/test
这个例子演示了 VFS 的核心思想。让我们逐步解析这个命令:
cp
是文件拷贝命令,它需要复制 /floppy/TEST
文件到 /tmp/test
。
/floppy/TEST
是源文件的路径,它位于名为 /floppy
的目录下。
/tmp/test
是目标文件的路径,它位于名为 /tmp
的目录下。
这个命令的执行涉及到两个不同的文件系统:一个是 /floppy
目录,通常是挂载的软盘(floppy)文件系统;另一个是 /tmp
目录,通常是根文件系统(ext4 或其他文件系统)。
VFS 的作用在于将这两个不同文件系统的操作抽象成相同的接口,让 cp
命令无需关心底层文件系统的细节。对于 cp
命令而言,源文件和目标文件都是通过 VFS 的统一接口来处理的。
在执行这个命令时,VFS 的作用有以下几个方面:
路径解析: VFS 解析路径 /floppy/TEST
和 /tmp/test
,确定它们分别对应于哪个文件系统的哪个文件。
打开文件: VFS 使用统一的接口打开源文件 /floppy/TEST
和目标文件 /tmp/test
。open
等系统调用是通过 VFS 提供的,不关心具体的文件系统类型。
读写数据: VFS 通过相同的接口执行读取 /floppy/TEST
和写入 /tmp/test
的操作,而这些操作可能分别对应于软盘文件系统和根文件系统。
关闭文件: VFS 也提供关闭文件的接口,确保在完成操作后文件被正确关闭。
通过 VFS,cp
命令可以统一处理来自不同文件系统的文件,这使得操作系统更加灵活,能够适应多种存储设备和文件系统的组合。
其中/floppy是MS-DOS磁盘的一个安装点,而/tmp是一个标准的第二扩展文件系统(second Extended Filesystom, Ext2)的目录。
正如图(a)所示,VFS是用户的应用程序与文件系统实现之间的抽象层。
因此,cp程序并不需要知道/floppy/TEST 和 /tmp/test是什么文件系统类型。
相反,cp程序直接与VFS交互,这是通过Unix程序设计人员都熟悉的普通系统调用来进行的。
cp的执行代码如图(b)所示:
如果从分区的角度,串口操作的就是/dev;普通文件如 .config在ext4上;共享内存 tmpfs dev/shm…
之前所学的Linux系统编程,各种应用层的知识,vfs都提供了帮助。
Linux 系统编程的角度可以从上层到底层来看。以下是一个简单的层次划分:
用户空间应用层: 包括用户编写的应用程序,这些程序通过系统调用与操作系统内核进行交互。这是最上层的层次,应用程序可以是各种用户工具、服务和应用。
系统调用层: 用户空间应用通过系统调用(如open
、read
、write
)与内核进行通信。这一层实现了用户和内核之间的接口,应用程序通过这些接口请求底层的操作。
C库(libc)层: C库包含了一系列的函数,这些函数是对系统调用的封装。例如,C库中的 fopen
函数可能会调用 open
系统调用。这一层的存在简化了用户空间应用的编程,使得开发者可以使用更高层的抽象。
虚拟文件系统(VFS)层: 提供了对不同文件系统的抽象,让上层的应用程序可以不用关心具体文件系统的实现细节。VFS 统一了文件访问的接口,使得用户空间应用可以透明地处理来自不同文件系统的文件。
文件系统层: 这是针对具体文件系统的实现,例如 ext4、FAT32 等。每个文件系统实现了 VFS 接口,这样它就能够被上层的应用程序调用。
设备驱动层: 包括了对硬件设备的驱动程序。这一层通过设备文件(如 /dev/ttyS0
)向用户空间提供对硬件的访问。串口、USB 设备、网络接口等都通过相应的设备驱动进行管理。
硬件层: 最底层是硬件层,包括处理器、内存、磁盘、网络接口等硬件设备。
系统编程的层次结构允许开发者在不同的层次上进行工作,根据需要选择合适的抽象层级。这种结构使得不同的应用和服务可以在相同的操作系统上运行,并与各种硬件设备和文件系统交互,实现了高度的灵活性和可移植性。