MD中bitmap源代码分析--设置流程
1. 同步/异步刷磁盘
Bitmap文件写磁盘分同步和异步两种:
1) 同步置位:当盘阵有写请求时,对应的bitmap文件相应bit被置位,bitmap内存页被设置了DIRTY标志。而在下发写请求给磁盘之前,必须保证bitmap文件下刷完成后才向磁盘发送写请求。这种情况需要等待写bitmap磁盘文件完成,因此是同步的。(由bitmap_unplug()完成)
之所以写bit要在写chunk数据之前就同步刷磁盘,因为如果写请求先下发了,而写bit在这之后刷磁盘的话,当写磁盘过程中发生故障,比如掉电,此时数据是不一致的,而磁盘的bitmap文件中由于还没来得及记录写bit在内存中置位的结果,导致之后会错误的认为数据是一致的。在通过bitmap_statrwrite()和bitmap_unplug()两步实现了bitmap中的bit批量下刷的情况下,实现了同步置位,是为了保证正确性。
2) 异步清零:当下发磁盘的写请求完成后,需要将bitmap内存页中相应的bit清零,然后把bitmap文件下刷。而这个过程不需要等待写bitmap磁盘文件完成,因此是异步的。(由bitmap_daemon_work()完成)
而清bit可以在写请求完成之后异步来做,因为就算是写失败,也不会影响正确性,只是会带来一次额外的同步。异步清零的机制好处在于,在还未清零或者内存位图清0但没有刷到磁盘的时候,又有对该页的写请求到来,就只用增加bmc计数器或者只是把内存位图置位,而不用再写到外存的位图文件中,从而减少了一次写外存位图的io。另外,异步清零也实现了bitmap中的bit批量下刷。
2. 写流程Bitmap的设置
在Raid1的写流程中,bitmap的设置操作主要在bitmap_statrwrite()、bitmap_unplug()、bitmap_endwrite()。
bitmap_statrwrite(),该函数在raid1中的make_request()中调用。在提交每个盘的bio到pending_bio_list之前调用该函数。
bitmap_statrwrite()的主要工作:
- 是对写请求的chunk对应bit置1;
- 设置对应bit的bitmap_attr为BITMAP_PAGE_DIRTY;
- 用*bmc来做尚未完成的写请求计数。
具体流程如下图所示:

- 如果是延迟写,则增加延迟写计数;
- 由于一个写操作涉及的数据段可能对应多个数据块(bitmap-chunk指定的大小),对于每个这样的数据块:
a) 获取该数据块的bitmap内存结构,即bp数组指向的内容;
b) 如果该数据块对应的counter达到最大值,说明盘阵上该数据区进行的写访问已经太多,盘阵等待太久,此时需要启动设备的队列处理;
c) 如果该数据块上没有正在进行的写操作(*bmc为0),设置filemap对应的bit,设置该bitmap页对应的bitmap_attr属性为BITMAP_PAGE_DIRTY,计数该页上有多少脏的chunk,将该数据块对应的计数*bmc直接设置为2;
d) 如果该数据块的内存位图已经置位,则将*bmc直接是设置为2;
e) 对应的bmc计数累加。
bitmap_unplug()的主要工作,遍历bitmap的所有filemap页:
- 如果页属性为BITMAP_PAGE_DIRTY,则将该页写入磁盘,同时清除BITMAP_PAGE_DIRTY。等待写入结束后返回。
- 如果页属性为BITMAP_PAGE_NEEDWRITE,则将该页写入磁盘,同时清除BITMAP_PAGE_NEEDWRITE。返回。
这里需要注意的是,如果只有BITMAP_PAGE_NEEDWRITE标记的页,是不需要等待的,因为bit的清除并不是很关键,即使这个信息丢失,最多不过是多余的同步操作而已,没有副作用。而bit的设置,则需要保证写入磁盘的“可靠”后,才能进行盘阵chunk的写入;否则在chunk数据写入磁盘时,对应的bitmap中的bit写入磁盘前,盘阵出现异常,则可能导致数据不一致而bitmap不能发觉。
bitmap_unplug()函数实现了下面两种机制:
实现bitmap同步刷磁盘:
- unplug函数的执行在写下发之前进行。raid1守护进程执行flush_pending_writes(),这个流程首先调用bitmap_unplug()处理,调用generic_make_request()下发chunk数据的写请求;
- bit写盘完全结束之后,才退出unplug函数。页属性BITMAP_PAGE_DIRTY 时,bitmap_unplug()是等待write_page()写盘完成之后才退出的。实现了bitmap同步刷磁盘,确保了数据的可靠性。
实现bitmap批量刷磁盘:
- bitmap_startwrite和bitmap_unplug两步实现。bitmap_unplug要遍历所有bitmap file缓存的page,bitmap_startwrite只针对一次写操作对应的bitmap file缓存的page。
bitmap_endwrite(),写完成后,取出对应数据段的bitmap内存结构:
- COUNT递减;
- 如果COUNT<=2,则设置对应filemap页的BITMAP_PAGE_CLEAN属性;
- 如果有chunk写失败,则设置对应bitmap的*bmc的NEEDED标志。表示需要同步。
具体的函数代码流程如下图所示:

