内核模块中如何获取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.
相关产品推荐
相关产品推荐

