Linux Kernel: What is the mapping of block device sectors to memory pages in struct bio?

85 Views Asked by At

I am working on Ubuntu 20.04 (kernel version 5.4.0). I am building a custom device mapper in which I want to cache the read data to a kernel space memory buffer so to serve later reads (similar to a page cache, but in the granularity of block device sectors). In order to do so, I need a mapping from sector_t (block device sector #) to the data.

From my understanding, I should be able to get this information from struct bio defined in linux/blk_types.h. I am referring to this pretty old post. If I understand it correctly, sector_t bi_sector specifies where to read the data in the block device and the data is read into struct bio_vec *bi_io_vec, but how should I know which portion of the data is mapped to which sector? I have some guessing and I need to check if my understanding is correct.

To be more specific, there is only one bi_sector specified in struct bio, but each bio can have read size larger than 512B (the sector size). Does this mean bi_sector is the start sector number of a group of continuous sectors to read from?

Also, how is the read data stored in bi_io_vec? Is it also a linear mapping? by linear mapping, I mean, say, I read 4KB of data, and there are two segments (struct bio_vec) in bi_io_vec, then is the data stored in the memory region (bi_io_vec[0].bv_page + bi_io_vec[0].bv_offset, bi_io_vec[0].bv_page + bi_io_vec[0].bv_offset + bi_io_vec[0].bv_len) and (bi_io_vec[1].bv_page + bi_io_vec[1].bv_offset, bi_io_vec[1].bv_page + bi_io_vec[1].bv_offset + bi_io_vec[1].bv_len) in order?

Also, I order to read get the data from bio, is it not safe to use char *bio_data(struct bio *bio)? Should I iterate each bio_vec and gather the data?

Thanks!

0

There are 0 best solutions below