4.bio、request和request_queue

2023-11-19

通常一个bio对应上层传递给块层的I/O请求;每个bio结构体实例及其包含的bvec_iterbio_vec结构体实例描述了该I/O请求的开始扇区、数据方向(读还是写),数据放入的页,
其定义如代码清单13.3所示。

struct bvec_iter
{
	sector_t bi_sector;
	unsigned int bi_size;
	unsigned int bi_idx;
	unsigned int bi_bvec_done;
}
struct bio
{
	struct bio *bi_next;
	struct block_device *bi_bdev;
	unsigned long bi_flags;
	unsigned long bi_rw;
	......
	struct bvec_iter bi_iter;
	struct bio_vec *bi_io_vec;
	struct bio_set *bi_pool;
	struct bio_vec bi_inline_vecs[0];
}

与bio对应的数据每次存放的内存不一定是连续的,bio_vec结构体用来描述与这个bio请求对应的所有的内存,他可能不总是在一个页面里面,因此需要一个向量。向量中的每个元素实际是一个[page,offset,len],我们称它为一个片段。

struct bio_vec
{
	struct page *bv_page;
	unsigned int bv_len;
	unsigned int bv_offset;
}

I/O调度算法可将连续的bio合并成一个请求,请求是bio经由I/O调度进行调整后的结果,这是请求和bio的区别。因此,一个request(请求)可以包含多个bio,当bio被提交给I/O调度器时,I/O调度器可能会将这个bio插入现存的请求中,也可能生成新的请求。
每个块设备或者块设备分区都对应有自己的request_queue,从I/O调度器合并和排序出来的请求会被分发(Dispatch)到设备级的request_queue
在这里插入图片描述
下面看一下驱动中涉及到处理bio,request和request_queue的主要API。
(1)初始化请求队列

request_queue_t *blk_init_queue(request_fn_proc *rfn,spinlock_t *lock);

第一个参数是请求处理函数的指针,
第二个参数是控制访问队列权限的自旋锁
这个函数会发生内存分配的行为,他可能会失败,因此一定要检查他的返回值。这个函数一般在块设备的初始化过程中调用。
(2)清除请求队列

void blk_cleanup_queue(request_queue_t *q);

这个函数完成请求队列返回给系统的任务,一般在块设备驱动卸载过程中调用。
(3)分配请求队列

request_queue_t *blk_alloc_queue(int gfp_mask);

对于RAMDISK这种完全随机访问的非机械设备,并不需要复杂的I/O调度,这个时候可以直接踢开I/O调度器,使用如下函数来绑定请求队列制造请求函数(make_request_fn)。

void blk_queue_make_request(request_queue_t *q,make_request_fn *mfn);

blk_alloc_queue()blk_queue_make_request()结合起来使用的逻辑一般是:

xxx_queue = blk_alloc_queue(GFP_KERNEL);
blk_queue_make_request(xxx_queue,xxx_make_request);

(4)提取请求

struct request *blk_peek_request(struct request_queue *q);

上述函数用于返回下一个要处理的请求(由I/O调度器决定),如果没有请求则返回NULL。他不会清除请求,而是仍然将这个请求保留在队列上。原先的老的函数elv_next_request()已经不再存在。
(5)启动请求

void blk_start_request(struct request *req);

从请求队列中移除请求,原先的老的API blkdev_dequeue_request()会在blk_start_request()内部被调用。
我们可以考虑使用blk_fetch_request()函数,他同时做完了blk_peek_request()(提取请求)和blk_start_request()的工作。

struct request *blk_fetch_request(struct request_queue *q)
{
	struct request *rq;
	rq = blk_peek_request(q);
	if(rq)
	{
		blk_start_request(rq);
	}
	return rq;
}

(6)遍历bio和片段
_rq_for_each_bio()遍历一个请求的所有bio。

#define _rq_for_each_bio(_bio,rq) \
		if(rq->bio)
		{
			for(_bio = rq->bio;_bio;_bio=_bio->bi_next);
		}

bio_for_each_segment()遍历一个bio的所有bio_vec
rq_for_each_segment()迭代遍历一个请求所有bio所有segment
(7)报告完成

void _blk_end_request_all(struct request *rq,int error);
void blk_end_request_all(struct request *rq,int error);

若我们用blk_queue_make_request()绕开I/O调度,但是在bio处理完成后应该使用bio_endio()函数通知处理结束

#define bio_io_error(bio) bio_endio((bio),-EIO); 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

