C 如何知道缓冲头映射到哪个地址空间?
在jbd2源代码中,文件系统中的任何修改都映射到C 如何知道缓冲头映射到哪个地址空间?,c,memory-management,ext4,journaling,C,Memory Management,Ext4,Journaling,在jbd2源代码中,文件系统中的任何修改都映射到句柄结构(每个进程),该结构稍后用于将缓冲区头映射到该句柄将成为其一部分的事务 据我所知,当需要修改给定的缓冲区头时,调用do\u get\u write\u access()会将该缓冲区头映射到句柄所属的事务。 但是,当使用此句柄将缓冲区头映射到事务时,反向映射将丢失,也就是说,我无法跟踪此缓冲区头属于哪个句柄 问题是,在jbd2\u journal\u commit\u transaction()(提交函数中的提交阶段2b)期间,我想找到一种方
句柄
结构(每个进程),该结构稍后用于将缓冲区头
映射到该句柄将成为其一部分的事务
据我所知,当需要修改给定的缓冲区头时,调用do\u get\u write\u access()
会将该缓冲区头映射到句柄
所属的事务。
但是,当使用此句柄
将缓冲区头
映射到事务
时,反向映射将丢失,也就是说,我无法跟踪此缓冲区头
属于哪个句柄
问题是,在jbd2\u journal\u commit\u transaction()
(提交函数中的提交阶段2b)期间,我想找到一种方法来遍历这些缓冲区头
,如果它们与索引节点或元数据相关,就能够对它们进行分类,或到索引节点位图块,或数据位图块。此外,在源代码的这一点上,buffer_heads
似乎是不透明的,它们只是被发送到存储器中
更新1:
到目前为止,我在jbd2\u journal\u commit\u transaction()
函数的提交阶段2b中尝试了这一点
struct journal_head *jh;
...
jh = commit_transaction->t_buffers;
if(jh->b_jlist == BJ_Metadata) {
struct buffer_head *bh_p = NULL;
bh_p = jh2bh(jh);
if(!bh_p) printk(KERN_DEBUG "Null ptr in bh_p\n");
else {
struct address_space *as_p = NULL;
if((as_p = bh_p->b_assoc_map) == NULL)
printk(KERN_DEBUG "Null ptr in as_p\n");
else {
struct inode *i_p = NULL;
if(i_p) printk(KERN_DEBUG "Inode is %lu\n", i_p->i_ino);
}
}
}
它不工作,它在中以p的形式给出空ptr,也就是说,没有为该缓冲头设置b\u assoc\u map
。但是,我不知道什么是b\u assoc\u map
更新2:
我试图从ext4\u mark\u iloc\u dirty
的handle\u t
结构中获取信息handle\u t->h\u type
包含我需要的信息。然而,当我尝试比较这个值时,一个空指针会导致内核警告。我认为这个结构在每个进程中都是唯一的,但它似乎有一些竞争条件,我还不清楚。在查看了与此问题相关的所有源代码路径后,我得出结论,如果不做任何更改,就无法做到这一点
基本上,handle\u t
结构包含有关事务的信息。稍后,当要在给定的缓冲区\u头
中进行某些修改时,将调用jbd2\u日志\u get\u write\u访问(handle,bh)
,以获取对指定缓冲区的写访问权
在jbd2\u journal\u get\u write\u access
内部,创建了journal\u head
结构,然后它将指向此缓冲区\u head
,但是,此时句柄与之间没有关系
下一步,从jbd2\u journal\u add\u journal\u head
返回后,调用do\u get\u write\u access(handle,bh)
,在这里用句柄传递的信息初始化journal\u head
在此步骤之后,如果使用句柄
初始化日志头
,则不再需要句柄
到目前为止,一切都已初始化,现在我们可以移动到提交点
在jbd2\u journal\u commit\u transaction
中,在提交阶段2b属于提交事务的缓冲区头将被迭代并提交
由于附加到缓冲头
的唯一信息是日志头
,并且日志头
不包含必要的信息来区分它是什么类型的缓冲头
,因此我得出结论,不修改源代码就不可能达到我想要的目的
我的解决方案是添加一个新成员,将inode编号存储在句柄中,也存储在日志头结构中。因此,当调用do\u get\u write\u access()
时,我可以像这样过滤操作:
if(handle->h_ino)
jh->b_ino = handle->h_ino;
因此,我不得不修改handle\u t
以将inode编号传输到journal\u head
,在提交时我可以获得所需的信息。多一点代码将有助于理解问题。这就是问题所在,我没有更改jbd2源代码中的任何内容,因此无法在此处放置任何代码。到目前为止,我一直在调查并试图找到一种方法来追踪缓冲头
和句柄
之间的这些关系。我添加了一些我尝试过的代码,但我认为它不是很有用。