drop_caches
[toc] fs/drop_caches.c 内核缓存手动回收(Manual Kernel Cache Reclaiming) 提供清空页面、目录和inode缓存的接口历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了给系统管理员、性能测试工程师和内核开发者提供一个手动、强制性地清空内核主要缓存的手段,以解决以下特定问题: 可重复的性能基准测试:在进行磁盘I/O或文件系统性能测试时,上一次运行的结果会“预热”内核缓存(Page Cache)。这导致下一次运行会直接从高速的内存中读取数据,而不是从慢速的磁盘读取,从而使得测试结果不准确,无法反映真实的“冷启动”性能。drop_caches 允许在每次测试前清空缓存,确保测试环境的一致性。 模拟内存压力:开发者需要测试应用程序或内核本身在内存资源紧张时的行为。通过手动清空缓存,可以快速回收大量内存,从而模拟出系统突然面临内存压力的场景。 诊断特定的内存问题:在极少数情况下,内核的slab分配器可能出现严重的内存碎片问题,或者某些驱动程序存在内存泄漏,导致缓存无法被正常回收。drop_caches 可...
dcache
[TOC] fs/dcache.c 目录项缓存(Directory Entry Cache) VFS路径查找加速器历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术以及它所实现的目录项缓存(dcache),是为了解决Linux虚拟文件系统(VFS)中最核心的性能瓶颈之一:路径名到inode的解析过程。 消除磁盘I/O:在一个典型的文件系统中,解析一个路径如/home/user/file.txt需要一系列的磁盘读取操作。首先读取根目录/的内容找到home,然后读取home目录的内容找到user,以此类推,直到最后找到file.txt。每一次目录读取都是一次缓慢的磁盘I/O。如果每次open()或stat()系统调用都执行这个过程,系统性能将无法接受。 提供快速路径查找:dcache在内存中缓存了目录项(dentry)的树状结构,它直接映射了文件系统的目录层次。当内核需要解析一个路径时,它首先在dcache中查找。如果路径的所有组件都在缓存中,整个解析过程就可以在内存中以极高的速度完成,完全无需访问磁盘。 缓存负面结果(Negative Loo...
exec
[TOC] fs/exec.c 程序加载与执行(Program Loading and Execution) execve系统调用的核心实现历史与背景这项技术是为了解决什么特定问题而诞生的?fs/exec.c 中的代码是为了解决操作系统中最基本的一个需求:如何在一个正在运行的进程上下文中启动一个全新的程序。这个过程被称为“执行”一个程序。它与创建新进程(由 fork() 实现)是分离的,这种“创建”与“执行”的分离是Unix哲学的核心之一。具体来说,它解决了以下问题: 进程复用:当一个进程完成了它的使命,但需要启动另一个程序来接替它时(例如shell执行用户输入的命令),没有必要销毁当前进程再创建一个全新的进程。execve 允许重用现有的进程结构(如PID),只将内存中的程序镜像替换为新的程序,这大大提高了效率。 程序解耦:它使得任何程序都可以调用任何其他程序,而无需了解其内部实现。一个简单的程序可以通过 exec 来调用一个复杂的工具来完成特定任务。 支持多种可执行格式:操作系统需要能够运行不同格式的可执行文件,例如经典的 a.out 格式、COFF 格式,以及现...
genhd
[toc] block/genhd.c 通用硬盘驱动(Generic Hard Disk Driver) 内核中块设备的表示与管理历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了在Linux内核中创建一个统一的、抽象的块设备表示,以解决如何管理和表示各种各样的块存储设备(如硬盘、软盘、U盘、RAID卷等)的问题。 在genhd.c(Generic Hard Disk)所代表的框架出现之前,内核中对不同类型块设备的管理是零散和不一致的。genhd.c的诞生旨在解决以下核心问题: 设备抽象:需要一个通用的数据结构来描述一个块设备,无论它是物理硬盘、一个硬盘上的分区,还是一个由多个磁盘组成的逻辑卷。这个结构就是struct gendisk。 分区管理:一个物理磁盘通常被划分为多个分区。内核需要一个标准的机制来发现、解析和表示这些分区,并将每个分区也作为一个独立的块设备呈现给上层。genhd.c负责扫描分区表并为每个分区创建设备节点。 设备注册与命名:需要一个统一的机制来向内核注册新的块设备,并为其分配一个唯一的设备号(major/minor ...
file_table
[toc] fs/file_table.c 文件表管理(File Table Management) VFS中“打开文件”对象的分配与管理核心历史与背景这项技术是为了解决什么特定问题而诞生的?fs/file_table.c 及其管理的核心数据结构 struct file 是整个Linux/Unix虚拟文件系统(VFS)的基石。它的诞生是为了解决一个操作系统设计中的根本性问题:如何清晰、高效地管理和区分“文件本身”与“对文件的打开实例”。 具体来说,它解决了以下几个核心问题: 分离“打开”的状态:一个磁盘上的文件(例如 /home/user/data.txt)是静态的。但当一个进程打开它时,就需要一个地方来存储与这次“打开”相关的动态状态,最关键的就是当前读写位置(file position/offset)。struct file 对象就是为此而生。 支持多个独立的打开实例:同一个进程或不同进程可以多次打开同一个文件。每一次open()调用都应该获得一个独立的“会话”,拥有自己独立的读写位置。这意味着需要为每次open()创建一个新的struct f...
filesystems
[toc] fs/ VFS - 虚拟文件系统(Virtual Filesystem) 内核统一的文件系统抽象层历史与背景这项技术是为了解决什么特定问题而诞生的?虚拟文件系统(Virtual Filesystem Switch, VFS)是Linux内核最核心、最强大的子系统之一。它的诞生是为了解决一个根本性的问题:如何让应用程序以一种统一的方式来访问各种不同类型的文件系统。 在VFS出现之前,操作系统如果想支持一种新的文件系统(例如,从Minix文件系统切换到ext文件系统),可能需要重写大量与文件操作相关的代码。应用程序也可能会与特定的文件系统实现产生耦合。VFS通过创建一个通用的抽象层来解决这个问题: 对应用程序的统一接口:无论底层是ext4、XFS、Btrfs、NFS(网络文件系统),还是一个USB U盘上的FAT32,应用程序都使用同样标准的系统调用(open, read, write, close, stat等)来操作文件。应用程序完全不需要知道底层文件系统的具体类型和实现细节。 对文件系统驱动的统一接口:VFS定义了一套标准的“插件”接口。任何想要被...
file
[TOC] fs/file.c 文件句柄管理(File Handle Management) 管理已打开文件的核心数据结构历史与背景这项技术是为了解决什么特定问题而诞生的?fs/file.c 及其管理的数据结构是为了解决在多进程操作系统中如何清晰、高效地管理“已打开文件”这一核心概念而诞生的。它解决了以下几个基本问题: 状态的区分:需要区分“磁盘上的文件”和“被打开的文件”。磁盘上的文件有其固有的属性(大小、权限等),而被打开的文件则有其动态的状态,最典型的就是当前的读写位置(offset)。多个进程可以同时打开同一个文件,但每个进程都应该有自己独立的读写位置。 抽象与统一:操作系统需要一个统一的接口来处理所有类型的I/O操作。无论是读写磁盘文件、管道、套接字还是硬件设备,用户空间程序都应该能使用相同的系统调用(read, write, close)。fs/file.c 提供的框架是实现这种统一接口(即VFS - 虚拟文件系统)的关键部分。 资源共享与隔离:需要一种机制来管理文件句柄在进程间的关系。例如,一个进程如何复制一个文件句柄(dup),以及父进程打开...
fs_context
[toc] fs/fs_context.c 文件系统创建上下文(Filesystem Creation Context)历史与背景这项技术是为了解决什么特定问题而诞生的?fs_context 框架的诞生是为了彻底改革和现代化Linux内核中挂载文件系统的方式,以解决传统mount(2)系统调用长期以来存在的诸多根本性问题: 混乱的参数传递:mount(2)系统调用使用一个名为data的参数(void *data),它实际上被用作一个非结构化的、以逗号分隔的字符串来传递文件系统特定的挂载选项(如"rw,noatime,jounal_checksum")。这种方式有几个巨大的缺点: 解析复杂且容易出错:每个文件系统都必须编写自己的、脆弱的字符串解析器来提取选项。 缺乏类型安全:所有选项都被当作字符串,无法以原生方式传递整数、布尔标志或二进制数据(如安全密钥)。 难以验证:内核很难在文件系统解析之前对选项进行统一的验证。 API不灵活且难以扩展:mount(2)的参数是固定的。当出现新的挂载需求或新型文件系统(特别是那些没有传统块设备源的,如网络文件...
fs_parser
[TOC] fs/fs_parser.c 文件系统参数解析器(Filesystem Parameter Parser) 为挂载和配置提供统一的参数解析历史与背景这项技术是为了解决什么特定问题而诞生的?fs/fs_parser.c 及其实现的框架是为了解决一个长期困扰Linux VFS(虚拟文件系统)层的问题:缺乏一个统一、健壮且可扩展的文件系统挂载选项(Mount Options)解析机制。 在引入该框架之前,每个独立的文件系统(如ext4, xfs, nfs, btrfs等)都需要在自己的代码中实现一套独立的逻辑来解析用户通过 mount(2) 系统调用传递进来的、以逗号分隔的选项字符串(例如 "ro,uid=1000,data=ordered")。这导致了几个严重的问题: 代码重复:几乎每个文件系统都有一段相似但又不完全相同的代码,用于分割字符串、区分标志(如ro)和键值对(如uid=1000)、并将字符串转换为整数或其他类型。 不一致性:不同的文件系统可能会以微妙不同的方式处理相同的选项,或者对错误的输入有不同的响应,缺乏一致的用户体验。 容...
fs-writeback
[TOC] fs-writebackfs-writeback.c 是 Linux 内核中负责处理文件系统数据写回(writeback)机制的核心模块。它的主要功能是管理脏页和脏 inode 的写回操作,以确保数据从内存缓冲区最终写入磁盘。以下是对其原理、使用场景、优缺点以及其他方案的详细阐述: 原理 脏页与脏 inode: 当文件系统中的数据被修改时,内核会将这些修改暂时存储在内存中(页缓存或 inode 缓存),并标记为“脏”。 脏页指的是页缓存中未写入磁盘的修改数据,脏 inode 则是文件元数据(如时间戳、权限等)的未写入部分。 写回机制: fs-writeback.c 通过后台线程(flusher threads)定期扫描脏页和脏 inode,并将它们写入磁盘。 写回操作可以是异步的(WB_SYNC_NONE),也可以是同步的(WB_SYNC_ALL),具体取决于调用场景。 核心组件: bdi_writeback: 表示一个设备的写回上下文,管理该设备的脏页和脏 inode。 wb_writeback_work: 描述写回任务的结构体,包括写回页数、...







