前言:这个系列主要是记录自己学习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. Linux系统下x86和ARM的区别有哪些?

    问题: 最近在用三星的一款i5处理器的Windows平板,和iPad,以及其他使用ARM处理器的手机相比,发热量大很多,甚至需要借助风扇来散热,耗电量也大了不少. 那么就很奇怪,在主频相差不大,并且实 ...

  2. Atitit 关于共享经济之共享男女朋友的创业计划

    Atitit 关于共享经济之共享男女朋友的创业计划 1. 共享经济的历史与趋势 1 1.1. 共享经济三大特征=产能过剩+共享平台+人人参与. 1 1.2. 共享经济是个大趋势,使用权渐渐的取代所有权 ...

  3. windows nginx配置https访问

    本文主要记录在windows下安装nginx 环境:win10-64位. 1.  到nginx官网上下载相应的安装包,http://nginx.org/en/download.html: 下载进行解压 ...

  4. Xcode 常用代码段

    weak_shortcut /** <#注释#> */ @property(nonatomic,weak) <#class#> *<#name#>; copy_sh ...

  5. vux安装中遇到的坑(转)

    1.输入 npm install vux --save 2.输入 npm install vux-loader --save-dev(没安装的时候,会一直报错) 3.build/webpack.bas ...

  6. go for-range中的循环变量

    测试的时候发现一个有意思的地方,就是go始终利用同一块内存来接收集合中的一个值,只是在每次循环的时候重新赋值而已. package main import (     "fmt" ...

  7. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

  8. Dynamic seq2seq in tensorflow

    v1.0中 tensorflow渐渐废弃了老的非dynamic的seq2seq接口,已经放到 tf.contrib.legacy_seq2seq目录下面. tf.contrib.seq2seq下面的实 ...

  9. 125、Android样式的开发(转载)

    Android样式的开发:drawable汇总篇 http://android.jobbole.com/82117/Android样式的开发:layer-list篇 http://android.jo ...

  10. docker 应用-2(Dockerfile 编写以及镜像保存提交)

    我们可以从docker hub上pull别人的镜像,也可以将容器进行修改,然后commit镜像,并把镜像push到docker hub上被被人使用.但是,直接pull或者push镜像的方式太过笨重,尤 ...