位置: IT常识 - 正文

linux块设备读写流程详解(linux块设备驱动详解)

编辑:rootadmin
今天小编为大家带来的是linux块设备读写流程详解!希望对大家会有帮助!有需要的朋友一起去看看吧... 17-03-30

推荐整理分享linux块设备读写流程详解(linux块设备驱动详解),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:linux块设备是什么,linux块设备读写和回写,linux读写操作,linux 块设备,linux 块设备 字符设备,linux块设备读写磁盘,需要格式化吗,linux块设备读写和回写,linux块设备读写和回写,内容如对您有帮助,希望把文章链接给更多的朋友!

在学习块设备原理的时候,我最关系块设备的数据流程,从应用程序调用Read或者Write开始,数据在内核中到底是如何流通、处理的呢?然后又如何抵达具体的物理设备的呢?下面对一个带Cache功能的块设备数据流程进行分析。一起去看看吧!

1、 用户态程序通过open()打开指定的块设备,通过systemcall机制陷入内核,执行blkdev_open()函数,该函数注册到文件系统方法(file_operations)中的open上。在blkdev_open函数中调用bd_acquire()函数,bd_acquire函数完成文件系统inode到块设备bdev的转换,具体的转换方法通过hash查找实现。得到具体块设备的bdev之后,调用do_open()函数完成设备打开的操作。在do_open函数中会调用到块设备驱动注册的open方法,具体调用如下:gendisk->fops->open(bdev->bd_inode, file)。

2、 用户程序通过read、write函数对设备进行读写,文件系统会调用相应的方法,通常会调用如下两个函数:generic_file_read和blkdev_file_write。在读写过程中采用了多种策略,首先分析读过程。

3、 用户态调用了read函数,内核执行generic_file_read,如果不是direct io方式,那么直接调用do_generic_file_read->do_generic_mapping_read()函数,在do_generic_mapping_read(函数位于filemap.c)函数中,首先查找数据是否命中Cache,如果命中,那么直接将数据返回给用户态;否则通过address_space->a_ops->readpage函数发起一个真实的读请求。在readpage函数中,构造一个buffer_head,设置bh回调函数end_buffer_async_read,然后调用submit_bh发起请求。在submit_bh函数中,根据buffer_head构造bio,设置bio的回调函数end_bio_bh_io_sync,最后通过submit_bio将bio请求发送给指定的快设备。

4、 如果用户态调用了一个write函数,内核执行blkdev_file_write函数,如果不是direct io操作方式,那么执行buffered write操作过程,直接调用generic_file_buffered_write函数。Buffered write操作方法会将数据直接写入Cache,并进行Cache的替换操作,在替换操作过程中需要对实际的快设备进行操作,address_space->a_ops提供了块设备操作的方法。当数据被写入到Cache之后,write函数就可以返回了,后继异步写入的任务绝大部分交给了pdflush daemon(有一部分在替换的时候做了)

linux块设备读写流程详解(linux块设备驱动详解)

5、 数据流操作到这一步,我们已经很清楚用户的数据是如何到内核了。与用户最接近的方法是file_operations,每种设备类型都定义了这一方法(由于Linux将所有设备都看成是文件,所以为每类设备都定义了文件操作方法,例如,字符设备的操作方法为def_chr_fops,块设备为def_blk_fops,网络设备为bad_sock_fops)。每种设备类型底层操作方法是不一样的,但是通过file_operations方法将设备类型的差异化屏蔽了,这就是Linux能够将所有设备都理解为文件的缘由。到这里,又提出一个问题:既然这样,那设备的差异化又该如何体现呢?在文件系统层定义了文件系统访问设备的方法,该方法就是address_space_operations,文件系统通过该方法可以访问具体的设备。对于字符设备而言,没有实现address_space_operations方法,也没有必要,因为字符设备的接口与文件系统的接口是一样的,在字符设备open操作的过程中,将inode所指向的file_operations替换成cdev所指向的file_operations就可以了。这样用户层读写字符设备可以直接调用cdev中file_operations方法了。

