首先来看scsi_prep_fn int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q->queuedata; int ret = BLKPREP_KILL; if (req->cmd_type == REQ_TYPE_BLOCK_PC) ret = scsi_setup_blk_pc_cmnd(sdev, req); return scsi_prep_retu…
前言:这个系列主要是记录自己学习Linux块IO子系统的过程,其中代码分析皆基于Linux3.10.0版本,如有描述错误或不妥之处,敬请指出! 参考书籍:存储技术原理分析--基于Linux 2.6内核源代码(敖青云著)   概述 块设备(Block Device)是支持以固定长度的块为单位读写数据的存储设备的统称.块设备通常是支持随机访问和寻道的硬件设备,如磁盘.软盘.CDROM.内存区域等,或者是基于其他块设备之上的逻辑设备,如分区.MD(multi-disk).Device Mapper等.…
和提交请求相反,完成请求的过程是从低层驱动开始的.请求处理完成分为两个部分:上半部和下半部.开始时,请求处理完成总是处在中断上下文,在这里的主要任务是将已完成的请求放到某个队列中,然后引发软终端让中断“下半部”来处理,这是通常的做法.而“下半部”则依次处理队列中的每一个已完成的请求.   在讲派发SCSI命令的时候,提到了scsi_done,低层驱动在初始化硬件时,注册过一个中断回调函数.在硬件中断被引发时,中断回调函数将被调用,如果是对SCSI命令的相应,则将找到对应的scsi_cmnd描述符…
很长时间以来,Linux块设备使用了一种称为“蓄流/泄流”(plugging/unplugging)的技术来改进吞吐率.简单而言,这种工作方式类似浴盆排水系统的塞子.当IO被提交时,它被储存在一个队列,稍后的某个时间,我们才允许IO从队列派发出去.之所以这么做是为IO尽可能做合并和排序. static void scsi_request_fn(struct request_queue *q) { struct scsi_device *sdev = q->queuedata; struct Sc…
Linux块设备可以分为三类.分别针对顺序访问物理设备.随机访问物理设备和逻辑设备(即“栈式设备”)   类型 make_request_fn request_fn 备注 SCSI 设备等 从bio构造request(经过合并和排序),返回0 逐个处理request 调用blk_init_queue,使用默认的__make_request,提供策略例程 SSD等 直接处理bio,返回0 无 调用blk_alloc_queue,提供make_request_fn RAID或Device Mappe…
在SCSI策略例程中最后调用scsi_dispatch_cmd将SCSI命令描述符派发给低层驱动进行处理 /** * scsi_dispatch_command - Dispatch a command to the low-level driver. * @cmd: command block we are dispatching. * * Return: nonzero return request was rejected and device's queue needs to be *…
SCSI数据缓冲区组织成聚散列表的形式.Linux内核中表示聚散列表的基本数据结构是scatterlist,虽然名字中有list,但它只对应一个内存缓冲区,聚散列表就是多个scatterlist的组合.这种组合是链表+数组的结合.这是因为他使用的内存以页面为基本单位分配,每个页面相当于一个scatterlist.每个scatterlist以链表方式组织起来. /* * Function: scsi_init_io() * * Purpose: SCSI I/O initialize functi…
Linux通用块层提供给上层的接口函数是submit_bio.上层在构造好bio之后,调用submit_bio提交给通用块层处理.   submit_bio函数如下:   void submit_bio(int rw, struct bio *bio) { bio->bi_rw |= rw; //记录读写方式 /* * 执行有数据传输的读写或屏障请求统计,暂不关心 */ if (bio_has_data(bio)) { unsigned int count; if (unlikely(rw &…
SolarWinds DPA的升级其实是一件非常简单的事情,这里介绍一下从DPA 9.1.95升级到 DPA 10.0.352版本的流程.为什么要升级呢? DPA给用户发的邮件已经写的非常清楚了(如下所示),DPA 10.0这个版本已开始支持MySQL了,另外它解决了一些Bug,在性能上有所改进.提升. Our records indicate that you might have Database Performance Analyzer (DPA) 9.0 installed and li…
我们含有分析的,是基于2.6.32及其后的内核. 我们在linux上总是要保存数据,数据要么保存在文件系统里(如ext3),要么就保存在裸设备里.我们在使用这些数据的时候都是通过文件这个抽象来访问的,操作系统会把我们需要的数据提交给我们,而我们则无需和块设备打交道. 从下图,我们可以清除的看到: I/O子系统是个层次很深的系统,数据请求从用户空间最终到达磁盘,经过了复杂的数据流动. 对设驱开发人员或与此相关的设计人员,特别是IO很密集,我们就需要搞清楚IO具体是如何动作的,免得滥用IO和导致设计…