首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

并发、DMA/IOMMU、安全与故障排查

并发、DMA/IOMMU、安全与故障排查

1. 并发域

该目录跨越:

  • process context ioctl/sysfs;
  • fbcon/console;
  • IRQ;
  • workqueue/timer;
  • runtime/system PM;
  • dma-buf/fence callbacks;
  • remove/shutdown。

单一mutex不能覆盖所有域。

2. 锁层次

建议固定顺序:

1
2
3
4
5
global/service
-> device
-> session
-> queue/job
-> buffer

IRQ只使用spinlock/atomic和短临界区;等待fence时不能持有阻止producer运行的锁。

3. Job状态

明确:

1
NEW -> QUEUED -> RUNNING -> DONE/ERROR/CANCELLED

只有一个路径负责最终free和fence signal,避免timeout与IRQ同时完成导致double free。

4. Remove顺序

1
2
3
4
5
6
7
8
9
remove userspace entry
-> reject new open/ioctl
-> cancel/drain pending work
-> mask IRQ
-> stop/reset hardware
-> complete active jobs with error
-> detach/unmap dma-buf/IOMMU
-> disable PM/clock
-> free device

5. DMA边界

所有plane计算使用checked arithmetic:

1
required = offset + stride * (height - 1) + last_line_bytes

还需考虑chroma subsampling、compressed modifiers、alignment和address width。

6. IOMMU

IOMMU限制设备可访问范围,但不能弥补:

  • 同一mapped buffer内部越界;
  • secure buffer误授权;
  • use-after-unmap;
  • 错误DMA direction;
  • cache同步遗漏。

7. Fence

  • import input fence;
  • job依赖满足后调度;
  • completion/error都signal output fence;
  • close/remove不能留下永不signal fence;
  • 检测或避免依赖环。

8. Userspace ABI

ioctl结构需:

  • 固定宽度类型;
  • reserved清零;
  • version/size;
  • copy_from_user完整检查;
  • pointer compat处理;
  • 数组count上限;
  • command/register白名单。

9. 设备节点权限

/dev/fbN可读取屏幕;RGA/MPP等节点可驱动高带宽DMA。按最小权限配置udev/SELinux,容器中不要默认透传。

10. 信息泄露

  • 新buffer先清零;
  • 不把未初始化register/result复制给用户;
  • debugfs不输出physical address;
  • crash dump避免包含受保护视频帧;
    -释放敏感metadata前清理。

11. DoS

限制:

  • 每session outstanding jobs;
  • imported buffer数/总字节;
  • timeout;
  • debug dump频率;
  • fault reset频率;
  • 最大分辨率和寄存器消息长度。

12. 故障定位路径

1
2
3
4
5
6
7
8
9
10
11
12
Kconfig/module
-> DT match/status
-> probe resources
-> device node/sysfs
-> open/ioctl
-> buffer import
-> IOMMU map
-> clock/PM
-> job queue
-> hardware start
-> IRQ/fence
-> display consumer

13. 关键观测

  • dmesg probe/reset/IOMMU fault;
  • /sys/kernel/debug/dri/0/state
  • debugfs/procfs job/session;
  • /proc/interrupts
  • clock/power-domain;
  • dma-buf/fence信息;
  • PWM/backlight;
  • tracepoints/ftrace。

14. 典型症状

症状 可能原因
ioctl永久等待 IRQ丢失、fence未signal、timeout失效
IOMMU fault size/offset、提前unmap、错误domain
随机花屏 producer/consumer同步、stride/format、cache
suspend后hang active job未drain、clock恢复顺序
remove崩溃 open/session/IRQ仍引用对象
性能低 DDR/QoS、重复copy、频繁PM、core策略

15. 配置裁剪

保留RK3588实际使用的DRM、bridge/panel、backlight、RGA/MPP backend;关闭无关legacy fb、vehicle、tunnel、proc/debugfs。裁剪后需回归boot logo、console、suspend、视频、合成和异常reset。

顶层 Helper 与启动参数

顶层 Helper 与启动参数

1. 根目录边界

drivers/video根目录除Kconfig/Makefile外有8个C文件:

