[ 摘自yuanbor的博客 ] bio的转发

本文深入探讨了块设备IO请求如何在Device Mapper中完成映射与转发的过程,包括map函数的作用、stripe_map的简单实现、以及bio在DM架构中的传递路径分析。

任何一个bio(块设备的io请求)都要映射到最终存储它的设备上的相应位置,Device Mappermap函数就要完成这一功能。该函数的原型如下:

int xxx_map(struct dm_target *ti, struct bio *bio, union map_info *map_context);

ti代表targetbio是发给这个targetio请求。一个bio有三个关键成员:bi_sector(位置)、bi_bdev(设备)、bi_io_vec(数据)。DM框架将bio发给map函数,使得target有机会来改变bio的这三个关键成员,从而实现两个目的:重定位和修改数据。map_context在许多情况下并没有许多作用。

如果map函数将bio赋值后又分发出去,那么就返回DM_MAPIO_SUBMITTED告诉DM不要再处理了;如果map函数修改了bio的内容,希望DMbio按照新内容再分发,那么就返回DM_MAPIO_REMAPPED即可;如果map函数将bio加入队列中等待后续处理,则返回DM_MAPIO_REQUEUEDM相应的处理代码可以在dm.c中的__map_bio()函数中找到。

stripe_map就很简单了,直接修改biobi_sectorbi_bdev,返回DM_MAPIO_REMAPPED通知DM再分发一次即可。stripe所扮演的角色就好比是一个邮件中转站,下辖N个子邮箱。所有邮件都按照规则被转发到对应子邮箱中,中转站的工作就是把每个邮件的地址和收件人改一改再让邮递员送一遍即可,接下来的bio传递路径分析将详细展示这一中转过程。


DM转发bio的过程

DM为每一个driver的实例创建一个md作为对外的接口,每一个md在内核中注册成为一个块设备,因此每一个driver的实例就是一个虚拟的块设备。

每一个md通过driver的实例管理一个或多个targetdriver的主要工作就是把每个提交给mdbio请求进行数据转换并转发给对应的targetmd实现了一个标准的块设备驱动,这里仅分析bio的转发过程。

每个块设备都有一个请求队列,请求队列包含一个make_request_fn指针指向原型为int make_request(struct request_queue *q, struct bio *bio);的函数,Linux内核中的void generic_make_request(struct bio *bio);函数就是通过bio找到对应的bi_bdev,然后找到该bdev对应的request_queue,并调用其make_request_fn函数:

block/blk_core.c 1484行:ret = q->make_request_fn(q, bio);

这就是bio从内核进入DM的起点。为什么这么说?因为在md创建的时候(通过dm.calloc_dev())将md->queuemake_request_fn指针设置为了dm_request

drivers/md/dm.c 1908行:blk_queue_make_request(md->queue, dm_request);

dm_request接收到bio之后有两种选择:如果q->queue_flags被设置了QUEUE_FLAG_STACKABLE,则对request进行排队处理,否则直接分发。alloc_dev中创建queue的时候按照QUEUE_FLAG_DEFAULT创建,包含了QUEUE_FLAG_STACKABLE,但是接着该标志被清除了:

drivers/md/dm.c 1889行:md->queue = blk_init_queue(dm_request_fn, NULL);

...

drivers/md/dm.c 1903行:queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, md->queue);

因此dm_request()函数将走_dm_request()分支。以下是bio所走过的流程:

int dm_request(struct request_queue *q, struct bio *bio)

`-> _dm_request(q, bio);

`-> __split_and_process_bio(md, bio); // md 由 q->queue_data 获得

`-> __clone_and_map(&ci);  // mdbio等信息记录在 ci 结构体中

`-> __map_bio(ti, clone, tio);  // ti 由 ci->md 查表获得,cloneci->bio克隆获得

`-> ti->type->map(ti, clone, &tio->info);

最终,bio传递给了对应timap函数。

要说明的是,DM构架及其驱动一般不会是真实设备的驱动,因此只会对bio进行处理之后再转发出去。转发的方法就是修改bio->bi_bdevbio->bi_sector。其中bi_bdev必需是在内核中已注册的设备,这些块设备和dm的块设备一道在Linux内核中注册,在Linux看来是平等的。而一个md其实是将其他块设备的bdev记录在自己的映射表中,按照自身的逻辑规律对bio进行映射转发而已。


内容概要:本文提出了一种基于融合鱼鹰算法和柯西变异的改进麻雀优化算法(OCSSA),用于优化变分模态分解(VMD)的参数,进而结合卷积神经网络(CNN)与双向长短期记忆网络(BiLSTM)构建OCSSA-VMD-CNN-BILSTM模型,实现对轴承故障的高【轴承故障诊断】基于融合鱼鹰和柯西变异的麻雀优化算法OCSSA-VMD-CNN-BILSTM轴承诊断研究【西储大学数据】(Matlab代码实现)精度诊断。研究采用西储大学公开的轴承故障数据集进行实验验证,通过优化VMD的模态数和惩罚因子,有效提升了信号分解的准确性与稳定性,随后利用CNN提取故障特征,BiLSTM捕捉时间序列的深层依赖关系,最终实现故障类型的智能识别。该方法在提升故障诊断精度与鲁棒性方面表现出优越性能。; 适合人群:具备一定信号处理、机器学习基础,从事机械故障诊断、智能运维、工业大数据分析等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①解决传统VMD参数依赖人工经验选取的问题,实现参数自适应优化;②提升复杂工况下滚动轴承早期故障的识别准确率;③为智能制造与预测性维护提供可靠的技术支持。; 阅读建议:建议读者结合Matlab代码实现过程,深入理解OCSSA优化机制、VMD信号分解流程以及CNN-BiLSTM网络架构的设计逻辑,重点关注参数优化与故障分类的联动关系,并可通过更换数据集进一步验证模型泛化能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值