Как узнать, в какое адресное пространство отображается заголовок буфера?
В исходном коде 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 в функции фиксации) Я хочу найти способ пройти через эти 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);
}
}
}
Это не работает, это дает NULL ptr в as_p
то есть нет b_assoc_map
установить для этого buffer_head
, Но я понятия не имею, что такое b_assoc_map
,
ОБНОВЛЕНИЕ 2:
Я пытаюсь получить информацию от handle_t
структура в ext4_mark_iloc_dirty
, handle_t->h_type
есть информация, которая мне нужна Однако, когда я пытаюсь сравнить это значение, указатель NULL вызывает предупреждение ядра. Я думал, что эта структура уникальна для каждого процесса, но похоже, что в ней есть какое-то состояние гонки, пока я точно не знаю.
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)
сделано, а вот journal_head
инициализируется информацией, передаваемой handle_t
,
После этого шага, где 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
и во время коммита я могу получить необходимую информацию, которую хочу.