C 如何知道缓冲头映射到哪个地址空间?

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)期间,我想找到一种方

jbd2源代码中,文件系统中的任何修改都映射到
句柄
结构(每个进程),该结构稍后用于将
缓冲区头
映射到该句柄将成为其一部分的
事务

据我所知,当需要修改给定的
缓冲区头时,调用
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源代码中的任何内容,因此无法在此处放置任何代码。到目前为止,我一直在调查并试图找到一种方法来追踪
缓冲头
句柄
之间的这些关系。我添加了一些我尝试过的代码,但我认为它不是很有用。