如何在Linux内核中recursion读取目录的内容?

我想实现一个树遍历函数,它打印给定的目录在内核中的所有内容。 我知道如何在用户空间做到这一点,但我的要求是在内核空间。 为此,我正在研究vfs_readdir函数,并对它的用法有点困惑。 说我会从其他内核模块调用我的遍历函数,这意味着请求不会通过用户空间。 现在的问题是如何调用vfs_readdir并使用该信息recursion地parsing给定的目录。 从vfs_readdir定义extern int vfs_readdir(struct file *,filldir_t,void *);

我可以使用像filp_open()这样的函数从文件path中获取struct file *,根据我的理解filldir_t是一个函数指针,用于callback函数,填充由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(文件,但填充); 这是否在内部做一些事情,并填写参数来调用callback函数? 现在这是一个层次。 我该如何recursion地打印给定目录中的所有文件? 我想我需要在自己的callback函数中做一些事情,但是我只有一些关于通过这个callback函数传递的文件的信息,比如文件名,inode号等等。 我怎么知道它是否是常规的文件或目录使用这个信息。 我的意思是我没有关于文件的dentry或inode数据结构。 任何build议如何做到这一点? 另外,如果我想在callback函数中删除一个文件,我可以通过使用inode号码(这是我除了名称之外的callback),我应该怎么做?

vfs_readdir ,例如从readdir系统调用实现中调用 。 它使用fillonedir作为回调fillonedir ,这反过来可以轻松地被忽略:它的第一个参数只是vfs_readdir最后一个参数,所有其他参数( namenamelenoffsetinod_type )被复制到用户空间中。

请注意, vfs_readdir回调是通过inode mutex locked( inode->i_mutex )执行的。 可能你不应该打开子目录介入回调。 而应保存子目录的名称,并 vfs_readdir调用打开它。 这与您在用户空间中遍历目录树的方式非常相似。

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

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