在内核模块中如何从文件描述符获取文件名?

18

我需要从给定的文件描述符中获取文件名,在我编写的小型Linux内核模块中。我尝试了在Getting Filename from file descriptor in C中提供的解决方案,但由于某种原因,它打印出垃圾值(在使用readlink/proc/self/fd/NNN时)。我该怎么做?


可能是sys_readlink fails EFAULT - alternative的重复问题。 - ephemient
1个回答

27

不要调用 SYS_readlink - 当读取这些链接之一时,使用与 procfs 相同的方法。从 fs/proc/base.c 中的 proc_pid_readlink()proc_fd_link() 开始。

总的来说,给定一个 int fd 和一个来自你感兴趣的任务的 struct files_struct *files(你已经引用过),您想做的是:

char *tmp;
char *pathname;
struct file *file;
struct path *path;

spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (!file) {
    spin_unlock(&files->file_lock);
    return -ENOENT;
}

path = &file->f_path;
path_get(path);
spin_unlock(&files->file_lock);

tmp = (char *)__get_free_page(GFP_KERNEL);

if (!tmp) {
    path_put(path);
    return -ENOMEM;
}

pathname = d_path(path, tmp, PAGE_SIZE);
path_put(path);

if (IS_ERR(pathname)) {
    free_page((unsigned long)tmp);
    return PTR_ERR(pathname);
}

/* do something here with pathname */

free_page((unsigned long)tmp);
如果您的代码在进程上下文中运行(例如通过系统调用调用),且文件描述符来自当前进程,则可以使用 current->files 获取当前任务的 struct files_struct *

1
@Siddhant:path_get()path_put()调用是必需的,因为它们会固定路径,以便在您尝试处理它时不会消失(所有struct path包含的只是一对指针,指向struct vfsmountstruct dentry)。 - caf
另外,为什么需要调用 path_get 并获取路径结构的引用? - sherrellbc
有没有将内存中的单个页面分配给使用kmalloc相比的原因或好处?这仅仅是因为您知道一个页面将适合路径数据的最坏情况要求吗?似乎通过简单地使用后者的内存分配方法可以避免整个混乱的IS_ERRPTR_ERR - sherrellbc
@sherrellbc:是的,pagesize 是路径名可能的最大大小,因此使用 kmalloc() 没有意义 - 无论如何都必须使用 IS_ERR() 测试 d_path() 的返回值。调用 path_get() 是必要的,以防止在释放 ->file_lock 后路径消失(因为此时文件可能会被另一个线程关闭)。我们不希望保持 ->file_lock 的持有时间超过必要的时间,因为它是自旋锁。 - caf
事实上,我甚至不确定在持有自旋锁的情况下是否允许调用 d_path() 函数。 - caf
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接