4.bio、request和request_queue 的相关文章

  • 更新Linux中的包含路径

    我的 my path to file 文件夹中有几个头文件 我知道如何将这些文件包含在新的 C 程序中 但每次我都需要在包含它之前输入头文件的完整路径 我可以在linux中设置一些路径变量 以便它自动查找头文件吗 您可以创建一个 makef
  • Bash:将字符串添加到文件末尾而不换行

    如何将字符串添加到文件末尾而不换行 例如 如果我使用 gt gt 它将添加到文件末尾并换行 cat list txt yourText1 root host 37 echo yourText2 gt gt list txt root hos
  • Python glob,操作系统,相对路径,将文件名放入列表中[重复]

    这个问题在这里已经有答案了 我正在尝试创建一个目录中所有文件的列表 其中文件名以 root 结尾 在阅读了论坛中的一些文章后 我尝试使用 glob 和 os listdir 的基本策略 但我都遇到了麻烦 首先 当我使用 import glo
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • 如何在 Linux 和 C 中使用文件作为互斥体?

    我有不同的进程同时访问 Linux 中的命名管道 并且我想让此访问互斥 我知道可以使用放置在共享内存区域中的互斥体来实现这一点 但作为一种家庭作业 我有一些限制 于是 我想到的是对文件使用锁定原语来实现互斥 我做了一些尝试 但无法使其发挥作
  • Crontab 每 5 分钟一次 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我如何告诉 crontab 每 5 分钟运行一次 但从每小时的第二分钟开始 换句话说 我想在以下时间执行我的脚本minute 5 2 例如 我的脚本应
  • Python 3.4.3 subprocess.Popen 在没有管道的情况下获取命令的输出?

    我试图将命令的输出分配给变量 而不让命令认为它正在通过管道传输 原因是 如果正在通过管道传输 则相关命令会给出未格式化的文本作为输出 但如果从终端运行 则会给出颜色格式化的文本 我需要获取这种颜色格式的文本 到目前为止我已经尝试了一些事情
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • ALSA:snd_pcm_writei 调用时缓冲区不足

    当运行我最近从灰烬中带回来的旧程序时 我遇到了缓冲区不足的情况 该程序将原始声音文件完全加载到内存中 2100 字节长 525 帧 并准备 ALSA 进行输出 44 1khz 2 通道 有符号 16 位 if err snd pcm set
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 在 Linux 上以编程方式设置 DNS 名称服务器

    我希望能够通过我的 C C 程序为 Linux 上的 DNS 名称服务器添加 IP 地址 我在一个带有只读 etc resolv conf 的嵌入式平台上 这意味着我不能简单地将 nameserver xxx xxx xxx xxx 行添加
  • tcpdump 是否受 iptables 过滤影响?

    如果我的开发机器有iptables规则到FORWARD一些数据包 这些数据包是否被 tcpdump 捕获 我有这个问题 因为我知道存在其他链称为INPUT如果数据包路由到 它会过滤发往应用程序的数据包FORWARD链 它会到达吗tcpdum
  • Linux 上的 Pervasive ODBC 错误 [01000][unixODBC][驱动程序管理器]无法打开 lib '/usr/local/psql/lib/odbcci.so':找不到文件

    我正在尝试让 Pervasive v10 客户端 ODBC 在 Centos 6 上运行 据我所知 没有 64 位 ODBC 客户端 因此我必须使用 32 位客户端 我终于成功安装了它 但尝试使用时出现以下错误 isql v mydsn 0
  • 无需超级用户即可在 Linux 中打开 RAW 套接字

    我必须编写一个在 Linux 上运行的 ping 函数 语言是 C 所以 C 也可以 在网上搜索并查看源代码ping命令 事实证明我应该创建一个原始套接字 icmp sock socket AF INET SOCK RAW IPPROTO
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I

