2

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

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

问题是,在jbd2_journal_commit_transaction()提交功能中的提交阶段 2b)期间,我想找到一种方法来遍历这些buffer_heads并能够对它们进行分类,如果它们与inodemetadatainode 位图块相关,或数据位图块,例如。此外,在源代码的这一点上,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);
        }
    }
}

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

更新 2:

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

4

1 回答 1

0

在查看了与此问题相关的所有源代码路径后,我得出结论,如果不进行任何更改,就无法做到这一点。

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

内部结构jbd2_journal_get_write_accessjournal_head创建,然后它会指向 this buffer_head,然而,此时 之间没有任何关系handle_t

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

在这一步之后,其中handle_t用于初始化journal_head,则handle_t不再需要 。

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

jbd2_journal_commit_transaction,在提交阶段 2bbuffer_heads属于提交事务的将被迭代并提交。

因为附在的唯一信息buffer_headjournal_head,而journal_head不包含区分buffer_head它是什么类型的必要信息,所以我得出结论,不修改源代码是不可能达到我想要的。

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

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

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

于 2017-12-12T11:45:47.233 回答