文件 作用
aperture.c framebuffer aperture ownership
hdmi.c HDMI infoframe编解码
hdmi-notifier.c 旧notifier实现,未进入Makefile
vgastate.c VGA寄存器保存/恢复
display_timing.c timing对象释放等
videomode.c timing到具体mode转换
of_display_timing.c OF timing解析
of_videomode.c OF到videomode封装

2. HDMI Helper

hdmi.c不是HDMI controller driver。它处理:

  • AVI infoframe;
  • SPD infoframe;
  • Audio infoframe;
  • Vendor Specific infoframe;
  • DRM/HDR static metadata infoframe;
  • init、check、pack、unpack、checksum和log。

实际RK3588 HDMI寄存器、HPD、DDC和PHY位于DRM及PHY driver。

3. Infoframe路径

1
2
3
4
5
DRM connector/mode/audio state
-> fill hdmi_*_infoframe
-> check
-> pack + checksum
-> HDMI controller writes packet RAM

pack必须检查buffer长度;unpack校验header、type、length和checksum。

4. hdmi-notifier.c

源码实现connected/disconnected/new EDID/new ELD blocking notifier,但没有任何Makefile引用,当前kernel不会链接它。存在头文件不代表运行时API可用。

5. VGASTATE

vgastate.c为legacy VGA driver提供save_vga()restore_vga(),保存字体、cmap和寄存器。它与RK3588 VOP2无关。

保存/恢复期间涉及VGA I/O和显存plane,调用者必须拥有硬件,不能与其它VGA/DRM driver并发。

6. video=

实现位于fbdev/core/fb_cmdline.c

  • video=<driver>:<options>把选项按driver保存;
  • 无driver名可作为全局mode option;
  • options以off开头可禁用对应fb driver;
  • video=ofonly限制Open Firmware framebuffer。

具体mode字符串由fbdev modedb/各driver继续解释。

7. fbcon=

实现位于fbdev/core/fbcon.c,控制:

  • framebuffer到VT映射;
  • 字体;
  • scroll;
  • rotate;
  • takeover行为。

配置符号在console/Kconfig,实现对象却编入fbdev Core,二者不要混淆。

Logo模块参数禁止启动logo。Logo数据位于init段,late init后logos_freed阻止继续引用,避免访问已释放init memory。

9. 全局nomodeset

全局参数实现于drivers/gpu/drm/drm_nomodeset.c,不在本目录。它使native DRM driver不注册,仅保留system framebuffer类路径。

本目录中radeonfb另有私有nomodeset语义,不能与DRM全局参数混为一谈。

10. nomodeset对RK3588的影响

RK3588本树无simplefb/efifb DTS节点,禁用Rockchip DRM后不应假定仍有可用图形framebuffer;可靠救援入口应保留串口console。

11. 构建符号

  • HDMI:通常由DRM/HDMI消费者select;
  • VGASTATE:legacy VGA;
  • VIDEOMODE_HELPERS:timing helper;
  • APERTURE_HELPERS:firmware framebuffer ownership。

这些bool/tristate不代表有独立用户设备。

12. 安全

  • Infoframe输入长度必须严格校验;
  • EDID/ELD视为外部不可信数据;
  • aperture physical range防overflow;
  • 不允许两个driver同时拥有VGA/aperture;
  • boot参数只改变策略,不提供权限隔离。

RK3588 kernel-6.1:drivers/video 作用、解决的问题与结构说明

RK3588 kernel-6.1:drivers/video 作用、解决的问题与结构说明

源码基准:/home/cp/work2/SeagullYpcEncode/rk3588/kernel-6.1/drivers/video/
说明:现代桌面 GPU 的主路径多在 drivers/gpu/drm/drivers/video 仍以 帧缓冲(fbdev)、背光、文本控制台(fbcon)、显示模式辅助 以及 本树中体量很大的 Rockchip 多媒体/2D 加速子树 为主。

内核图形菜单在 drivers/video/Kconfig 中汇总:APERTURE、引用 drivers/gpu/drm 等;本文聚焦 drivers/video 目录本体


1. 代码的作用(总体)

