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个数。

3in_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。

4R1BIO_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了。

5IO_BLOCKED标志位的作用?

如果之前读失败的盘为只读状态,在守护进程处理读失败的时候,将r1_bio的该盘bio标记为IO_BLOCKED;接着调用read_balance函数,如果重新指定读盘成功,那么就重发read请求;如果重发的这次read请求还是失败了,同样还是会唤醒守护进程来处理读出错流程,这时又会调用到read_balance函数,而将之前的IO_BLOCKED传入进来,参与到这些流程中。也就是在只读盘上读失败之后,重发读请求,再次读失败的场景会使用到。

6make_request函数中的do_barriersdo_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位。

7r1_bioconf结构中都有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源代码分析--一些补充的更多相关文章

  1. Raid1源代码分析--开篇总述

    前段时间由于一些事情耽搁了,最近将raid1方面的各流程整理了一遍.网上和书上,能找到关于MD下的raid1的文档资料比较少.决定开始写一个系列的关于raid1的博客,之前写过的一篇读流程也会在之后加 ...

  2. Raid1源代码分析--同步流程

    同步的大流程是先读,后写.所以是分两个阶段,sync_request完成第一个阶段,sync_request_write完成第二个阶段.第一个阶段由MD发起(md_do_sync),第二个阶段由守护进 ...

  3. Raid1源代码分析--Barrier机制

    本想就此结束Raid1的专题博客,但是觉得Raid1中自己构建的一套barrier机制的设计非常巧妙,值得单独拿出来分析.它保证了同步流程和正常读写流程的并发性,也为设备冻结/解冻(freeze/un ...

  4. Raid1源代码分析--写流程

    正确写流程的总体步骤是,raid1接收上层的写bio,申请一个r1_bio结构,将其中的所有bios[]指向该bio.假设盘阵中有N块盘.然后克隆N份上层的bio结构,并分别将每个bios[]指向克隆 ...

  5. Raid1源代码分析--读流程(重新整理)

    五.Raid1读流程分析 两个月前,刚刚接触raid1,就阅读了raid1读流程的代码,那个时候写了一篇博客.现在回过头看看,那篇的错误很多,并且很多地方没有表述清楚.所以还是决定重新写一篇以更正之前 ...

  6. Raid1源代码分析--初始化流程

    初始化流程代码量比较少,也比较简单.主要是run函数.(我阅读的代码的linux内核版本是2.6.32.61) 四.初始化流程分析 run函数顾名思义,很简单这就是在RAID1开始运行时调用,进行一些 ...

  7. Raid1源代码分析--读流程

    这篇博文不足之处较多,重新整理了一下,链接:http://www.cnblogs.com/fangpei/p/3890873.html 我阅读的代码的linux内核版本是2.6.32.61.刚进实验室 ...

  8. 转:SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...

  9. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

随机推荐

  1. [Javascript] Intro to Recursion

    Recursion is a technique well suited to certain types of tasks. In this first lesson we’ll look at s ...

  2. NYOJ 1091 超大01背包(折半枚举)

    这道题乍一看是普通的01背包,最最基础的,但是仔细一看数据,发现普通的根本没法做,仔细观察数组发现n比较小,利用这个特点将它划分为前半部分和后半部分这样就好了,当时在网上找题解,找不到,后来在挑战程序 ...

  3. NYOJ-569最大公约数之和

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=569 此题目可以用筛选法的思想来做,但是用到一个欧拉函数 gcd(1,12)=1,gcd( ...

  4. 组合控件 圆环 ring

    使用 可以设置内部填充样式及大小 可以设置边框颜色及宽度 这里只是介绍了其中一种实现方式,其实这种类型的东西完全可以用自定义View去实现,他就是一个空中的大圆+一个空中或实心的小圆,实现起来也是非常 ...

  5. Java类与类之间关系总结

    继承,依赖,关联,聚合,组合 一般来说依赖和关联是类似的,关联是强依赖,聚合和组合是一类,组合属于强聚合. 继承:一般是子类和父类之间的关系,关键字extends 依赖:可以这样记忆,做某件事必须要依 ...

  6. CSS简要内容

    1. 简介 用于布局与美化网页(颜色,字体) CSS语言是一种标记语言,不需编译,可直接由浏览器执行 大小写不敏感 CSS定义由选择符.属性.属性取值组成 格式:selector{property:v ...

  7. sping注解原理

    持续更新中.. spring注解用的是java注解,用到的是java反射机制. 参考文档如下: http://zxf-noimp.iteye.com/blog/1071765 对应spring源码如下 ...

  8. 启动android程序报错

    提示错误如下: The connection to adb is down, and a severe error has occured. [2010-03-11 09:36:56 - HelloO ...

  9. php Socket基础

    ◆ Socket 基础PHP使用Berkley的socket库来创建它的连接.socket只不过是一个数据结构.你使用这个socket数据结构去开始一个客户端和服务器之间的会话.这个服务器是一直在监听 ...

  10. 关于android:screenOrientation="portrait"等

    1.android:screenOrientation="portrait",表示当切换横竖屏的时候,屏幕的内容始终以竖屏显示,而不会根据屏幕的方向来显示内容. 2.插入个Andr ...