3. 同步流程Bitmap的设置
bitmap_start_sync()。在chunk同步操作开始时,调用该函数。这个函数获取bitmap的内存结构:
- 如果NEEDED标志或者RESYNC标志被设置,就认为该数据块需要同步;
- 此时如果盘阵工作完好,则清除NEEDED标志,设置RESYNC标志;
- 如果NEEDED和RESYNC都没有设置,则认为该数据块不需要同步。
bitmap_end_sync()。chunk同步完成后,调用该函数。这个函数获取bitmap的内存结构:
- 如果RESYNC标志被设置,则清除该标志;
- 如果同步是失败的,则设置NEED位;
- 如果同步成功,并且COUNT<=2,则设置该页属性为BITMAP_PAGE_CLEAN,表示该页存在需要清除的bit位。
转载请注明出处:http://www.cnblogs.com/fangpei/
MD中bitmap源代码分析--设置流程的更多相关文章
- MD中bitmap源代码分析--清除流程
bitmap的清零是由bitmap_daemon_work()来实现的.Raid1守护进程定期执行时调用md_check_recovery,然后md_check_recovery会调用bitmap_d ...
- MD中bitmap源代码分析--入题概述
在MD模块中,各级raid都使用的一份bitmap的源码,也就是说共用一种bitmap的流程,下面以raid1的使用为例来分析bitmap的工作原理. 在使用raid1磁盘阵列的时候,对于数据的可靠性 ...
- MD中bitmap源代码分析--数据结构
本篇分析bitmap的数据结构的设计,并基于此分析bitmap的工作机制. 为了后面更清楚的理解,先有个总体印象,给出整体的结构图: 在下面的描述中涉及到的内容可以对照到上图中相应部分,便于理解. 首 ...
- MD中bitmap源代码分析--SYNC IO和RAID5的补充
最近在做bwraid的R6的设计工作,需要调研一下bitmap下刷磁盘的IO属性(是否为SYNC IO),还有raid5中bitmap的存储和工作方式. 1.bitmap刷磁盘是否为 SYNC IO? ...
- MD中bitmap源代码分析--状态机实例
1. page_attrs的状态转换关系 之前说过,bitmap的优化核心是:bitmap设置后批量写入:bitmap延时清除.写bit用bitmap_statrwrite() + bitmap_un ...
- Raid1源代码分析--同步流程
同步的大流程是先读,后写.所以是分两个阶段,sync_request完成第一个阶段,sync_request_write完成第二个阶段.第一个阶段由MD发起(md_do_sync),第二个阶段由守护进 ...
- Raid1源代码分析--写流程
正确写流程的总体步骤是,raid1接收上层的写bio,申请一个r1_bio结构,将其中的所有bios[]指向该bio.假设盘阵中有N块盘.然后克隆N份上层的bio结构,并分别将每个bios[]指向克隆 ...
- Raid1源代码分析--读流程(重新整理)
五.Raid1读流程分析 两个月前,刚刚接触raid1,就阅读了raid1读流程的代码,那个时候写了一篇博客.现在回过头看看,那篇的错误很多,并且很多地方没有表述清楚.所以还是决定重新写一篇以更正之前 ...
- Raid1源代码分析--读流程
这篇博文不足之处较多,重新整理了一下,链接:http://www.cnblogs.com/fangpei/p/3890873.html 我阅读的代码的linux内核版本是2.6.32.61.刚进实验室 ...
随机推荐
- QTimerLine类学习
QTimeLine类提供了控制动画的时间轴. 类型:enum CurveShape{EaseInCurve,EaseOutCurve,EaseInOutCurve,LinearCurve,Sine ...
- fork 和 vfork 的区别与联系
vfork用于创建一个新进程,而该新进程的目的是exec一个新进程,vfork和fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,不会复制页表.因为子进程会立即调用exec ...
- 关于lower_bound()的用法--NYOJ 201作业题
lower_bound它有三个参数, 第一个和第二个是给定区间起点和终点的指针,第三个参数是要查找的数,它的作用原理是在给定的区间中进行二分查找,这个二分区间是前开后闭的,他返回第一个大于等于它的函数 ...
- 【iOS之轮播视图、自定义UIPageControl】
基于UISrollView实现的无限循环轮播视图. 实现的思路:使用三个UIImageView不断循环利用,始终将最中间一个View显示在UIScrolView的contentSize上,每次滚动后, ...
- 30款jQuery常用网页焦点图banner图片切换 下载 (转)
1.jquery 图片滚动特效制作 slide 图片类似窗帘式图片滚动 查看演示 2.jquery幻灯片插件带滚动条的圆形立体图片旋转滚动 查看演示 3.jQuery图片层叠旋转类似洗牌翻转图片幻灯片 ...
- 基于jQuery仿uploadify的HTML5图片上传控件jquery.html5uploader
(function($){ var methods = { init:function(options){ return this.each(function(){ var $this = $(thi ...
- Thinkphp 上传图片
<?php // 本类由系统自动生成,仅供测试用途 class ListAction extends Action { public function index(){ //$name = 's ...
- 粗俗易懂的SQL存储过程在.NET中的实例运用
整理了一下存储过程在项目中的运用,防止遗忘,便记录于此!存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中.用户通过指定存储过程的名字并给出参数( ...
- Starting nagios:This account is currently not available nagios
nagios在启动时报错 # service nagios restartRunning configuration check…done.Stopping nagios: done.Starting ...
- 如何删除Windows服务
删除的办法有两个: 办法一: 用sc.exe这个Windows命令 开始——运行——cmd.exe,然后输入sc就可以看到了.使用办法很简单: sc delete &q ...