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

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

文章分类

全部博文(25)

文章存档

2015年(25)

我的朋友

分类: LINUX

2015-07-26 11:59:25


前面所列出的函数,涵盖了全部的bitmap核心函数。不过只有bit的设置,并没有bit的清除。
对于可以清除的bit,最多只是设置了filemap对应页的CLEAN标记,没有实际的清除filemap中的bit和写入磁盘操作。

Bitmapbit清除操作是在bitmap_daemon_work函数,此函数在raid5d中的md_check_recovery函数中调用,而且是一进函数就被调用。
因为raid5d是处理IO请求的进程(包括上层应用的IO请求和恢复、同步时自身触发的IO请求),所以此函数在每次守护进程运行时,都会被调用。

函数bitmap_daemon_work

这个函数逻辑上比较绕,但可以看到:
1. 执行
磁盘位图结构filemap中每个chunk清除的工作是在该chunk对应的内存位图结构bitmap_page*bmc=1后进行的,
2. 写盘操作是在
filemap页的状态为NEEDWRITE后进行的。

所以要理清逻辑关系,还需要对每个
chunk*bmc的值和filemap的状态变化以及相互的关系做一个详细的了解:
1. 
*bmc是用来描述每个chunk对应在内存位图结构bitmap_page中的状态,共占16 bit
    
a)   最高位为NEED_MASK,表示需要进行数据恢复;
    
b)   第二位为RESYNC_MASK,表示数据恢复到当前chunk被终止,需要下次从此位置开始接着恢复;
    
c)   14位是一个计数器counter,表示当前chunk被写的次数,counter值前面讲过,包括特殊的0、1、2以及用来计数的大于2的值:
        
i)  012,这三个值都说明该chunk没有写操作进行,真正的写操作是从2开始累加的(bitmap_startwrite);但是0表示该chunk没有设置,1表示已经设置,2表示所有写操作刚刚结束
        
ii) 3开始,描述被写的次数,为3表示写1次,依次类推;
2. Filemap页的属性,CLEAN表示该页有bit需要清除;在CLEAN被清除后,会被设置NEEDWRITE属性,再次走进此daemon时,检测到NEEDWRITE标志被设置,会先清除此标记,然后把bitmap数据写入底层磁盘。

整个函数的大概流程如下:
1. 检查bitmap_daemon_work是否睡眠足够长时间(当前时间-(上次运行时间+5s)),没有睡够就退出了;睡眠一段时间可以将一定时间内的写盘操作集中批量处理;
2. 
遍历整个底层磁盘的trunks,获取每个trunk对应在mdev->filemap数组中的page,然后处理如下:
    
a)   如果该page没有设置BITMAP_PAGE_CLEAN(简称CLEAN)标记,再检查有没有设置BITMAP_PAGE_NEEDWRITE(简称NEED)标记:
          
没有NEED标记,则跳过此page;
          
NEED标记,先清除NEED标记,然后将此page的内容写入底层磁盘(不需要等待bio完全返回),然后跳过此page
    
b)   如果该page设置了CLEAN标记,清除CLEAN标记;在本次bitmap_daemon_work执行中,清除该page的CLEAN标记只有这一次机会;如果在本次bitmap_daemon_work执行中,再次设置了CLEAN标记,也只能等待下次再执行时被清除了。
    
c)   获取该chunk对应的内存位图结构bitmap_page(二级位图)中对应map(指向page指针)中的状态*bmc(bitmap_counter)
       
  如果bmc存在,且bmc的状态NEEDRESYNC没有设置(*bmc=2,表明该chunk对应所在的内存结构中的md数据段已经没有写访问),设置*bmc=1,并且将该chunk对应的磁盘位图结构filemap(一级位图)中对应的page设置标记CLEAN
          
如果bmc存在,且*bmc=1,则设置*bmc=0,调用函数bitmap_count_page,减少此chunk对应内存位图结构bitmap_page中的计数count,如果计数count==0,则释放该内存bitmap_page中申请的page;调用函数ext2_clear_bit清除该chunk对应磁盘位图结构filemap中的bit位;
          
如果bmc不存在,继续跳转到内存位图结构bitmap_page中下一个map所对应的起始chunk
    
d)   磁盘位图结构中每个page中的chunk处理完成,都会判断该page是否设置了标记BITMAP_PAGE_NEEDWRITE(前提条件是该页的CLEAN标记在处理时被设置,然后刚刚在此流程中清除)
          
标记被设置,则清除NEED标记,然后将该页写入底层磁盘;
         
标记没有被设置,则设置NEED标记;

函数bitmap_count_page

此函数用于处理counter值的加减,其传入参数如下:
1. struct bitmap *bitmapbitmap结构;
2. 
sector_t offset:单位sector
3. 
int inc: 可以传入1或者-1,用于加/bitmap->bp[page].count计数,表示此page对应有一个写或者一个写完成。

会在内部调用函数bitmap_checkfree,当判断到bitmap->bp[page].count==0时,表示此bitmap->bp[page]已经完全处理,这个时候可以释放掉申请的page空间,bitmap->bp[page]->map=NULL

注:在写流程中调用函数bitmap_startwrite时会给bitmap->bp[page]->map申请page空间。

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