gpt4 book ai didi

linux - 如何在 Linux 内核中递归读取目录的内容?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:14:20 31 4
gpt4 key购买 nike

我想实现一个树遍历函数,打印给定目录的所有内容在内核中。我知道如何在用户空间中执行此操作,但我的要求是在内核空间中执行此操作。为此,我正在研究 vfs_readdir 函数并且对其用法有点困惑。假设我将从其他内核模块调用我的遍历函数,这意味着请求不会来自用户空间。现在的问题是如何调用 vfs_readdir 并使用该信息递归解析给定目录。从 vfs_readdir 的定义extern int vfs_readdir(struct file *, filldir_t, void *);

我可以使用 filp_open() 之类的函数从文件路径中获取结构文件 *,并且根据我的理解,filldir_t 是一个指向回调函数的函数指针,它填充由 void * 指向的用户提供的缓冲区。但就我而言,我不需要将任何信息传递给用户。我应该在 void * 地方传递什么?查看 filldir 函数定义

static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned int d_type);

这个函数的参数从哪里来。我的假设是 vfs_readdir 依次调用 file->f_op_readdir(file,but,filler);这是否在内部执行某些操作并填写参数以调用回调函数?现在这是一个级别。我应该怎么做才能递归打印给定目录中的所有文件。我想我需要在我自己的回调函数中做一些事情。但是我只有一些关于通过这个回调函数传递的文件的信息,比如文件名、 inode 号等。我如何使用此信息知道它是常规文件还是目录。我的意思是我没有关于该文件的 dentry 或 inode 数据结构。任何建议如何做到这一点?另外,如果我想在回调函数中删除一个文件,我可以通过使用 inode 编号(这是我在回调中除了名称之外的内容)来实现吗?我应该怎么做?

最佳答案

vfs_readdir 被调用,例如,来自 readdir syscall implementation .它使用 fillonedir 作为回调,这反过来很容易理解:它的第一个参数只是 vfs_readdir 的最后一个参数,所有其他参数(name , namelen, offset, ino, d_type) 按原样复制到用户空间。

请注意,vfs_readdir 的回调是在 inode mutex locked(inode->i_mutex) 的情况下执行的。可能您不应该打开包含该回调的子目录。相反,将子目录的名称保存在某处,并在 vfs_readdir 调用之后打开它。这与您在用户空间中遍历目录树的方式非常相似。

请注意,自 3.11 版以来,内核使用另一种方式迭代目录中的条目:iterate_dir。它的第二个参数结合了回调和回调特定参数,还包括文件中的当前位置。除了第一个参数外,回调接受与以前相同的参数。

至于 ino 参数,您不能将它用于打开给定的 inode(内核只是没有通过 inode 编号打开文件的机制)。使用 filp_open 或类似的。

关于linux - 如何在 Linux 内核中递归读取目录的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32617244/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com