【问题标题】:How to know which address space a buffer head is mapped to?如何知道缓冲区头映射到哪个地址空间?
【发布时间】:2018-05-23 23:09:43
【问题描述】:

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

据我所知,当需要对给定的buffer_head 进行修改时,调用do_get_write_access() 会将这个buffer_head 映射到handle_t 所属的事务。 但是,当使用这个handle_tbuffer_head 映射到transaction_t 时,倒数映射就丢失了,也就是说,我无法追溯这个buffer_head 属于哪个handle_t

问题是,在jbd2_journal_commit_transaction()commit phase 2b in commit function)我想找到一种方法来遍历这些buffer_heads并成为如果它们与 inode元数据 相关,则能够对它们进行分类>inode 位图块,或 数据位图块。此外,在源代码的这一点上,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 指针会导致内核警告。我认为这个结构在每个进程中都是独一无二的,但似乎它有一些竞争条件,我还不清楚。

【问题讨论】:

  • 更多代码有助于理解问题。
  • 就是这样,我没有在jbd2源代码中做任何改动,所以这里没有办法放任何代码。到目前为止,我一直在调查并试图找到一种方法来追踪 buffer_headhandle_t 之间的这些关系。
  • 好吧,我添加了一些我尝试过的代码,但我认为它不是很有用。

标签: c memory-management ext4 journaling


【解决方案1】:

查看了与这个问题相关的所有源代码路径后,我得出的结论是,不改变任何东西是没有办法的。

基本上,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是什么类型的必要信息,那么我得出的结论是不可能无需修改源代码即可达到我想要的效果。

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

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

因此,我不得不修改handle_t 以将inode 号传输到journal_head,并且在提交时我可以获得所需的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2023-03-03
    • 2012-03-02
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多