简体   繁体   中英

How to know which address space a buffer head is mapped to?

In the jbd2 source code, any modification in the File System is mapped into a handle_t structure (per process) that later is used to map the buffer_head to the transaction_t which this handle is going to be part of.

As far as I could understand, when a modification to a given buffer_head is needed, then a call to do_get_write_access() is going to map this buffer_head to the transaction that the handle_t is being part of. However, when this handle_t is used to map the buffer_head to the transaction_t , the reciprocal mapping is lost, that is, I cannot track back to which handle_t this buffer_head belonged.

The thing is that, during the jbd2_journal_commit_transaction() ( commit phase 2b in commit function) I want to find a way to walk through these buffer_heads and be able to classify them if they are related to an inode , or to a metadata , or to a inode bitmap block , or an data bitmap block , for example. Furthermore, at this point in the source code, the buffer_heads seems to be opaque, where they are simply sent to the storage.

UPDATE 1:

What I have tried so far was this, in the jbd2_journal_commit_transaction() function, in the commit phase 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);
        }
    }
}

It is not working, it is giving NULL ptr in the as_p , that is, there is no b_assoc_map set for this buffer_head . But, I have no idea what is the b_assoc_map .

UPDATE 2:

I am trying to get the information from the handle_t structure at ext4_mark_iloc_dirty . handle_t->h_type has the information I need. However, when I try to compare this value, a NULL pointer is causing a kernel warning. I thought this structure is unique per process, but seems like it is having some race condition, I don't know clearly yet.

After looking through all the source code path related to this issue, I conclude that there is no way to do it without changing anything.

Basically, the handle_t structure has the information about the transaction. Later, when some modification is going to be done in a given buffer_head , the jbd2_journal_get_write_access(handle, bh) is called to get the write access to the specified buffer.

Inside jbd2_journal_get_write_access the journal_head structure is created, and then it is going to point to this buffer_head , however, at this point there is no relation between handle_t .

Next step, after returning from jbd2_journal_add_journal_head , a call to do_get_write_access(handle, bh) is made, and here the journal_head is initialized with the information passed by the handle_t .

After this step, where the handle_t is used to initialize the journal_head , then the handle_t is not necessary anymore.

Up to here, everything is initialized, now we can move to the commit point.

In jbd2_journal_commit_transaction , at commit phase 2b the buffer_heads belonging to the committing transaction are going to be iterated, and committed.

Because the only information attached to the buffer_head is the journal_head , and the journal_head does not contain the necessary information to distinguish what kind of buffer_head is it, then I conclude that it is not possible to reach what I want without modifying the source code.

My solution was to add a new member to store the inode number in the handle_t , and also in journal_head structure. So, when the do_get_write_access() call is made, I can filter the operation like this:

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

So, I had to modify handle_t to transport the inode number to journal_head , and at commit time I can get the required information that I want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM