linux kernel, struct bio : 页面如何 read/written
linux kernel, struct bio : how pages are read/written
我正在阅读 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)
(多个)扇区中的 reading/writing,从扇区 bio->bi_sector
开始。传输的数据大小受实际设备、设备驱动程序、and/or 主机适配器的限制。我可以通过 queue_max_hw_sectors(request_queue)
获得该限制,对吗?因此,如果我继续提交结果证明在磁盘扇区中是连续的 bio
s,I/O scheduler/elevator 会将这些 bio
s 合并为一个,直到该限制达到了吧?
此外,bio->size
必须是 512(或等效扇区大小)的倍数,以便 bio_sectors(bio)
是一个整数,对吗?
此外,这些 bio_sectors(bio)
个扇区将被移动 to/from 系统内存,我们所说的内存是指 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}
之一吗?我的意思是,例如请求将 100 字节写入从偏移量 200 开始的页面上是否有意义?
此外,bio.bio_phys_segments
是什么意思,为什么它与 bio.bi_vcnt
不同? bio_phys_segments
定义为 "The number of physical segments contained within this BIO"。三重 <page,len,offset>
不就是我们所说的 'physical segment' 吗?
最后,如果 struct bio
如此复杂和强大,为什么我们要创建 struct bio
的列表并将它们命名为 struct request
并将它们的请求排队到 request_queue
?为什么不为每个 struct bio
存储直到被服务的块设备设置一个 bio_queue
?
我有点困惑,所以任何答案或对文档的指示都会非常有用!提前谢谢你:)
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 是页面框架中的偏移量。在磁盘上的实际 writing/reading 之前,每个东西都映射到扇区,因为磁盘在扇区中交易。这并不意味着长度必须是扇区的倍数。所以这将导致未对齐的 read/writes 由底层设备驱动程序处理。
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?
请求队列是每个设备结构并负责刷新。每个块设备都有自己的请求队列。 bio 结构是 IO 的通用实体。如果您将 request_queue 功能合并到 bio 中,那么您将创建一个单一的全局 bio_queue 并且该结构太重了。这不是个好主意。所以基本上这两个结构在 IO 操作的上下文中有不同的用途。
希望对您有所帮助。
我正在阅读 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)
(多个)扇区中的 reading/writing,从扇区 bio->bi_sector
开始。传输的数据大小受实际设备、设备驱动程序、and/or 主机适配器的限制。我可以通过 queue_max_hw_sectors(request_queue)
获得该限制,对吗?因此,如果我继续提交结果证明在磁盘扇区中是连续的 bio
s,I/O scheduler/elevator 会将这些 bio
s 合并为一个,直到该限制达到了吧?
此外,bio->size
必须是 512(或等效扇区大小)的倍数,以便 bio_sectors(bio)
是一个整数,对吗?
此外,这些 bio_sectors(bio)
个扇区将被移动 to/from 系统内存,我们所说的内存是指 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}
之一吗?我的意思是,例如请求将 100 字节写入从偏移量 200 开始的页面上是否有意义?
此外,bio.bio_phys_segments
是什么意思,为什么它与 bio.bi_vcnt
不同? bio_phys_segments
定义为 "The number of physical segments contained within this BIO"。三重 <page,len,offset>
不就是我们所说的 'physical segment' 吗?
最后,如果 struct bio
如此复杂和强大,为什么我们要创建 struct bio
的列表并将它们命名为 struct request
并将它们的请求排队到 request_queue
?为什么不为每个 struct bio
存储直到被服务的块设备设置一个 bio_queue
?
我有点困惑,所以任何答案或对文档的指示都会非常有用!提前谢谢你:)
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 是页面框架中的偏移量。在磁盘上的实际 writing/reading 之前,每个东西都映射到扇区,因为磁盘在扇区中交易。这并不意味着长度必须是扇区的倍数。所以这将导致未对齐的 read/writes 由底层设备驱动程序处理。
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?
请求队列是每个设备结构并负责刷新。每个块设备都有自己的请求队列。 bio 结构是 IO 的通用实体。如果您将 request_queue 功能合并到 bio 中,那么您将创建一个单一的全局 bio_queue 并且该结构太重了。这不是个好主意。所以基本上这两个结构在 IO 操作的上下文中有不同的用途。
希望对您有所帮助。