6、 截至到步骤(4),读操作在没有命中Cache的情况下通过address_space_operations方法中的readpage函数发起块设备读请求;写操作在替换Cache或者Pdflush唤醒时发起块设备请求。发起块设备请求的过程都一样,首先根据需求构建bio结构,bio结构中包含了读写地址、长度、目的设备、回调函数等信息。构造完bio之后,通过简单的submit_bio函数将请求转发给具体的块设备。从这里可以看出,块设备接口很简单,接口方法为submit_bio(更底层函数为generic_make_request),数据结构为struct bio。

7、 submit_bio函数通过generic_make_request转发bio,generic_make_request是一个循环,其通过每个块设备下注册的q->make_request_fn函数与块设备进行交互。如果访问的块设备是一个有queue的设备,那么会将系统的__make_request函数注册到q->make_request_fn中;否则块设备会注册一个私有的方法。在私有的方法中,由于不存在queue队列,所以不会处理具体的请求,而是通过修改bio中的方法实现bio的转发,在私有make_request方法中,往往会返回1,告诉generic_make_request继续转发比bio。Generic_make_request的执行上下文可能有两种,一种是用户上下文,另一种为pdflush所在的内核线程上下文。

8、 通过generic_make_request的不断转发,最后请求一定会到一个存在queue队列的块设备上,假设最终的那个块设备是某个scsi disk(/dev/sda)。generic_make_request将请求转发给sda时,调用__make_request,该函数是Linux提供的块设备请求处理函数。在该函数中实现了极其重要的操作,通常所说的IO Schedule就在该函数中实现。在该函数中试图将转发过来的bio merge到一个已经存在的request中,如果可以合并,那么将新的bio请求挂载到一个已经存在request中。如果不能合并,那么分配一个新的request,然后将bio添加到其中。这一切搞定之后,说明通过generic_make_request转发的bio已经抵达了内核的一个站点——request,找到了一个临时归宿。此时,还没有真正启动物理设备的操作。在__make_request退出之前,会判断一个bio中的sync标记,如果该标记有效,说明请求的bio是一个是实时性很强的操作,不能在内核中停留,因此调用了__generic_unplug_device函数,该函数将触发下一阶段的操作;如果该标记无效的话,那么该请求就需要在queue队列中停留一段时间,等到queue队列触发闹钟响了之后,再触发下一阶段的操作。__make_request函数返回0,告诉generic_make_request无需再转发bio了,bio转发结束。

9、 到目前为止,文件系统(pdflush或者address_space_operations)发下来的bio已经merge到request queue中,如果为sync bio,那么直接调用__generic_unplug_device,否则需要在unplug timer的软中断上下文中执行q->unplug_fn。后继request的处理方法应该和具体的物理设备相关,但是在标准的块设备上如何体现不同物理设备的差异性呢?这种差异性就体现在queue队列的方法上,不同的物理设备,queue队列的方法是不一样的。举例中的sda是一个scsi设备,在scsi middle level将scsi_request_fn函数注册到了queue队列的request_fn方法上。在q->unplug_fn(具体方法为:generic_unplug_device)函数中会调用request队列的具体处理函数q->request_fn。Ok,到这一步实际上已经将块设备层与scsi总线驱动层联系在了一起,他们的接口方法为request_fn(具体函数为scsi_request_fn)。

10、明白了第(9)点之后,接下来的过程实际上和具体的scsi总线操作相关了。在scsi_request_fn函数中会扫描request队列,通过elv_next_request函数从队列中获取一个request。在elv_next_request函数中通过scsi总线层注册的q->prep_rq_fn(scsi层注册为scsi_prep_fn)函数将具体的request转换成scsi驱动所能认识的scsi command。获取一个request之后,scsi_request_fn函数直接调用scsi_dispatch_cmd函数将scsi command发送给一个具体的scsi host。到这一步,有一个问题:scsi command具体转发给那个scsi host呢?秘密就在于q->queuedata中,在为sda设备分配queue队列时,已经指定了sda块设备与底层的scsi设备(scsi device)之间的关系,他们的关系是通过request queue维护的。

