前言:这个系列主要是记录自己学习Linux块IO子系统的过程,其中代码分析皆基于Linux3.10.0版本,如有描述错误或不妥之处,敬请指出!
参考书籍:存储技术原理分析--基于Linux 2.6内核源代码(敖青云著)

 
概述
  块设备(Block Device)是支持以固定长度的块为单位读写数据的存储设备的统称。块设备通常是支持随机访问和寻道的硬件设备,如磁盘、软盘、CDROM、内存区域等,或者是基于其他块设备之上的逻辑设备,如分区、MD(multi-disk)、Device Mapper等。
  Linux内核中负责提交对块设备IO请求的子系统被称为块IO子系统,也被称为Linux块层。块IO子系统可以被分为下面三层:

  • 通用块层为各种类型的块设备建立了一个统一的模型,它主要的工作是接收上层发出的磁盘请求,并最终发出IO请求。该层隐藏了底层硬件块设备的特性,为块设备提供了一个通用的抽象视图。
  • IO调度层:接收通用块层发出的IO请求,缓存请求并试图合并相邻的请求(如果请求在磁盘上面是相邻的),并根据设置好的算法,回调驱动层提供的请求处理函数,以处理具体的IO请求。
  • 块设备驱动层:具体的IO处理交给块设备驱动层来完成,视块设备的不同。对于大多数逻辑块设备,块设备驱动可能是一个纯粹的软件层,并不需要直接和硬件打交道,只是机械地重定向IO。对于SCSI块设备,其块设备驱动即为SCSI磁盘驱动,为SCSI子系统的高层驱动,从而将块IO子系统和SCSI子系统联系了起来。
  块IO子系统的一般IO处理流程是:上层调用通用块层提供的接口向块IO子系统提交IO请求,这些请求首先被放入IO调度层的调度队列,经过合并和排序,最终将转换后的IO请求派发到具体的块设备的等待队列,由后者的驱动进一步处理。这个过程涉及两种形式的IO请求:一种是通用块层的IO请求,即上层提交的IO请求,在Linux内核中以bio结构描述;另一种是块设备驱动层的IO请求,即经过IO调度层转换后的IO请求,在Linux内核中以request描述。
 
  IO简单来讲,就是将数据从磁盘读入内存或者从内存写入磁盘。但是,为了提升系统性能,块IO子系统采用了聚散IO(scatter/gather IO)这样一种机制:将对磁盘上连续,但内存中不连续的的数据访问由单次操作即可完成。也就是说,在单次操作中,从磁盘上的连续扇区中的数据读取到几个物理上不连续的内存空间或者将物理上不连续的内存空间的数据写入磁盘的连续扇区。前者叫分散读,后者叫聚集写。上层向通用块层提交的IO请求是基于聚散IO的,它包含多个“请求段(segment)”,一个“请求段”是一段连续的内存区域,其中包含了和其他“请求段”处于连续扇区的数据。
 
  如果说SCSI磁盘驱动是连接块IO子系统和SCSI子系统之间的桥梁,那么也可以这样认为:块设备是联系块IO子系统和文件系统之间的纽带。bio表示上层发给通用块层的请求,称为通用块层请求,它关注的是请求的应用层面,即读取(或写入)哪个块设备,读取(或写入)多少字节的数据,读取(或写入)到哪个目标缓冲区等、request表示通用块层为底层块设备驱动准备的请求,称作块设备驱动层IO请求,或块设备驱动请求,它关注的是请求的实施层面,即构造哪种类型的SCSI命令。
 
  一个块设备驱动层请求可能包含多个通用块层请求,也就是说,一次SCSI命令可以服务多个上层请求,这就是所谓的请求合并。在Linux内核实现中,请求合并就是将多个bio链入到同一个request。此外,块IO子系统还涉及不同的请求队列,包括IO调度队列和派发队列。IO调度队列是块IO子系统用于对通用块层请求进行合并和排序的队列。派发队列是针对块设备驱动的,即块IO子系统严格按照队列顺序提交块设备驱动层请求给块设备驱动处理。一般来说,每个块设备都有一个派发队列,IO子系统又为它内部维护了一个IO调度队列,不同的块设备可以采用不同的IO调度算法。
 
  通用块层请求到达块IO子系统时,首先在IO调度队列中进行合并和排序,变成为块设备驱动层的请求。之后块设备驱动层请求按照特定的算法被转移到派发队列,从而被提交到块设备驱动。在Linux内核中,IO调度队列和派发队列都反应在request_queue结构中。理清各种请求队列以及各种请求之间的关系,是透彻了解块IO子系统的另一个关键所在。
 

