我正在开发块分层设备驱动程序。因此,我拦截了 WRITE 请求并加密了数据,并在end_bio()
例程中解密了数据(在处理和 READ 请求期间)。
因此,所有功能都可以在单个流中正常运行。但是,如果试图同时从两个或多个进程执行I / O,我将缓冲内容损坏。我没有用于缓冲区的本地存储。
我是否需要将BIO合并到驱动程序中?
Linux I / O子系统对一些并发I / O请求是否有一些要求?
是否有一些与堆栈使用或编译相关的技巧?
这是在4.15内核下。
当时我使用下一个限制条件来运行磁盘扇区:
/*
* A portion of the bio_copy_data() ...
*/
for (vcnt = 0, src_iter = src->bi_iter; ; vcnt++)
{
if ( !src_iter.bi_size)
{
if ( !(src = src->bi_next) )
break;
src_iter = src->bi_iter;
}
src_bv = bio_iter_iovec(src, src_iter);
src_p = bv_page = kmap_atomic(src_bv.bv_page);
src_p += src_bv.bv_offset;
nlbn = src_bv.bv_len512;
for ( ; nlbn--; lbn++ , src_p += 512 )
{
{
/* Simulate a processing of data in the I/O buffer */
char *srcp = src_p, *dstp = src_p;
int count = DUDRV$K_SECTORSZ;
while ( count--)
{
*(dstp++) = ~ (*(srcp++));
}
}
}
kunmap_atomic(bv_page);
**bio_advance_iter**(src, &src_iter, src_bv.bv_len);
}
这是正确的吗?还是我需要使用诸如** bio_for_each_segment(bvl,bio,iter)**之类的东西?
答案 0 :(得分:1)
您是否考虑过将vmap与全局同步一起使用?
使用kmap_atomic有一些限制:
由于映射仅限于发出该映射的CPU,因此它 表现良好,但必须执行发布任务 CPU,直到完成为止,以免其他任务替换其映射。
kmap_atomic()也可以被中断上下文使用,因为它不是 进入睡眠状态,直到调用kunmap_atomic()之后,呼叫者才可能进入睡眠状态。
答案 1 :(得分:1)
问题的根源是Block I / O方法的“功能”。特别是(请参见Linex网站reference上的说明)
** Biovecs 可以在多个BIOS之间共享-bvec iter可以代表 现有生物载体的任意范围,中途开始和结束 通过生物媒介。这就是有效分割任意对象的原因 BIOS。请注意,这意味着我们仅使用bi_size来确定何时 到达了bio的末尾,而不是bi_vcnt-并且bio_iovec()宏需要 构建生物载体时要考虑bi_size。*
因此,在我的情况下,这是导致磁盘扇区溢出的缓冲区的原因。
在将BIO发送到支持的设备驱动程序之前,先在 .bi_opf 中设置 REQ_NOMERGE_FLAGS 。
第二个原因是备份设备驱动程序返回了不实际的 .bi_iter 。因此,我们需要保存它(在向后端提交BIO请求之前),然后将其恢复到我们的“ bio_endio()”例程中。