分类: LINUX
2015-07-25 18:21:47
函数在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对应page的bit位,再将此page对应的filemap_attr设置为BITMAP_PAGE_DIRTY位,最后设置*bmc=2;如果*bmc==1,也将此值赋值为2;
d) 将*bmc ++,此时此值为3,表示当前chunk写了1次(*bmc为0,表示没有写入操作;为1和2,特殊状态;为3,有1个写入,依次类推);
说明:
a) 设置filemap对应page的bit位,调用函数ext2_set_bit(bit, kaddr)实现
b) 设置对应page的filemap_attr位,先算出此page对应在filemap_attr中的位置(page->index<<2),然后将此值加上BITMAP_PAGE_DIRTY得到一个新的值tmp,然后调用__set_bit(tmp,bitmap->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,获取对应sector在bitmap->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,获取对应sector在bitmap->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-11,chunk=7,end_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位置