11、 在scsi_dispatch_cmd函数中,通过scsi host的接口方法queuecommand将scsi command发送给scsi host。通常scsi host的queuecommand方法会将接收到的scsi command挂到自己维护的队列中,然后再启动DMA过程将scsi command中的数据发送给具体的磁盘。DMA完毕之后,DMA控制器中断CPU,告诉CPU DMA过程结束,并且在中断上下文中设置DMA结束的中断下半部。DMA中断服务程序返回之后触发软中断,执行SCSI中断下半部。

12、在SCSi中断下半部中,调用scsi command结束的回调函数,这个函数往往为scsi_done,在scsi_done函数调用blk_complete_request函数结束请求request,每个请求维护了一个bio链,所以在结束请求过程中回调每个请求中的bio回调函数,结束具体的bio。Bio又有文件系统的buffer head生成,所以在结束bio时,回调buffer_head的回调处理函数bio->bi_end_io(注册为end_bio_bh_io_sync)。自此,由中断引发的一系列回调过程结束,总结一下回调过程如下:scsi_done->end_request->end_bio->end_bufferhead。

13、回调结束之后,文件系统引发的读写操作过程结束。

本文链接地址:https://www.jiuchutong.com/zhishi/280519.html 转载请保留说明!

上一篇:将在MAC电脑屏幕上的操作录制下来制成Gif格式动画(macbook直接显示桌面)

