前言:这个系列主要是记录自己学习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. 【20180111】【物流FM专访】贝业新兄弟李济宏:我们是如何做到大件家居B2C物流第一的?

    在2017年的双11中,贝业新兄弟承接了日日顺家装和卫浴行业的仓储和配送,上海仓和武汉仓双十一期间及时出库率为100%,KPI位列第一:此外,贝业新兄弟还是科勒18年以来中国区唯一的物流服务商以及宜家 ...

  2. system generator学习笔记【01】

    作者:桂. 时间:2018-05-18  18:26:50 链接:http://www.cnblogs.com/xingshansi/p/9045914.html 前言 学习使用system gene ...

  3. 很烦人的maven和gradle的jar缓存

    1. 起因 a. 最近在学习大数据相关东西,自然就少不免去操作linux系统,更别说不敲命令 b. 然而那个配置软件时,很经常使用ln -s为一个软件目录(带着版本或者其他信息的长命名)创建别名(软连 ...

  4. Android内存泄漏杂谈

    内存泄漏:是指内存得不到GC的及时回收,从而造成内存占用过多.从而导致程序Crash,也就是常说的OOM. 一.static 先来看以下一段代码 public class DBHelper { pri ...

  5. Visual Studio编辑器“智能提示(IntelliSense)”异常的解决方案

    1.删除工程中的 .suo 文件. 2.重启vs

  6. JVM:Java常见内存溢出异常分析

    转载自:http://www.importnew.com/14604.html Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等,而Hotspot jvm的实现中,将堆 ...

  7. mac os系统go安装:go install github.com/nsf/gocode: open /usr/local/go/bin/gocode: permission denied

    gocode是go语言代码自动提示工具 安装时进入src目录执行:go get -u github.com/nsf/gocode 出现: github.com/nsf/gocode (download ...

  8. Python学习笔记(二)

    标识符和关键字 1,邮箱的Python标识符是任意长度的非空字符序列(引导字符+后续字符.) python标识符必须符合两条规则--标识符区分大小写 (1)只要是unicode编码字母都可以充当引导字 ...

  9. DBeaver连接MySQL 8.0显示"Unable to load authentication plugin 'caching_sha2_password'."错误的问题

    下载MySQL绿色版本mysql-8.0.12-winx64,手动安装完成后.使用DBeaver连接提示"Unable to load authentication plugin 'cach ...

  10. asp.net mvc 通过StyleBundle添加样式后,没有作用

    在App_Start/BundleConfig配置 导入bootstrap,但不起作用,代码如下: bundles.Add(new StyleBundle("~/Content/bootst ...