Linux内核重启后dentry消失及inode_operations清空问题求助
问题根因
struct dentry是VFS层的内存缓存结构,不会持久化存储。系统重启后只有被用户态/内核态主动访问过的目录项才会被加载到父dentry的d_subdirs链表中,未被访问的子目录dentry不会出现在该链表中,所以你直接遍历d_subdirs只能看到根目录f1,看不到未被访问的f2、f3。- 你运行时绑定的
struct inode_operations是内存态数据,没有写入文件系统的持久化元数据。重启后内核从磁盘加载inode时,会默认赋值对应文件系统的原生操作回调,你之前手动绑定的自定义操作自然会丢失。
修复方案
1. 修正目录遍历逻辑
不要直接遍历d_subdirs链表,改用VFS标准的目录迭代接口iterate_dir,该接口会自动触发未加载目录项的元数据加载,能返回所有实际存在的子项,参考实现:
// 自定义迭代回调处理每个子项 static int iterate_callback(struct dir_context *ctx, const char *name, int namlen, loff_t offset, u64 ino, unsigned int d_type) { if (d_type == DT_DIR) { printk(KERN_INFO "%s <- dir (subdir f1)\n", name); } return 0; } // 遍历逻辑替换为 struct dir_context ctx = {.actor = iterate_callback}; err = kern_path(FULL_MAIN_DIR_NAME, LOOKUP_FOLLOW, &tmp_root); if (err) return err; printk(KERN_DEBUG "%s <- dir\n", tmp_root.dentry->d_name.name); err = iterate_dir(tmp_root.dentry->d_inode, &ctx); path_put(&tmp_root);
2. 解决inode_operations丢失问题
根据你的实现场景二选一:
- 如果你是开发自定义文件系统:将自定义
i_op的赋值逻辑写到文件系统超级块操作的alloc_inode/read_inode回调中,每次inode从磁盘加载到内存时内核都会自动绑定你的自定义操作,重启不会丢失。 - 如果你是在现有通用文件系统上扩展功能:不要直接修改内存中inode的
i_op指针,改用堆叠文件系统(类似OverlayFS的分层逻辑)在堆叠层统一实现自定义操作,只要系统启动时自动挂载你的堆叠文件系统,自定义操作就不会丢失;轻量需求也可以用eBPF hook VFS相关系统调用实现自定义逻辑。
3. 补全现有创建逻辑的缺失
你当前的目录创建代码中vfs_mkdir失败后的错误处理为空,必须补全错误分支的资源释放逻辑,避免内存泄漏:
err = vfs_mkdir(d_inode(path.dentry), dentry, mode); if (err) { done_path_create(&path, dentry); return err; }
内容的提问来源于stack exchange,提问作者QQa
相关产品推荐
相关产品推荐

