Как узнать, в какое адресное пространство отображается заголовок буфера?

В исходном коде 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и во время коммита я могу получить необходимую информацию, которую хочу.

Другие вопросы по тегам