Linux下如何检测struct page是否由文件系统中的文件支撑?
检测Linux内核中struct page是否由文件inode支撑
问题背景
编写Linux设备模块时,需要固定用户空间内存页,但部分页面可能来自用户程序通过mmap()创建的非匿名文件映射。这类文件支撑的页面若执行DMA操作可能引发问题,因此需要检测这类页面并区别于匿名页面处理(如拒绝操作、发出警告或调整流程)。已知持有struct page指针,需判断其是否由文件(inode)支撑。
解决方案
可以通过struct page的核心字段和内核提供的辅助宏/函数来判断:
1. 快速区分匿名页与非匿名页:PageAnon()宏
内核提供PageAnon()宏直接判断页面是否为匿名页:
#include <linux/page-flags.h> if (PageAnon(page)) { // 页面是匿名页,按正常逻辑处理 } else { // 页面非匿名,可能由文件支撑,需进一步验证 }
注意:tmpfs/shmem的页面不会被标记为匿名页,因为它们关联了对应的inode。
2. 验证页面是否关联文件inode
非匿名页的page->mapping字段指向struct address_space结构,其中host成员若不为空,则指向该页面对应的struct inode,说明页面由文件支撑:
#include <linux/fs.h> if (!PageAnon(page)) { struct address_space *mapping = page->mapping; if (mapping && mapping->host) { // 页面由文件支撑,mapping->host为对应的inode pr_warn("检测到文件支撑页面,inode编号:%lu\n", mapping->host->i_ino); // 执行自定义处理逻辑:拒绝固定、调整流程等 } else { // 特殊情况:无关联inode的内核内部页面 } }
3. 精准判断普通文件支撑的页面
若需要进一步确认是否为普通文件(而非设备文件、管道等),可通过inode的模式位判断:
if (mapping && mapping->host && S_ISREG(mapping->host->i_mode)) { // 页面由普通磁盘文件支撑 }
注意事项
- 访问
page->mapping前,需确保页面处于稳定状态(比如已通过get_user_pages()固定,或持有page_lock()),避免并发修改导致的异常; - 不同内核版本的字段或宏可能存在细微差异,建议参考对应版本的内核头文件(如
include/linux/page-flags.h、include/linux/fs.h)。
内容的提问来源于stack exchange,提问作者Grigory Rechistov
相关产品推荐
相关产品推荐