下一篇:PHP:ftp_rename()的用法_FTP函数

  • 饿了么可以用支付宝支付吗(饿了么可以用支付宝亲情卡吗)

    饿了么可以用支付宝支付吗(饿了么可以用支付宝亲情卡吗)

  • 苹果下载不需要输入ID密码如何设置(苹果下载不需要id的有什么软件)

    苹果下载不需要输入ID密码如何设置(苹果下载不需要id的有什么软件)

  • 快手如何设置听歌模式(快手如何设置听音)

    快手如何设置听歌模式(快手如何设置听音)

  • 卖家要你修改退款原因(卖家要你修改退款申请)

    卖家要你修改退款原因(卖家要你修改退款申请)

  • 三星s20可以双卡加内存卡吗(三星s20可以双卡双待吗)

    三星s20可以双卡加内存卡吗(三星s20可以双卡双待吗)

  • 手机超过15天怎么要求退换货(手机超过15天可以退吗)

    手机超过15天怎么要求退换货(手机超过15天可以退吗)

  • 什么是红外功能(红外功能在手机什么位置)

    什么是红外功能(红外功能在手机什么位置)

  • nova6支持wifi6吗(nova6支持5gwifi)

    nova6支持wifi6吗(nova6支持5gwifi)

  • qq电话通话内容能回放吗(qq电话通话内容怎么查)

    qq电话通话内容能回放吗(qq电话通话内容怎么查)

  • xr死机黑屏(xr突然卡住然后黑屏)

    xr死机黑屏(xr突然卡住然后黑屏)

  • iphone7plus有红外吗(iPhone7plus有红外功能吗)

    iphone7plus有红外吗(iPhone7plus有红外功能吗)

  • 京东30天无忧体验是什么意思(京东30天无忧体验怎么用)

    京东30天无忧体验是什么意思(京东30天无忧体验怎么用)

  • 手机为什么会突然震动(手机为什么会突然黑屏打不开)

    手机为什么会突然震动(手机为什么会突然黑屏打不开)

  • 手机长时间不用充电没反应怎么办(手机长时间不用会坏吗)

    手机长时间不用充电没反应怎么办(手机长时间不用会坏吗)

  • 苹果7p手写输入法在哪里设置(苹果7p手写输入不了)

    苹果7p手写输入法在哪里设置(苹果7p手写输入不了)

  • 摄像头一天用多少流量(摄像头一天用多少内存怎么算)

    摄像头一天用多少流量(摄像头一天用多少内存怎么算)

  • qq限制加好友处理多少天(QQ限制加好友处理多久才能恢复)

    qq限制加好友处理多少天(QQ限制加好友处理多久才能恢复)

  • 怎么复制自己淘宝账号(怎么复制自己淘宝店铺的短的链接)

    怎么复制自己淘宝账号(怎么复制自己淘宝店铺的短的链接)

  • 淘宝提交订单后怎么备注(淘宝提交订单后怎么修改地址)

    淘宝提交订单后怎么备注(淘宝提交订单后怎么修改地址)

  • 手机管家拦截的短信在哪里看(手机管家拦截的短信是不是看不到内容)

    手机管家拦截的短信在哪里看(手机管家拦截的短信是不是看不到内容)

  • 努比亚红魔3S像素多少(努比亚红魔3是什么型号)

    努比亚红魔3S像素多少(努比亚红魔3是什么型号)

  • 华为jsn tloo是什么型号(华为jsnaloo是什么型号)

    华为jsn tloo是什么型号(华为jsnaloo是什么型号)

  • 共享电动单车定位器在哪里(共享电动单车定位怎么拆除)

    共享电动单车定位器在哪里(共享电动单车定位怎么拆除)

  • 苹果手机锁屏时间怎么设置黑色(苹果手机锁屏时的照相机和手电怎么关闭)

    苹果手机锁屏时间怎么设置黑色(苹果手机锁屏时的照相机和手电怎么关闭)

  • 拼多多悬浮球怎么关闭(拼多多悬浮球怎么设置)

    拼多多悬浮球怎么关闭(拼多多悬浮球怎么设置)

  • 年报纳税总额能查到吗
  • 一般纳税人发生特定应税销售行为
  • 代缴税费
  • 一般纳税人的税点
  • 上年度暂估的票回不来一直挂帐吗
  • 固定资产未转固属于什么风险
  • 小规模差额征税全额开票和差额开票
  • 基本户的利息和本金比例
  • 重新建账 和之前数据差的多
  • 个税反推税前工资速算
  • 收到的货款与发票数不符,怎么做账
  • 应付账款收不回,可否转营业外收入
  • 计提工资数大于实际支付数怎么办?
  • 已确认并转销的应收账款会计分录
  • 处置资产发生的清理费计入
  • 企业年会的增值税能抵扣吗?
  • 出口退税是按进项税额吗
  • 发票勾选可以勾选几次
  • 工作量法计提折旧会计分录
  • 技术转让所得减去成本吗
  • 建筑企业能申请小微企业吗
  • 学校的房子归哪里管
  • 经营终止前企业资质变更
  • 固定资产大修理怎么界定
  • 增值税红字发票是什么意思
  • 企业所得税减免税额计算公式
  • 税收筹划有哪些特点?
  • win 11bug
  • world超链接
  • 什么货物出口最多
  • 企业会计师证是咋回事
  • 技术合同包括哪些类型
  • 设计行业开票税点
  • windows 10 21h1
  • 卖废旧物品账务处理
  • php 无限级分类
  • 小规模纳税人缴税标准是什么
  • 收到外单位委托办事的资金应该计入
  • 跨省经营建筑企业税收政策
  • php教程全集
  • 表单建模
  • php redis使用
  • 嵌入html
  • mongodb 查询条件
  • dpkg命令详解
  • linux sz命令使用
  • 应收账款期末余额在借方还是贷方
  • 帝国cms灵动标签调用外表
  • 资产负债表中衍生金融资产项目应根据什么科目填列
  • 预提的费用当年必须冲掉吗
  • 个体户开票额度超了
  • 典当行必须出具当票吗
  • 火车票报销抵扣比例是多少
  • 厂房维修费是制造费用还是管理费用
  • 计提工会经费会计分录怎么写
  • 汇算清缴的会计分录怎么做
  • 股东撤资后需要承担责任
  • 暂估入账会计科目
  • 置换房产怎么交税
  • 调整事项涉及损益的
  • 农业机耕属于种植业吗
  • 公对公转账必须签合同吗
  • 开机后cpu占用高
  • xp系统怎么调性能
  • macos触控
  • linux CentOS/redhat 6.5 LVM分区使用详解
  • wps linux版本是什么意思
  • linux查找文件语句
  • cocos2dx游戏有哪些
  • Tutorial 4: Shaders
  • css控制图片大小和宽度
  • easyui combobox onchange
  • js控制display属性
  • jquery封装原理
  • javascript基础
  • 税务局的人工资多少
  • 增值税的进项税额转出是什么意思
  • 上海自由贸易区图片
  • 江西税务登记证查询官网
  • 房屋设备租赁费
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设