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

内核模块中如何获取dentry绝对路径并解析符号链接目标?

内核中获取符号链接dentry的目标方法

问题分析

你当前的实现依赖dentry_path_raw获取路径,但该函数返回的是相对于vfsmount的路径(如/self对应/proc/self的相对路径),导致kern_path无法正确解析。核心问题是缺少dentry所属的vfsmount信息,无法生成绝对路径;此外,通过字符串路径中转的方式也并非最优解。

方案一:构造完整Path获取绝对路径

每个struct dentry都包含d_mnt成员,指向它所属的vfsmount。通过将dentry与对应的vfsmount组合成struct path,即可用d_absolute_path生成可被kern_path正确解析的绝对路径。

修改后的代码示例:

int print_dentry(struct dentry *d) {
    struct path orig_path, target_path;
    char *buffer;
    char *path_name;
    int ret;

    buffer = (char *)__get_free_page(GFP_KERNEL);
    if (!buffer)
        return -ENOMEM;

    // 构造原始dentry对应的完整path(dentry + 所属vfsmount)
    orig_path.mnt = d->d_mnt;
    orig_path.dentry = d;

    // 获取绝对路径
    path_name = d_absolute_path(&orig_path, buffer, PAGE_SIZE);
    if (IS_ERR(path_name)) {
        printk(KERN_ERR "Failed to get absolute path: %ld\n", PTR_ERR(path_name));
        free_page((unsigned long)buffer);
        return PTR_ERR(path_name);
    }

    // 用绝对路径解析目标path
    ret = kern_path(path_name, LOOKUP_FOLLOW, &target_path);
    if (ret) {
        printk(KERN_ERR "kern_path returned %d for path \"%s\", inode %ld\n",
               ret, path_name, d->d_inode->i_ino);
        free_page((unsigned long)buffer);
        return ret;
    }

    printk_once(KERN_INFO "Path %s -> target inode %ld\n",
                path_name, target_path.dentry->d_inode->i_ino);

    // 释放kern_path获取的path引用
    path_put(&target_path);
    free_page((unsigned long)buffer);
    return 0;
}

方案二:直接跟随符号链接(推荐)

无需生成路径字符串,直接在内核空间调用vfs_follow_link解析符号链接,获取目标dentry,效率更高且避免路径解析的潜在问题。

代码示例:

int print_dentry(struct dentry *d) {
    struct path target_path;
    int ret;

    // 先判断当前dentry是否为符号链接
    if (!S_ISLNK(d->d_inode->i_mode)) {
        printk(KERN_INFO "Not a symlink, inode %ld\n", d->d_inode->i_ino);
        return 0;
    }

    // 构造原始dentry对应的path
    struct path orig_path = {.mnt = d->d_mnt, .dentry = d};

    // 跟随符号链接获取目标path
    ret = vfs_follow_link(&orig_path, &target_path);
    if (ret) {
        printk(KERN_ERR "Failed to follow symlink: %d\n", ret);
        return ret;
    }

    printk_once(KERN_INFO "Symlink target inode %ld\n",
                target_path.dentry->d_inode->i_ino);

    // 释放目标path的引用,避免内存泄漏
    path_put(&target_path);
    return 0;
}

关键注意事项

  • 所有通过内核函数获取的struct path都需要调用path_put释放引用,防止内存泄漏。
  • vfs_follow_link会自动处理符号链接的跳转,无需手动解析路径字符串。

内容的提问来源于stack exchange,提问作者Maxime B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:25:48