如何知道缓冲区头映射到哪个地址space?

How to know which address space a buffer head is mapped to?

jbd2 源代码中,文件系统中的任何修改都映射到 handle_t 结构(每个进程),稍后用于映射 buffer_headtransaction_t,这个句柄将成为其中的一部分。

据我所知,当需要修改给定的 buffer_head 时,调用 do_get_write_access() 会将此 buffer_head 映射到交易handle_t 正在参与。 但是,当用这个handle_tbuffer_head映射到transaction_t时,倒数映射就丢失了,也就是我无法追溯到哪个handle_t这个buffer_head属于。

事情是,在jbd2_journal_commit_transaction()期间(提交阶段2b在提交函数中)我想找到一个如果它们与 inode 或 [=57] 有关,则可以遍历这些 buffer_heads 并能够对它们进行分类=]元数据,或inode位图块,或[=例如57=]数据位图块。此外,在源代码的这一点上,buffer_heads 似乎是不透明的,它们只是被发送到存储。

更新 1:

到目前为止,我在 jbd2_journal_commit_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);
        }
    }
}

它不起作用,它在 as_p 中给出 NULL ptr,也就是说,没有为此 buffer_head 设置的 b_assoc_map。但是,我不知道 b_assoc_map.

是什么

更新 2:

我正在尝试从 ext4_mark_iloc_dirtyhandle_t 结构中获取信息。 handle_t->h_type 有我需要的信息。然而,当我尝试比较这个值时,一个 NULL 指针导致了内核警告。我认为这个结构在每个进程中都是独一无二的,但似乎它有一些竞争条件,我还不清楚。

查看了所有与此问题相关的源代码路径后,我得出结论,不做任何更改是不可能的。

基本上,handle_t 结构包含有关事务的信息。稍后,当要在给定的 buffer_head 中进行某些修改时,将调用 jbd2_journal_get_write_access(handle, bh) 以获取对指定缓冲区的写访问权。

jbd2_journal_get_write_access内部创建了journal_head结构体,然后指向这个buffer_head,然而此时handle_t没有关系].

下一步,从jbd2_journal_add_journal_head返回后,调用do_get_write_access(handle, bh),这里用handle_t传递的信息初始化journal_head

在这一步之后,handle_t用于初始化journal_head,那么handle_t就不再需要了。

到这里,一切都已经初始化,现在我们可以移动到提交点了。

jbd2_journal_commit_transaction中,在提交阶段2b属于提交事务的buffer_heads将迭代并提交。

因为buffer_head附加的信息只有journal_head,而journal_head不包含区分buffer_head是哪种的必要信息,然后我得出结论,不修改源码是不可能达到我想要的。

我的解决方案是在 handle_tjournal_head 结构中添加一个新成员来存储索引节点号。所以,当调用 do_get_write_access() 时,我可以像这样过滤操作:

if(handle->h_ino)
    jh->b_ino = handle->h_ino;

所以,我不得不修改 handle_t 以将索引节点号传输到 journal_head,并且在提交时我可以获得我想要的所需信息。