子目录/模块 作用
fbdev/ 帧缓冲设备(/dev/fb0:为应用程序提供 统一像素缓冲接口(ioctl mmap);内含 fbmem.c 核心 与各 SoC/PCI/VGA 简易驱动
backlight/ 背光/LCD 类设备backlight sysfs、PWM/GPIO/WLED 等调节亮度
console/CONFIG_VT 帧缓冲控制台(fbcon) 等:内核 printk / 文本 VT 输出到 framebuffer
logo/CONFIG_LOGO 启动 企鹅等 logo 写入 fb
videomode.cdisplay_timing.cof_*.cCONFIG_VIDEOMODE_HELPERS DT display-timings 解析、videomode 换算,供 fb/simpledrm/部分 DRM 面板驱动复用
aperture.chdmi.cvgastate.c 显存窗口(aperture)移交HDMI 通用 EDID 等辅助(按配置)、VGA 状态
rockchip/(本 RK SDK 树 obj-y Rockchip 专用RGA/RGA2/RGA3(2D 合成与缩放)RVEIEPMPP(视频编解码服务入口)车载 camera/display(vehicle)vtunneldvbm

2. 解决了什么问题

2.1 通用部分(fbdev / backlight / console)

问题 解决办法
应用如何在不绑定特定 GPU 驱动的情况下画屏 /dev/fb* + mmap,尤其在 无 DRM/KMS 的老嵌入式 上几乎是唯一简单路径
内核早期与救援 shell 需要图形或帧缓冲文本输出 fbconVTfb 绑定
LCD 亮度与电源序列 backlight/lcd class drivers:PWM、PMIC、GPIO
面板时序从设备树统一描述 videomode/display_timing helpers,减少各驱动重复解析 DT

2.2 与 DRM 的关系(避免混淆)

  • 新平台上桌面/Wayland/Android HWComposer 主流使用 DRM/KMSdrivers/gpu/drm)。
  • fbdev 仍常见于:boot splash、简单 Qt/EGLFS fb、遗留驱动;部分系统 DRM fbdev emulation(CONFIG_DRM_FBDEV_EMULATION 提供 /dev/fb0 兼容层,并非必须由 drivers/video/fbdev 提供物理 fb。

2.3 Rockchip 子树(RK3588 相关)

模块 典型用途
MPP 视频硬件编解码调度(与 /dev/mpp_service 类接口配合用户态堆栈)
RGA / RGA2 / RGA3 2D 图像缩放、格式转换、合成,减轻 CPU
IEP 图像增强处理(Image Enhancement Processor)
RVE Rockchip vendor 图像/矢量加速模块,能力以硬件配置表和配套 UAPI 为准
vehicle 车载多路视频输入/显示链路(serializer、ISP、flinger 等)
vtunnel 虚拟显示隧道(源码注释与 Kconfig 为准)

这些是 芯片多媒体/display pipeline 的内核侧支撑,与单纯「帧缓冲」不同,但历史上落在 drivers/video/rockchip 目录下维护。


3. Makefile 链接关系(节选)

1
2
3
4
5
6
obj-$(CONFIG_VT)          += console/
obj-$(CONFIG_LOGO) += logo/
obj-y += backlight/
obj-y += rockchip/
obj-y += fbdev/
obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o ...

rockchip/backlight/fbdev/ 在本 Makefile 中为 obj-y:是否最终进内核映像仍取决于 各子目录内 obj-$(CONFIG_*)(未选中的驱动不会链接)。


4. RK3588 集成要点

  • 显示输出:RK3588 产品常见 DRM(如 rockchipdrmdrivers/gpu/drmdrivers/video 侧可能仍编 fbdev 兼容背光RGA/MPP
  • 多媒体:编解码除 staging rkvdec 外,MPP 路径 常与 drivers/video/rockchip/mpp 协同(具体节点名与 ABI 以 SDK 文档为准)。
  • 裁剪内核时:勿误以为删掉整个 drivers/video 即可,需确认 fbcon/logo/backlight/MPP 是否仍被根文件系统或引导依赖。

5. 小结表

维度 内容
作用 fbdev 框架与驱动背光fbcon/logo显示时序辅助RK SDK 加 Rockchip 多媒体与车载大块代码
解决的问题 统一像素缓冲访问内核控制台显示背光抽象DT 时序复用RK 侧 2D/编解码/车载 pipeline
与 DRM 现代显示优先看 DRMvideo 侧重 fbdev 生态与 RK 扩展

6. 延伸阅读

  • Documentation/fb/framebuffer.rst
  • Documentation/gpu/index.rst(DRM 体系)

Linux 6.1 drivers/video 文档索引

Linux 6.1 drivers/video 文档索引

源码:rk3588/kernel-6.1/drivers/video/

文档 内容
Video子系统架构与源码总览.md fbdev、backlight、console、辅助层和Rockchip扩展
源码目录构建配置与模块索引.md 目录、Kconfig、Makefile及边界
01-FBDev-Core注册与生命周期.md fb_infofb_ops、注册和注销
02-FBDev用户接口IOCTL-MMap与Sysfs.md /dev/fbN、read/write、ioctl、mmap
03-FBCon-VT文本渲染与启动Logo.md fbcon、bitblit、cursor、旋转和logo
04-显示模式EDID与DeviceTree-Timing.md modedb、EDID、videomode和display-timings
05-Backlight与LCD-Class框架.md brightness、blank、sysfs、notifier和PM
06-PWM与GPIO背光驱动.md RK3588主要背光路径和DTS
07-Aperture固件帧缓冲移交.md simplefb/efifb与DRM ownership handoff
08-FBDev硬件驱动分类与现代DRM边界.md 大量legacy驱动、simplefb及DRM emulation
09-Rockchip-Video扩展目录总览.md RGA、MPP、IEP、RVE、DVBM、vehicle
10-RGA多核2D加速架构.md job、fence、dma-buf、IOMMU和调度
11-MPP视频编解码服务框架.md decoder/encoder、session、task和硬件复位
12-IEP-RVE-DVBM与视频隧道.md 图像增强、矢量、buffer和tunnel
13-Vehicle倒车影像链路.md CIF、sensor、flinger和direct show
14-RK3588显示拓扑与DRM集成.md VOP2、HDMI、eDP、DP、DSI和背光
15-并发DMA-IOMMU安全与故障排查.md 生命周期、同步、权限、调试和裁剪
16-顶层Helper与启动参数.md HDMI infoframe、VGASTATE、video/fbcon/nomodeset

原有单篇分析保留于drivers-video分析.md,以上文档提供源码级拆分。

Video 子系统架构与源码总览

Video 子系统架构与源码总览

1. 目录不是单一子系统

drivers/video同时承担:

  • Graphics Kconfig总入口;
  • fbdev Core和历史硬件驱动;
  • backlight/LCD class;
  • VT console后端和logo;
  • display timing、HDMI、aperture等helper;
  • Rockchip SDK特有RGA/MPP/IEP等媒体扩展。

现代KMS显示主路径在drivers/gpu/drm/,并非全部位于本目录。

2. 通用分层

1
2
3
4
5
6
7
8
9
10
11
应用 / console
| \
/dev/fbN fbcon
| |
fbdev Core <------+
|
fb_ops
|
legacy fb driver 或 DRM fbdev emulation

panel/DRM ---- backlight class ---- PWM/GPIO/PMIC

3. Graphics菜单

drivers/video/Kconfig还source:

  • drivers/char/agp/Kconfig
  • drivers/gpu/vga/Kconfig
  • Host1x/IPU;
  • DRM;
  • ARM GPU;
  • fbdev;
  • backlight;
  • Rockchip misc video;
  • console/logo。

因此“Graphics support菜单内容”大于“drivers/video目录代码”。

4. fbdev

struct fb_info表示一块framebuffer,struct fb_ops由驱动实现。Core注册/dev/fbN、sysfs和notifier,提供mode、colormap、mmap、drawing helpers。

fbdev可来自:

  • 独立legacy硬件driver;
  • firmware framebuffer(simplefb/efifb);
  • DRM fbdev emulation。

5. fbcon

fbcon把VT字符、属性和光标转换为fb_fillrect/copyarea/imageblit,是内核文本控制台,不是用户图形合成器。

6. Backlight

Backlight class统一亮度、blank、power和实际亮度。具体驱动控制PWM、GPIO、LED、PMIC或外置芯片。

7. 显示模式辅助

display_timing表示带min/typ/max范围的板级时序;videomode表示具体像素时序。OF helper解析display-timingsnative-mode

8. Aperture

Firmware framebuffer可能先占显存。真实GPU/DRM driver加载时通过aperture helper移除冲突的simplefb/efifb,完成ownership handoff。

9. Rockchip扩展

drivers/video/rockchip包含:

  • RGA/RGA2/Multi-RGA:2D图像操作;
  • MPP:视频编解码服务;
  • IEP/IEP2:图像增强;
  • RVE;
  • DVBM;
  • vehicle倒车影像;
  • video tunnel。

这些大多不是显示scanout driver,也不属于fbdev Core。

10. RK3588主显示路径

1
2
3
4
5
Userspace DRM/HWC
-> Rockchip DRM
-> VOP2 video ports/planes
-> HDMI/eDP/DP/DSI bridge/connector
-> panel/backlight

VOP2及输出驱动主要在drivers/gpu/drm/rockchip;本目录直接相关的是PWM backlight、兼容fbdev和Rockchip媒体扩展。

11. 边界

  • Camera capture:media/V4L2及vendor CIF/ISP;
  • GPU 3D:Mali driver;
  • Display KMS:DRM;
  • codec标准接口:V4L2 mem2mem或vendor MPP;
  • buffer sharing:dma-buf;
  • DMA隔离:IOMMU;
  • fbdev:兼容像素buffer。

12. 生命周期原则

显示/媒体驱动必须按“阻止新任务→停止硬件→等待IRQ/fence→解绑IOMMU/dma-buf→关闭clock/reset/power→释放对象”顺序卸载。

源码目录、构建配置与模块索引

源码目录、构建配置与模块索引

1. 顶层文件

文件 作用
aperture.c firmware framebuffer aperture ownership
display_timing.c timing范围转换
videomode.c 具体mode转换
of_display_timing.c DT display-timings解析
of_videomode.c DT timing→videomode
hdmi.c HDMI通用辅助
hdmi-notifier.c vendor notifier实现,未由本层Makefile直接编入
vgastate.c VGA state save/restore

2. 子目录

  • fbdev/:Core及大量平台/PCI legacy drivers;
  • backlight/:class与约60个LCD/backlight drivers;
  • console/:dummy/VGA/MDA/STI/Newport console;
  • logo/:编译期图片转换和logo数据;
  • rockchip/:约152个vendor媒体文件。

3. 顶层Makefile

始终递归进入:

1
2
3
backlight/
rockchip/
fbdev/

实际对象仍由子目录CONFIG_*控制。

按配置构建:

  • APERTURE_HELPERS
  • VGASTATE
  • HDMI
  • VT console;
  • LOGO
  • VIDEOMODE_HELPERS及OF helper。

4. fbdev Core

CONFIG_FB生成fb.o

1
2
3
fbmem + fbmon + fbcmap + fbsysfs + modedb + fbcvt
[deferred_io]
[fbcon + bitblit + softcursor + rotation]

另外按需构建CFB/SYS drawing、DDC、sys fops等helper。

5. fbdev硬件驱动

Makefile覆盖旧PCI显卡、各SoC LCDC、firmware fallback、USB framebuffer和virtual fb。RK3588没有专用rk3588fb,主路径为DRM。

6. Backlight

Core:

  • BACKLIGHT_CLASS_DEVICEbacklight.o
  • LCD_CLASS_DEVICElcd.o

RK3588常用:

  • BACKLIGHT_PWMpwm_bl.o
  • 少数板可用GPIO、LED或PMIC backlight。

console目录并不含fbcon;fbcon代码位于fbdev/core/并链接进fb.oconsole/是VT底层console drivers。

Logo目录的pnmtologo是host tool,图片在构建时转换为C数据。

8. Rockchip子目录

配置 目录
ROCKCHIP_RGA rga
ROCKCHIP_RGA2 rga2
ROCKCHIP_MULTI_RGA rga3
ROCKCHIP_RVE rve
IEP iep
ROCKCHIP_MPP_SERVICE mpp
ROCKCHIP_MPP_OSAL mpp_osal
ROCKCHIP_DVBM dvbm
VIDEO_REVERSE_IMAGE vehicle
ROCKCHIP_VIDEO_TUNNEL vtunnel

9. Rockchip默认配置

rockchip_linux_defconfig启用DRM Rockchip、backlight class/PWM、Multi-RGA、IEP、MPP及多个codec backend。RVE、DVBM、vehicle、vtunnel是否启用需检查最终fragment。

10. 文档边界

Graphics Kconfig中AGP/DRM/GPU虽由本文件source,但代码分析应分别到drivers/char/agpdrivers/gpu文档,不应误计为本目录实现。

VFS 核心对象与生命周期

VFS 核心对象与生命周期

1. file_system_type

具体文件系统以 register_filesystem() 注册到 filesystems.c 的类型链表。核心回调是 init_fs_context 或旧 mount,模块所有者保证代码生命周期。

2. super_block

super.c 管理挂载实例:

  • sget_fc() 查找或分配 super;
  • get_tree_bdev() 绑定块设备;
  • get_tree_nodev() 建立无设备实例;
  • deactivate_super() / generic_shutdown_super() 卸载;
  • s_umount 串行化 mount/unmount 和 freeze。

一个磁盘文件系统 super 通常包含块大小、root dentry、dirty inode、writeback、quota 和私有 s_fs_info

3. inode

inode.c 管理 inode cache:

1
2
3
4
5
iget_locked()/iget5_locked()
-> lookup inode hash
-> miss: alloc_inode() + insert
-> filesystem reads metadata
-> unlock_new_inode()

i_count 归零经 iput();无链接或 super teardown 时进入 evict(),调用 super_operations->evict_inode() 清理页缓存和磁盘资源。

inode 不是路径名。同一 inode 可被多个 hard link dentry 引用。

4. dentry

dcache.c 的 dentry 表示父目录 + 名称的 lookup 结果,可为:

  • positive:d_inode != NULL
  • negative:记录不存在,缓存失败 lookup;
  • disconnected/anonymous:exportfs 等特殊场景。

d_lookup() 查 hash;d_alloc() 创建;d_add() 绑定 inode;dput() 降引用;shrinker 回收未使用 dentry。

5. file

file_table.cfilp_cachep 分配 file,alloc_file() 绑定 path 和 operations。关键字段:

  • f_path
  • f_inode
  • f_op
  • f_flags / f_mode
  • f_pos
  • f_cred
  • f_count

fput() 最终异步或 task-work 执行 __fput(),调用 flush/release、释放 path 和安全上下文。

6. 操作表

典型职责
super_operations inode alloc/evict、sync、stat、freeze
inode_operations lookup/create/link/unlink/rename/permission/xattr
file_operations open/read_iter/write_iter/mmap/fsync/ioctl/poll
dentry_operations revalidate/hash/compare/release
address_space_operations read/write folio、dirty、writepages、invalidate

操作表通常为只读静态对象,VFS 在持有正确对象引用和锁时调用。

7. 引用关系

1
files_struct -> file -> path -> mount + dentry -> inode -> super_block

这些引用形成复杂图,不能按单一树理解。mount namespace、open fd、cwd、mmap、page cache、export handle 都可能延长对象寿命。

8. 回收

  • file:fput/__fput
  • dentry:LRU + shrink_dcache
  • inode:unused LRU + prune_icache
  • super:unmount + deactivate
  • page cache:memory reclaim/truncate/invalidate

泄漏排查应区分 fd 引用、mount 引用、cwd/root、mmap 和内核 pin。

路径解析、打开与元数据操作

路径解析、打开与元数据操作

1. namei.c

namei 把用户路径字符串解析为 struct pathnameidata 保存当前位置、root、flags、符号链接栈和 RCU 状态。

主链:

1
2
3
4
5
6
7
filename_lookup/path_parentat
-> path_init()
-> link_path_walk()
-> walk_component()
-> lookup_fast()
-> lookup_slow() -> inode_operations->lookup
-> complete_walk()

2. RCU-walk 与 ref-walk

RCU-walk 不对每个 dentry/mount 获取常规引用,使用 sequence counter 检测 rename/mount 变化,适合 dcache 热命中。遇到:

  • cache miss;
  • filesystem revalidate 需阻塞;
  • 权限或 automount;
  • 复杂 symlink;
  • sequence 不稳定,

unlazy_walk() 转为 ref-walk。

3. open

1
2
3
4
5
6
7
8
9
10
openat/openat2
-> do_sys_openat2()
-> get_unused_fd_flags()
-> do_filp_open()
-> path_openat()
-> open_last_lookups()
-> do_open()
-> may_open/security_file_open
-> vfs_open()/do_dentry_open()
-> fd_install()

openat2RESOLVE_* 可限制 symlink、mount crossing、beneath/in-root,适合安全沙箱,不能用字符串前缀检查替代。

4. 创建与删除

  • vfs_create() / vfs_mkdir()
  • vfs_unlink() / vfs_rmdir()
  • vfs_link() / vfs_symlink()
  • vfs_mknod()
  • vfs_rename()

VFS 先做 mount read-only、权限、LSM、sticky bit、delegation 等检查,再调用目标目录 inode_operations

5. rename

rename 是路径并发最复杂操作之一:

  • 锁父目录 inode;
  • 防止目录环;
  • 处理 exchange/noreplace/whiteout;
  • 更新 dcache;
  • 调 filesystem transaction;
  • 触发 fsnotify。

跨 superblock rename 返回 EXDEV。用户态需 copy+fsync+unlink 才能跨文件系统移动,但这不具备单步原子性。

6. 符号链接和 mount crossing

path walk 同时处理:

  • absolute/relative path;
  • ...
  • symlink depth;
  • bind mount 和 mountpoint;
  • chroot/root;
  • automount;
  • managed dentry。

容器安全依赖 mount namespace 和 openat2 约束,而不仅是 realpath()

7. 权限与 credential

检查基于调用时 credential、inode mode/ACL、mount flags、idmapped mount、LSM。打开后的 file->f_cred 保存 open 时凭据,后续某些操作不简单使用当前线程新凭据。

8. 性能

路径热点主要受:

  • dcache/inode cache 命中;
  • 目录索引实现;
  • negative dentry;
  • LSM/ACL;
  • 网络文件系统 revalidate;
  • rename 和目录锁竞争;
  • 冷缓存存储延迟。

drop_caches 会破坏正常缓存,不应作为性能优化。

文件描述符、读写与零拷贝

文件描述符、读写与零拷贝

1. FD table

进程 files_struct 指向可扩展 fdtable

  • open bitmap;
  • close-on-exec bitmap;
  • file **fd

查找常用 RCU,更新在 file_lock 下。dup 共享同一 file,因此共享 f_pos 和 file status flags;独立 open 创建不同 file。

2. read/write

1
2
3
4
5
6
7
ksys_read/ksys_write
-> fdget_pos()
-> vfs_read/vfs_write
-> rw_verify_area()
-> new_sync_read/new_sync_write
-> call_read_iter/call_write_iter
-> filesystem file_operations

iov_iter 统一 user iovec、kernel vector、pipe、bvec、xarray 等数据源/目的地。

3. pread/pwrite 与 vectored I/O

  • pread/pwrite 使用显式 offset,不修改共享 f_pos
  • readv/writev 使用多 iovec;
  • preadv2/pwritev2 支持 NOWAIT、DSYNC、HIPRI、APPEND 等 flags,具体支持依文件系统。

4. pipe

pipe.c 使用环形 pipe_buffer

  • anonymous pipe 与 FIFO 共用主体;
  • reader/writer wait queue;
  • 每 buffer 由 pipe_buf_operations 管理 release/try_steal/get;
  • pipe size 可由 fcntl 调整并受系统/用户限制。

5. splice

splice.c 在 file、pipe、socket 间搬运 page/folio 引用,减少用户态往返复制:

1
file -> splice_read -> pipe buffers -> splice_write -> target

“零拷贝”不保证 NIC/块设备或所有 filesystem 完全不复制;fallback 和 checksum/加密都可能产生复制。

6. copy_file_range/remap

  • copy_file_range() 允许文件系统高效复制;
  • remap_file_range() 可由 CoW 文件系统 reflink extent;
  • 不支持时可能 fallback 或返回错误;
  • 跨文件系统语义和限制依内核版本。

7. seek

llseek 修改 f_posSEEK_DATA/SEEK_HOLE 由文件系统解释。稀疏文件复制工具应使用该接口但也要处理不支持情况。

8. fsync

vfs_fsync_range()file_operations->fsync。正确持久化通常要求:

  1. 写文件数据;
  2. fsync(file)
  3. 创建/rename/unlink 后按需要 fsync(parent directory)
  4. 底层设备正确实现 flush/FUA。

close 成功不等同于断电持久。

9. 限制与安全

  • MAX_RW_COUNT 限制单次 I/O;
  • access mode 和 mandatory checks;
  • LSM hooks;
  • append-only/immutable;
  • RLIMIT_FSIZE 和 signal;
  • freeze/read-only;
  • user pointer fault。

挂载命名空间与 fs_context

挂载命名空间与 fs_context

1. Mount tree

内核内部 struct mount 包含公开 vfsmount、父 mount、mountpoint dentry、子树和 propagation 信息。每个 mount namespace 维护自己的拓扑,但 superblock 和 dentry 可被多个 namespace 共享。

2. 旧 mount

1
2
3
4
5
6
mount(2)
-> do_mount()
-> path_mount()
-> do_new_mount()/bind/remount/move
-> filesystem mount/get_tree
-> graft_tree/attach_recursive_mnt

umount2()path_umount(),busy 检查依赖 open file、cwd、子 mount 等引用。

3. 新 mount API

1
2
3
4
5
6
7
8
9
10
fsopen("ext4")
-> fs_context_for_mount()
fsconfig(fsfd, SET_STRING/SET_FD/CREATE, ...)
-> vfs_parse_fs_param()
-> filesystem parse_param
fsmount(fsfd)
-> vfs_get_tree()
-> detached mount fd
move_mount()
-> attach to namespace

新 API 避免把所有参数拼成逗号字符串,并支持 detached mount 和更清晰的错误。

4. fs_context

包含:

  • fs_type
  • ops
  • source;
  • purpose(mount/reconfigure/submount);
  • user/mount namespace;
  • security context;
  • filesystem private state。

fs_parser.c 通过 fs_parameter_spec 校验 string/u32/enum/flag/path/fd 等参数。CONFIG_VALIDATE_FS_PARSER 可在注册时加强描述校验。

5. super 获取

  • block fs:get_tree_bdev()
  • singleton/pseudo:get_tree_single()
  • nodev:get_tree_nodev()
  • key-based reuse:sget_fc() test/set callbacks。

同一设备重复 mount 可能复用 super,但不同 mount 可有不同 mount flags/idmap/path。

6. Propagation

mount 可为:

  • private
  • shared
  • slave
  • unbindable

shared subtree 决定 mount 事件如何传播到 peer/slave。容器 runtime 必须显式管理 propagation,否则可能泄漏 host mount 或看不到期望挂载。

7. idmapped mount

mount 可关联 user namespace/idmap,使 inode uid/gid 在该挂载视图中映射。VFS permission、chown、ACL 和具体文件系统支持均需正确处理,不能等同于递归修改磁盘 owner。

8. Freeze 和 remount

superblock freeze 分阶段阻止写入、page fault、internal write 并同步;用于 snapshot 等。remount/reconfigure 通过 fs_context 修改 super 状态,受 s_umount 和 filesystem 检查保护。

9. 排障

1
2
3
4
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS,PROPAGATION
cat /proc/self/mountinfo
lsns -t mnt
fuser -vm /mountpoint

“target is busy”应查 open fd、cwd/root、mmap 和子挂载,而不是直接使用 lazy unmount 掩盖生命周期问题。