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

C 如何从内核模块内的文件描述符获取文件名?,c,linux,linux-kernel,kernel-module,C,Linux,Linux Kernel,Kernel Module,我需要从给定的文件描述符中获取文件名,该描述符位于我编写的一个小型linux内核模块中。我尝试了在中给出的解决方案,但出于某种原因,它会打印垃圾值(在解决方案中提到的readlink上使用/proc/self/fd/NNN)。我该怎么做?不要调用SYS\u readlink-使用与读取其中一个链接时procfs相同的方法。从proc\u pid\u readlink()和fs/proc/base.c中的proc\u fd\u link()中的代码开始 概括地说,给定您感兴趣的任务(您已经参考了该

我需要从给定的文件描述符中获取文件名,该描述符位于我编写的一个小型linux内核模块中。我尝试了在中给出的解决方案,但出于某种原因,它会打印垃圾值(在解决方案中提到的
readlink
上使用
/proc/self/fd/NNN
)。我该怎么做?

不要调用
SYS\u readlink
-使用与读取其中一个链接时
procfs
相同的方法。从
proc\u pid\u readlink()
fs/proc/base.c
中的
proc\u fd\u link()
中的代码开始

概括地说,给定您感兴趣的任务(您已经参考了该任务)中的
int fd
struct files\u 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);

如果您的代码在流程上下文中运行(例如通过系统调用调用),并且文件描述符来自当前流程,那么您可以对当前任务的
struct files\u struct*

使用
current->files
。成功了。谢谢不过还是有个简单的问题。
path\u get
path\u put
调用的作用是什么(因为删除它们对我的程序没有多大影响)?还有,你知道为什么
sys\u readlink
不起作用吗?@Siddhant:
path\u get()
path\u put()
调用是正确性所必需的,因为它们会锁定路径,这样在你尝试使用它时它就不会消失(结构路径
包含的所有内容都是一对指针,指向结构vfsmount
和结构dentry)还有,为什么需要调用
path\u get
并获取对路径结构的引用?与使用
kmalloc
相比,从内存中分配一个页面有什么原因或好处吗?仅仅是因为您知道一个页面将适合路径数据的最坏情况要求吗?看起来
的整个混乱情况更糟R
PTR\u ERR
可以通过简单地使用后一种内存分配方法来避免。@sherrelbc:对,页面大小是路径名可能大小的上限,因此使用
kmalloc()
没有任何意义,
d\u path()
的返回值必须使用
is\u ERR()进行测试
不管怎样。有必要调用
path\u get()
以防止释放
->file\u lock
后路径消失(因为此时,文件可能会被另一个线程并行关闭)。我们不希望保持
->file\u lock
的时间过长,因为它是一个自旋锁。