Linux3.10.0块IO子系统流程(0)-- 块IO子系统概述的更多相关文章

  1. Linux 0.11源码阅读笔记-文件IO流程

    文件IO流程 用户进程read.write在高速缓冲块上读写数据,高速缓冲块和块设备交换数据. 什么时机将磁盘块数据读到缓冲块? 什么时机将缓冲块数据刷到磁盘块? 函数调用关系 read/write( ...

  2. C# 8.0和.NET Core 3.0高级编程 分享笔记三:控制流程和转换类型

    控制流程和转换类型 本章的内容主要包括编写代码.对变量执行简单的操作.做出决策.重复执行语句块.将变量或表达式值从一种类型转换为另一种类型.处理异常以及在数值变量中检查溢出. 本章涵盖以下主题: 操作 ...

  3. 多校3- RGCDQ 分类: 比赛 HDU 2015-07-31 10:50 2人阅读 评论(0) 收藏

    RGCDQ Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Practic ...

  4. Linux命令 标签: linux 2016-08-01 10:26 508人阅读 评论(0) 收藏

    Linux常用命令 文件.目录的基本操作 ls - 查看文件 cp - 拷贝文件 mv - 移动或重命名文件 rm - 删除文件 touch - 创建空文件或更新文件时间 cd - 改变当前路径 pw ...

  5. MySQL与MariaDB核心特性比较详细版v1.0(覆盖mysql 8.0/mariadb 10.3,包括优化、功能及维护)

    注:本文严禁任何形式的转载,原文使用word编写,为了大家阅读方便,提供pdf版下载. MySQL与MariaDB主要特性比较详细版v1.0(不含HA).pdf 链接:https://pan.baid ...

  6. ElasticsearchException: java.io.IOException: failed to read [id:0, file:/data/elasticsearch/nodes/0/_state/global-0.st]

    from : https://www.cnblogs.com/hixiaowei/p/11213143.html 1.以前装过elasticsearch,重新安装elastic search ,报错 ...

  7. Linux 0.11源码阅读笔记-块设备驱动程序

    块设备驱动程序 块设备驱动程序负责实现对块设备数据的读写功能.内核代码统一使用缓冲块间接和块设备(如磁盘)交换数据,缓冲区数据通过块设备驱动程序和块设备交换数据. 块设备的管理 块设备表 内核通过一张 ...

  8. 10款最好的 Bootstrap 3.0 免费主题和模板

    Twitter Bootstrap 框架已经广为人知,用于加快网站,应用程序或主题的界面开发,并被公认为是迄今对于Web开发的最有实质性帮助的工具之一.在此之前的,各种各样的界面库伴随着高昂的维护成本 ...

  9. effective OC2.0 52阅读笔记(六 块与大中枢派发)

    派发队列:dispatch_queue 操作队列:NSOperationQueue  组:dispathc_group_t 37 理解“块”这一概念 总结:块就是一个值,且自有其相关类型.块的强大之处 ...

随机推荐

  1. Vue $emit()不触发方法的原因

    vue使用$emit时,父组件无法触发监听事件的原因是: $emit传入的事件名称只能使用小写,不能使用大写的驼峰规则命名

  2. HDU 5095--Linearization of the kernel functions in SVM【模拟】

    Linearization of the kernel functions in SVM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: ...

  3. paste

    echo "step 1" >> steplog.txt    echo "step 1"        sudo apt-get install ...

  4. Python实现im2col和col2im函数

    今天来说说im2col和col2im函数,这是MATLAB中两个内置函数,经常用于数字图像处理中.其中im2col函数在<MATLAB中的im2col函数>一文中已经进行了简单的介绍. 一 ...

  5. 【Nginx】Nginx在Linux下的入门介绍

    Nginx的安装 下载.解压 从Nginx下载安装包,我下的是nginx-1.8.0.tar.gz.解压后的目录为: [root@blog third_package]# tar -zxf nginx ...

  6. mac下安装mysql5.7.18,连接出现Access denied for user 'root'@'localhost' (using password: YES)

    mac下,mysql5.7.18连接出错,错误信息为:Access denied for user 'root'@'localhost' (using password: YES) ()里面的为she ...

  7. sql 同步2个表中的一个字段数据

    update PMS.tenant_contract a inner join(select id,home_id from PMS.owner_contract) c on a.id = c.id ...

  8. puppet(2)-资源介绍

    puppet- 资源介绍: 类型.属性与状态同实现方式分离.仅指定目标状态 type {'title': attribute => value, ... } 查看支持的资源类型: puppet ...

  9. 关于Kafka producer管理TCP连接的讨论

    在Kafka中,TCP连接的管理交由底层的Selector类(org.apache.kafka.common.network)来维护.Selector类定义了很多数据结构,其中最核心的当属java.n ...

  10. git error: Your local changes to the following files would be overwritten by merge:xxxxxx ,Please commit your changes or stash them before you merge.的phpstorm解决办法

    git报错 error: Your local changes to the following files would be overwritten by merge: .idea/encoding ...