我正在阅读LDD3并弄乱内核源代码。目前,我正在尝试完全理解struct bio
及其用法。
到目前为止我读过的内容:
https://lwn.net/images/pdf/LDD3/ch16.pdf
http://www.makelinux.net/books/lkd2/ch13lev1sec3
https://lwn.net/Articles/26404/
(a part of) https://www.kernel.org/doc/Documentation/block/biodoc.txt
如果我理解正确,struct bio
描述了在块设备和系统内存之间传输某些块的请求。规则是单个struct bio只能引用一组连续的磁盘扇区,但系统内存可以是非连续的,并由<page,len,offset>
的向量表示,对吗?也就是说,单个struct bio请求bio_sectors(bio)
(众多)扇区的读/写,从扇区bio->bi_sector
开始。传输的数据大小受实际设备,设备驱动程序和/或主机适配器的限制。我可以通过queue_max_hw_sectors(request_queue)
获得该限制,对吗?因此,如果我继续提交在磁盘扇区中连续的bio
,则I / O调度程序/电梯会将这些bio
合并为一个sigle,直到达到该限制为止, ?
此外,bio->size
必须是512的倍数(或等效的扇区大小),以便bio_sectors(bio)
是整数,对吗?
此外,这些bio_sectors(bio)
扇区将被移入/移出系统内存,而内存则指代struct page
s。由于<page,len,offset>
和磁盘扇区之间没有特定的映射,我假设隐式bio->bi_io_vec
按顺序或外观提供服务。也就是说,第一个磁盘扇区(从bio->bi_sector
开始)将从/ {读到bio->bi_io_vec[0].bv_page
然后bio->bi_io_vec[1].pv_page
等写入。是吗?如果是这样,bio_vec->bv_len
应该始终是sector_size或512的倍数吗?由于页面通常为4096字节,bv_offset
应该是{0,512,1024,1536,...,3584,4096}
中的一个吗?我的意思是,例如,请求在偏移量为200的页面上写入100字节是否有意义?
此外,bio.bio_phys_segments
的含义是什么?为什么它与bio.bi_vcnt
不同? bio_phys_segments
定义为&#34;此BIO中包含的物理段数&#34;。我们称之为&#39;物理细分&#39;是不是三<page,len,offset>
?
最后,如果struct bio
如此复杂和强大,我们为什么要创建struct bio
列表并将它们命名为struct request
并在request_queue
中对它们进行排队?为什么没有bio_queue
用于存储每个struct bio
的块设备,直到它被服务为止?
我有点困惑所以任何文档的答案或指针都会非常有用!提前谢谢你:)
答案 0 :(得分:3)
what is the meaning of bio.bio_phys_segments?
通用块图层可以合并不同的段。当内存中的页面框架和磁盘上相邻的磁盘数据块是连续的时,结果合并操作会创建更大的内存区域 这被称为物理段。
Then what is bi_hw_segments?
允许在通过专用总线电路处理总线地址和物理地址之间的映射的体系结构上进行另一种合并操作。由这种合并操作产生的存储区称为硬件段。在80 x 86架构中,总线地址和物理地址之间没有这种动态映射,硬件段总是与物理段重合。
That is, the first disk sectors (starting at bio->bi_sector) will be written from / read to bio->bi_io_vec[0].bv_page then bio->bi_io_vec[1].pv_page etc.
Is that right? If so, should bio_vec->bv_len be always a multiple of sector_size or 512? Since a page is usually 4096bytes, should bv_offset be exactly one of {0,512,1024,1536,...,3584,4096}? I mean, does it make sense for example to request 100bytes to be written on a page starting at offset 200?
bi_io_vec包含IO的页面框架。 bv_offset是页面框架中的偏移量。在磁盘上实际写入/读取之前,每个东西都映射到扇区,因为磁盘处理扇区。这并不意味着长度必须在多个扇区中。因此,这将导致未对齐的读/写,这是由底层设备驱动程序处理的。
if a struct bio is so complex and powerfull, why do we create lists of struct bio and name them struct request and queue them requests in the request_queue? Why not have a bio_queue for the block device where each struct bio is stored until it is serviced?
请求队列是每个设备结构并负责刷新。每个块设备都有自己的请求队列。生物结构是IO的通用实体。如果将request_queue特征结合到bio中,那么您将创建一个单一的全局bio_queue,并且结构太重。不是个好主意。所以基本上这两种结构在IO操作的上下文中有不同的用途。
希望它有所帮助。