如何将多个 struct BIO 组合成一个 struct 请求?
我正在研究 Linux 内核版本 2.6.39.1,并正在开发块设备驱动程序。在这方面,我想将多个 struct bio 组合成一个 struct request ,然后将其添加到 request_queue 中以供处理设备驱动程序,即 -- scsi_request_fn()
。
我尝试使用struct bio
的->bi_next
字段来链接我编写的多个struct bio
,从而创建一个链接列表struct bio
。当我调用submit_bio()
将bio提交到块设备层进行I/O时,this BUG_ON()
被触发,因为代码期望 bio->bi_next
NULL
。
在将多个struct bio
发送到较低层进行服务之前,有没有办法将多个struct bio
链接到单个struct request
中?
I'm working on Linux kernel version 2.6.39.1, and am developing a block device driver. In this regard, I want to combine multiple struct bio
s into a single struct request
, which is then added to the request_queue
for processing by the device driver, namely -- scsi_request_fn()
.
I tried using the ->bi_next
field of struct bio
to link multiple struct bio
s that I have composed, thereby creating a linked list of struct bio
s. When I call submit_bio()
to submit a bio to the block device layer for I/O, this BUG_ON()
is triggered because the code expects bio->bi_next
to be NULL
.
Is there a way to link several struct bio
s into a single struct request
before sending it to lower layers for servicing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定如何将多个 struct bio 串在一起,但您可能想看看 libsas 和 aic94xx 驱动程序用于替代方法。文档不多,但是 libsas 文档 将其描述为
实际上,这使块层(又名 BIO)保持不变,但多个请求在驱动程序层累积并一起提交。
I'm not sure how to string multiple
struct bio
together, but you might want to take a look at the "task collector" implementation in libsas and the aic94xx driver for an alternate approach. There isn't much documentation, but the libsas documentation describes it asEffectively, this lets the block layer (a.k.a. BIO) remain unchanged, but multiple requests are accumulated at the driver layer and submitted together.
感谢您的回复,@ctuffli。我决定使用与所描述的结构类似的结构 在这里。基本上,我分配一个 struct packet_data ,它将包含指向所有 struct bio 的指针,这些指针应合并形成一个 struct bio (稍后上,一个
结构请求
)。此外,我还在这个struct packet_data
中存储了一些驱动程序相关信息。接下来,我分配一个新的struct bio
(我们称之为“merged_bio”),复制原始 BIO 列表中的所有页面,然后创建merged_bio->bi_private
指向struct packet_data
。最后一个 hack 将使我能够跟踪原始 BIO 列表,并且在merged_bio
完成后,还可以调用bio_endio()
来结束所有单独 BIO 上的 I/O。成功转移。不确定这是否是最明智的方法,但它达到了我的预期! :^)
Thanks for the reply, @ctuffli. I've decided to use a structure similar to the one described here. Basically, I allocate a
struct packet_data
which would contain pointers to allstruct bio
s that should be merged to form one singlestruct bio
(and later on, one singlestruct request
). In addition, I store some driver related information as well in thisstruct packet_data
. Next, I allocate a newstruct bio
(lets call it "merged_bio"), copy all the pages from the list of original BIOs and then make themerged_bio->bi_private
point to thestruct packet_data
. This last hack would allow me to keep track of the list of original BIOs, and also callbio_endio()
to end I/O on all individual BIOs once themerged_bio
has been successfully transferred.Not sure if this is the smartest way to do this, but it does what I intended! :^)