Chinaunix首页 | 论坛 | 博客
  • 博客访问: 127100
  • 博文数量: 25
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 251
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-29 14:18
个人简介

不以物喜,勿以己悲;乐观向上,持之以恒。

文章分类

全部博文(25)

文章存档

2015年(25)

我的朋友

分类: LINUX

2015-07-25 18:21:47


BitmapMD设备处理写访问请求时,调用了函数bitmap_startwrite设置bitmap内存信息,包括内存中的bitmap结构,以及内存中bitmap磁盘文件的映射表filemap;在md设备实际将写请求提交给底层设备前,调用函数bitmap_unplugbitmap信息写入磁盘。
除以上两个函数外,bitmap_start_sync,bitmap_end_sync,bitmap_endwrite等函数也和bitmap的一些状态设置有关。

函数bitmap_startwrite

函数在MD设备处理写请求时(make_request --> add_stripe_bio)调用。
函数主要完成:
1. 如果是延迟写,增加延迟写计数;
2. 
由于一个写操作的数据长度可能对应在内存位图中多个chunk,对于每个这样的chunk,有以下处理(这里传入的大小为STRIPE_SECTORS)
    
a)   获取该chunk对应的内存结构bp[page],返回bp数组指向的内容*bmc(表示该chunk的状态):调用函数bitmap_get_counter实现,如果找不到对应的bp[page],则申请一个新的page
    
b)   如果该bitmap*bmc达到最大值,说明md设备上对此chunk进行写的次数太多了,磁盘等待了太久,就需要启动设备的队列处理;
    
c)   如果bitmap上没有正在写操作(*bmc==0),设置此chunk磁盘位图结构filemap对应pagebit位,再将此page对应的filemap_attr设置为BITMAP_PAGE_DIRTY位,最后设置*bmc=2;如果*bmc==1,也将此值赋值为2
    d)   将*bmc ++,此时此值为3,表示当前chunk写了1次(*bmc为0,表示没有写入操作;为1和2,特殊状态;为3,有1个写入,依次类推);
说明:
    a)   
设置filemap对应pagebit位,调用函数ext2_set_bit(bit, kaddr)实现
    b)   
设置对应pagefilemap_attr位,先算出此page对应在filemap_attr中的位置(page->index<<2),然后将此值加上BITMAP_PAGE_DIRTY得到一个新的值tmp,然后调用__set_bit(tmpbitmap->filemap_attr)进行位设置。

函数bitmap_unplug

此函数只在函数bitmap_set_bits和函数raid5d中调用。
函数实现功能为检查每个filemap,然后将信息写入底层磁盘。
流程如下:

流程说明:
1. 遍历bitmap所有的filemap页,如有标记为脏的页,或者需要写入的页,需要调用函数write_page将该页写入磁盘;
2. 
如果有脏页,需要等待mddev->biolist(保存bitmap未处理完成的bio)所有bio处理结束函数才能返回;
3. 
函数write_page,实际调用函数write_sb_page处理;此函数会先判断下发的sector是否越界,没有越界就调用函数md_super_write将数据写入底层磁盘,
   假设组成MD设备的
成员盘data_offset=2048存放超级块和bitmap数据,公式如下:
   
rdev->sb_start+offset+page->index*(PAGE_SIZE/512)+size/512>rdev->data_offset
4. 
如果只有BITMAP_PAGE_NEEDWRITE标记的页,是不需要等待的。因为bit的清除并不是很关键,即使这个信息丢失,最多不过是多余的同步操作而已,没有副作用。而bit设置则需要可靠写入磁盘后方可进行md设备数据的写入,否则在数据写入底层磁盘过程中,bitmap写入底层磁盘前,MD设备出现异常,可能会导致数据不一致而bitmap不能发觉。

函数bitmap_endwrite

此函数在函数handle_failed_stripe和函数handle_stripe_clean_event中调用,第一个函数只有在raid5设备有两块及以上成员盘失效时被调用,这里不考虑;第二个函数在hanle_stripe中写数据完成后调用,会循环所有的成员盘,然后逐个调用此函数。

函数bitmap_endwrite实现功能如下:
1. 调用函数bitmap_get_counter,取出对应chunk在内存位图结构bitmap_page中的状态*bmc
2. 
*bmc递减,表示一个写入操作完成;
3. 
 检查*bmc值,如果小于3,设置对应filemap页标记BITMAP_PAGE_CLEAN

函数bitmap_start_sync

函数在MD设备需要恢复、同步时调用(函数sync_request)

主要调用函数bitmap_get_counter,获取对应sectorbitmap->bp[page].map[pageoff]中的状态bitmap_counter,检测此状态:
1. 如果NEED标志或者RESYNC标志被设置,就认为该数据块需要同步;
2. 如果
NEED标志被设置,且md设备工作完好,需要清除NEED标志,设置RESYNC标志;
3. 
如果以上两个标志都没有设置或者某个sector在bitmap->bp[page].map不存在,则认为该sector对应的数据块不需要同步。

函数bitmap_end_sync

此函数同样也在函数sync_request中调用。

主要调用函数bitmap_get_counter,获取对应sectorbitmap->bp[page].mp[pageoff]中的状态bitmap_counter,检测此状态:
1. 如果RESYNC标志被设置,清除该标志
2. 
如果数据恢复、同步被终止,设置NEED标志;
3. 
如果bitmap_counter值小于3,表示当前page内对应的sector没有写入操作,设置该page对应的filemap_attr中的标记BITMAP_PAGE_CLEAN,表示该页需要清除bit位


函数bitmap_store

此函数在sys接口bitmap_set_bits中设置需要恢复的数据段时被调用,此接口支持的输入格式为:echo “0 7-11 50 52-100 ” > /sys/block/mdx/md/bitmap_set_bits,其中“0 7-11 50 52-100 ”数值段代表bitmap_chunk号,md设备共有多少个chunk可以根据mddev->devsectors值和输入的bitmap_chunksize计算得出

函数主要实现内容:
1. 获取其中一段数据段,如7-11chunk=7end_chunk=11
2. 
chunk的值和end_chunk的值传入函数bitmap_dirty_bits
    
a)   chunk开始,设置该chunk代表磁盘位图filemap中的状态为BITMAP_PAGE_CLEAN,并且为该chunk在内存位图bp中申请一个page,并将内存位图中描述此chunk的状态*bmc设置成NEEDED_MASK
    
b)   设备该chunk在磁盘位图filemap中对应的bit位,并将其对应在filemap中的page设置为BITMAP_PAGE_DIRTY标记
    
c)   修改当前恢复位置mddev->recovery_cp为此chunk对应的第一个sector位置

3. 调用函数bitmap_unplue,将此状态位写入组成MD设备的每个成员盘中。

未完 -- 待续。下一节将讲述bitmap的状态清除过程。


阅读(2079) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~