如何知道缓冲区头映射到哪个地址space?
How to know which address space a buffer head is mapped to?
在 jbd2 源代码中,文件系统中的任何修改都映射到 handle_t
结构(每个进程),稍后用于映射 buffer_head
到 transaction_t
,这个句柄将成为其中的一部分。
据我所知,当需要修改给定的 buffer_head
时,调用 do_get_write_access()
会将此 buffer_head
映射到交易handle_t
正在参与。
但是,当用这个handle_t
将buffer_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_dirty
的 handle_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_t
和 journal_head
结构中添加一个新成员来存储索引节点号。所以,当调用 do_get_write_access()
时,我可以像这样过滤操作:
if(handle->h_ino)
jh->b_ino = handle->h_ino;
所以,我不得不修改 handle_t
以将索引节点号传输到 journal_head
,并且在提交时我可以获得我想要的所需信息。
在 jbd2 源代码中,文件系统中的任何修改都映射到 handle_t
结构(每个进程),稍后用于映射 buffer_head
到 transaction_t
,这个句柄将成为其中的一部分。
据我所知,当需要修改给定的 buffer_head
时,调用 do_get_write_access()
会将此 buffer_head
映射到交易handle_t
正在参与。
但是,当用这个handle_t
将buffer_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_dirty
的 handle_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_t
和 journal_head
结构中添加一个新成员来存储索引节点号。所以,当调用 do_get_write_access()
时,我可以像这样过滤操作:
if(handle->h_ino)
jh->b_ino = handle->h_ino;
所以,我不得不修改 handle_t
以将索引节点号传输到 journal_head
,并且在提交时我可以获得我想要的所需信息。