You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核重启后dentry消失及inode_operations清空问题求助

问题根因

  1. struct dentry 是VFS层的内存缓存结构,不会持久化存储。系统重启后只有被用户态/内核态主动访问过的目录项才会被加载到父dentry的d_subdirs链表中,未被访问的子目录dentry不会出现在该链表中,所以你直接遍历d_subdirs只能看到根目录f1,看不到未被访问的f2、f3。
  2. 你运行时绑定的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:45:03