我想实现一个树遍历函数,打印给定目录的所有内容
在内核中。我知道如何在用户空间中执行此操作,但我的要求是在内核空间中执行此操作。
为此,我正在研究 vfs_readdir 函数,并且对其用法有点困惑。
假设我将从其他内核模块调用我的遍历函数,这意味着请求不会通过用户空间。现在的问题是如何调用 vfs_readdir 并使用该信息递归解析给定目录。来自 vfs_readdir 的定义
extern int vfs_readdir(struct file *, filldir_t, void *);
我可以使用 filp_open() 等函数从文件路径获取 struct file * ,根据我的理解, 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 系统调用实现。它用fillonedir
作为回调,这又很容易理解:它的第一个参数只是最后一个参数vfs_readdir
,所有其他参数(name
, namelen
, offset
, ino
, d_type
)按原样复制到用户空间。
请注意,该回调vfs_readdir
在 inode 互斥体锁定的情况下执行(inode->i_mutex
)。也许您不应该打开包含该回调的子目录。相反,将子目录的名称保存在某处,然后打开它after vfs_readdir
称呼。这与在用户空间中遍历目录树的方式非常相似。
请注意,从版本 3.11 开始,内核使用另一种方式来迭代目录中的条目:iterate_dir
。它的第二个参数结合了回调和回调特定的参数,并且还包括文件中的当前位置。除了第一个参数之外,回调接受与以前相同的参数。
As for ino
参数,你不能使用它来打开给定的 inode(内核没有机制open文件(按索引节点号)。使用filp_open
或类似的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)