Raid1源代码分析--一些补充
Raid1的源码的读、写、同步,在本系列博客中都已经分析完成。除了barrier机制要专门拿出来分析(下一篇会写)以外,有一些问题值得思考和注意,分析如下。
1、freeze_array是如何做的?
通过barrier挡住上层用户io请求,并且nr_waiting++计数。nr_pending表示未完成的请求数,nr_queue表示retrylist的r1_bio数量。conf->nr_pending == conf->nr_queued+1表示没有正常的处理请求了,满足这个条件的时候就进行read error的处理;不满足的话,就进行后面的两个处理,之后wait。后面的两个处理是:flush_pending_writes(conf); raid1_unplug(conf->mddev->queue);第一句的意思是下发raid1层中未下发的所有写请求,第二句的意思是通知下层赶紧unplug下发请求。这里需要注意的是,读请求是在make_request中下发的,是用户上下文,并且nr_pending++也是在make_request中做的;而这里是daemon的上下文,所以只需要通知下层赶紧unplug就可以了。而写请求本来就是需要挂在pending list中由deamon来进行处理的,所以需要第一句下发raid1中还未下发的写请求。
假设一种情景,如果这时又有另外一个或者多个读出错,那么就是将其r1_bio挂到retry list上等待处理,deamon处理retry list链上的r1_bio是逐个进行处理,处理完一个之后才处理下一个,不会有并发产生。也就是说如果有两个读出错,那么需要等待前一个读出错处理流程完全做完之后,才可以做下一个。
另外需要说明的是,这里如果读出错的同一个磁盘位置,正好raid1有写请求还未下发,通知raid1层下发,那么就写了这个位置,当修复读出错位置完成之后,重发这个读请求,那么这次读请求其实是想读旧值,而其实这次读到的是新值,出现一致性问题。Raid1没有保证短时间内对同一个数据块同时读写的一致性,通常这是由上层文件系统层来保证的。
2、读均衡为什么能达到均衡,读均衡算法还有哪些缺陷?
因为当多个读并发的时候,可以尽可能均衡到各个盘中,提高并发读性能,即可以同时读,这样既利用每个盘的带宽提高了整体带宽,又均衡了每个盘的IO负载;而如果多个读是连续的,那么这几个读都落在一块盘上,因为不会发生磁头抖动,进而提高读性能。
但是缺陷还是有的:如果一个读IO很大,也只能选出一个盘作为读盘;更糟糕的是,如果连续多个读IO是顺序读,那么仍然落在一块盘上,导致顺序读性能受限于单盘性能;
解决办法我目前有两种思路:1、条带化,raid0就是这么干;2、bio切分,将大bio切分成小bio,并且限制每个盘的读IO的pending个数。
3、in_sync的作用?
在raid1中有两种in_sync,一种是mddev->in_sync,一种是rdev->flags的In_sync标志位。
mddev->In_sync标志位的作用,超级块中设计一个in_sync标志, 没有IO时,in_sync设置为1,并写回磁盘。 写操作遇到in_sync=1时,则先修改in_sync=0并写回 磁盘之后才执行。
rdev->flag的In_sync位为0,表示该盘不是active disk,不能工作,不可对其操作;In_sync位为1,表示该盘是active disk。
4、R1BIO_Returned标志位的作用?
bio_endio之前要进行test_and_set_bit(R1BIO_Returned, &r1_bio->state)来判断是否已经endio了,如果已经endio了,就不再进行bio_endio。R1BIO_Returned标志位的作用就在于此,当设置了延迟写的时候,存在还没有真正将所有盘的写操作完成的时候endio的,所以在真正将所有盘都返回的时候调用raid_end_bio_io(),会出现已经设置R1BIO_Returned的情景,则不需要再endio了。
5、IO_BLOCKED标志位的作用?
如果之前读失败的盘为只读状态,在守护进程处理读失败的时候,将r1_bio的该盘bio标记为IO_BLOCKED;接着调用read_balance函数,如果重新指定读盘成功,那么就重发read请求;如果重发的这次read请求还是失败了,同样还是会唤醒守护进程来处理读出错流程,这时又会调用到read_balance函数,而将之前的IO_BLOCKED传入进来,参与到这些流程中。也就是在只读盘上读失败之后,重发读请求,再次读失败的场景会使用到。
6、make_request函数中的do_barriers和do_sync变量的作用?
do_barriers标志接收到的bio的BIO_RW_BARRIER是否置位。如果接收到的上层bio->bi_rw的BIO_RW_BARRIER置位,则为1;BIO_RW_BARRIER不置位,则为0。
do_barriers有两个用途:
1、根据do_barriers来设置r1_bio->state的R1BIO_Barrier位;
2、根据do_barriers来设置要下发的bio的BIO_RW_BARRIER位。
7、r1_bio和conf结构中都有retry_list,但是r1_bio中没有pending_bio_list,这是为什么?
因为retry_list是由list_head组织起来的链表,其中的每个元素是r1_bio,对于这种组织方式,需要在每个r1_bio中都有一个list_head的结构从而可以找到上一项和下一项,这是一个双向链表;
而pending_bio_list是由bio组织起来的链表,其中的每个元素直接就是bio,直接用bio->bi_next就可以找到下一项了,这是一个单向链表。
8、为什么用户的read io是在make_request中下发的,而write io是在raid1d中下发的?
因为写io需要修改bitmap,在make_request中先标记一下DRITY位表示需要下刷,而放在deamon中,可以攒集一些write bio用来批量下刷。为了保证正确性,这些write bio在下刷之前要保证bitmap已经下刷到磁盘,所以在批量下刷写之前可以做到bitmap达到批量同步下刷,节省开销。
转载请注明出处:http://www.cnblogs.com/fangpei/
Raid1源代码分析--一些补充的更多相关文章
- Raid1源代码分析--开篇总述
前段时间由于一些事情耽搁了,最近将raid1方面的各流程整理了一遍.网上和书上,能找到关于MD下的raid1的文档资料比较少.决定开始写一个系列的关于raid1的博客,之前写过的一篇读流程也会在之后加 ...
- Raid1源代码分析--同步流程
同步的大流程是先读,后写.所以是分两个阶段,sync_request完成第一个阶段,sync_request_write完成第二个阶段.第一个阶段由MD发起(md_do_sync),第二个阶段由守护进 ...
- Raid1源代码分析--Barrier机制
本想就此结束Raid1的专题博客,但是觉得Raid1中自己构建的一套barrier机制的设计非常巧妙,值得单独拿出来分析.它保证了同步流程和正常读写流程的并发性,也为设备冻结/解冻(freeze/un ...
- Raid1源代码分析--写流程
正确写流程的总体步骤是,raid1接收上层的写bio,申请一个r1_bio结构,将其中的所有bios[]指向该bio.假设盘阵中有N块盘.然后克隆N份上层的bio结构,并分别将每个bios[]指向克隆 ...
- Raid1源代码分析--读流程(重新整理)
五.Raid1读流程分析 两个月前,刚刚接触raid1,就阅读了raid1读流程的代码,那个时候写了一篇博客.现在回过头看看,那篇的错误很多,并且很多地方没有表述清楚.所以还是决定重新写一篇以更正之前 ...
- Raid1源代码分析--初始化流程
初始化流程代码量比较少,也比较简单.主要是run函数.(我阅读的代码的linux内核版本是2.6.32.61) 四.初始化流程分析 run函数顾名思义,很简单这就是在RAID1开始运行时调用,进行一些 ...
- Raid1源代码分析--读流程
这篇博文不足之处较多,重新整理了一下,链接:http://www.cnblogs.com/fangpei/p/3890873.html 我阅读的代码的linux内核版本是2.6.32.61.刚进实验室 ...
- 转:SDL2源代码分析
1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...
- 转:RTMPDump源代码分析
0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...
随机推荐
- Windows Server 2008 R2 搭建FTP服务
一.安装ftp服务 1.在服务管理器"角色"右键单击"添加角色". 2.下一步. 3.勾选"Web 服务器(IIS)",下一步. 4.勾选 ...
- VS2015编译器问题简单记录
问题:VS2015community 无法查找或打开 pdb 文件 解决办法: 1.点击工具->选项, 在选项窗口中展开左侧菜单: 2.展开调试->常规,然后在右边的窗格中勾选“启用服务器 ...
- jQuery 基本实现功能模板
下面是列出了基本功能的实现 <!DOCTYPE html> <html> <head> <script src="http://libs.baidu ...
- 获取android手机联系人信息
package com.yarin.android.Examples_04_04; import android.app.Activity; import android.database.Curso ...
- ARGB和RGB
ARGB 一种色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常见于32位位图的存储结构. ARGB---Alpha,Red,Green,Blue. Alpha-图像通道 如果图形卡具有 ...
- 安卓手机内外SD卡互换
相信有許多人....有內置sd太小...外置sd(sdcard2或extsd)卻只能放資料.... 一些遊戲或者是影音播放軟體....根本不會去讀外置sd(sdcard2或extsd)..... 記憶 ...
- MultipeerConnectivity
Multipeer connectivity是一个使附近设备通过Wi-Fi网络.P2P Wi-Fi以及蓝牙个人局域网进行通信的框架.互相链接的节点可以安全地传递信息.流或是其他文件资源,而不用通过网络 ...
- iOS更改ShareSDK默认的分享功能界面
ShareSDK的集成这里就不详细介绍了, 官网的都已经够详细了.. 官方的默认分享样式如下: 贴上我的源代码: // 创建分享图片 NSString *imageURLString = @" ...
- pod update或者pod install很慢
最近使用CocoaPods来添加第三方类库,无论是执行pod install还是pod update都卡在了Analyzing dependencies不动 原因在于当执行以上两个命令的时候会升级Co ...
- printk和printf的区别
内核使用printk()打印! 应用层使用printf()打印! &&& 大部分常用的C库函数在Linux内核中都已经得到了实现.在所有没有实现的函数中,最著名的就数print ...