随机推荐

  • 证据理论(1)—— DS证据理论基本理论

    证据理论 证据理论 Theory of Evidence 是由 Dempster 首先提出 由Shafer进一步发展起来的一种不精确推理理论 也称为 Dempster Shafer DS 证据理论 证据理论可以在没有先验概率的情况下 灵活并
  • 基于Matlab分析的电力系统可视化研究

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及数据 1 概述 电力系统可视化研究是电力系统分析中一项具
  • IKE协议与实现

    一 IKE的作用 当应用环境的规模较小时 可以用手工配置SA 当应用环境规模较大 参与的节点位置不固定时 IKE可自动地为参与通信的实体协商SA 并对安全关联库 SAD 维护 保障通信安全 二 IKE的机制 IKE属于一种混合型协议 由In
  • php curl ajax get请求,PHP的curl的get,post请求-Fun言

    GET请求如下 param string url return mixed public function doGet url 初始化 ch curl init curl setopt ch CURLOPT URL url 执行后不直接打印
  • 面试题:从用户在浏览器输入域名,到浏览器显示出页面,这中间发生了什么(工作过程)?

    这是一道很基础的题 但是也容易被忽视 主要是要进行域名解析 1 在浏览器中输入地址 如 www baidu com 2 向DNS服务器查询网站IP地址 3 DNS服务器返回网站IP地址 如 119 75 217 56 4 浏览器得到IP地址
  • 使用pipeline加速Redis

    面试官 怎么快速删除10万个key 某厂面试题 prod环境 如何快速删除10万个key 带着思考 我们一来研究Redis pipeline why pipeline Redis客户端与server的请求 响应模型 前面的文章 Redis底
  • C#开发WinForm之DataGridView开发

    C 开发WinForm之DataGridView开发 原文 https blog csdn net achenyuan article details 84632751 文章目录 C 开发WinForm之DataGridView开发 基本的
  • 在Linux中使用selenium(环境部署)

    在Linux中使用selenium 环境部署 1 安装chrome 用下面的命令安装Google Chrome yum install https dl google com linux direct google chrome stabl
  • 【单片机笔记】K型热电偶单运放放大,单片机ADC采集电路

    以下内容来自百科 K型热电偶作为一种温度传感器 K型热电偶通常和显示仪表 记录仪表和电子调节器配套使用 K型热电偶可以直接测量各种生产中从0 到1300 范围的液体蒸汽和气体介质以及固体的表面温度 高清K型热电偶图片 K型热电偶是目前用量最
  • 【RuoYi-Vue-Plus】学习笔记 09 - 数据权限调用流程分析(参照 Mybatis Plus 数据权限插件)

    文章目录 前言 参考目录 代码分析 1 数据权限配置 MybatisPlusConfig 2 数据权限拦截器 PlusDataPermissionInterceptor 3 数据权限处理器 PlusDataPermissionHandler
  • 20-Docker-常用命令详解-docker attach

    常用命令详解 docker attach 前言 docker attach 语法格式 options 说明 使用示例 进入容器 和docker exec 的区别 前言 本篇来学习docker attach命令 docker attach 作
  • 解决 -bash: ifconfig: command not found 实测有效

    1 查看是否已经联网 输入ip addr 或 ip a 发现ens33 中不包含IP内容 2 修改配置步骤 1 输入 cd etc sysconfig network scripts 回车 找到ifcfg ens33 注意 cd后面有空格
  • 坐标系和投影 知识的内容介绍

    回想一下 接触遥感专业也有几个年头了 而现在越来越偏离遥感了 突然想着把自己脑中的遥感知识整理出来 首先想到的便是坐标系和投影 我想这个东西困扰着80 以上的测绘 遥感和GIS领域的从业人员吧 群里经常有人问 我自己曾经也很迷糊 什么大地坐
  • Java测试题_1

    单选题 1 class Base Base System out print Base public class Alpha extends Base public static void main String args new Alph
  • JavaScript 获取 input 输入框内容的方法

    在 JavaScript 中获取 input 输入框内容的方法有以下几种 使用 document getElementById 方法获取输入框元素 再通过 value 属性获取输入框内容 示例代码如下 var input document
  • 吴恩达老师深度学习视频课笔记:逻辑回归公式推导及C++实现

    逻辑回归 Logistic Regression 是一个二分分类算法 逻辑回归的目标是最小化其预测与训练数据之间的误差 为了训练逻辑回归模型中的参数w和b 需要定义一个成本函数 cost function 成本函数 cost functio
  • Golang匿名结构体的使用

    一 结构体基础 结构体 struct 将多个不同类型的字段集中组成一种复合类型 按声明时的字段顺序初始化 type user struct name string age byte user user Tom 2 定义匿名结构体时没有 ty
  • 编程TRICK

    一 20200729 1 image和annots的数据类型要统一 如image annots设为np float32 在具体函数中 输入和输出的数据类型要保持一致 中间具体应用再改变数据类型 2 仿射变换可以用PIL的transform
  • Flowable入门系列文章113 - 进程实例 02

    1 激活或暂停流程实例 PUT运行时 process instances processInstanceId 表1 激活或暂停流程实例 URL参数 参数 需要 值 描述 processInstanceId 是 串 激活 挂起的流程实例的ID
  • 4.bio、request和request_queue

    通常一个bio对应上层传递给块层的I O请求 每个bio结构体实例及其包含的bvec iter bio vec结构体实例描述了该I O请求的开始扇区 数据方向 读还是写 数据放入的页 其定义如代码清单13 3所示 struct bvec i