加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_镇江站长网 (https://www.0511zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux内核md源代码解读 十一 raid5d - Linux系统

发布时间:2014-03-24 10:22:56 所属栏目:Linux 来源:站长网
导读:正是有了上一篇的读写基础,我们才开始看raid5d的代码。raid5d不是读写的入口,也不是读写处理的地方,只是简简单单的中转站或者叫做交通枢纽。这个枢纽具有制
正是有了上一篇的读写基础,我们才开始看raid5d的代码。raid5d不是读写的入口,也不是读写处理的地方,只是简简单单的中转站或者叫做交通枢纽。这个枢纽具有制高点的作用,就像美国在新加坡的基地,直接就控制了太平洋和印度洋的交通枢纽。

4626 /* 
4627  * This is our raid5 kernel thread. 
4628  * 
4629  * We scan the hash table for stripes which can be handled now. 
4630  * During the scan, completed stripes are saved for us by the interrupt 
4631  * handler, so that they will not have to wait for our next wakeup. 
4632  */
4633 static void raid5d(struct mddev *mddev)  
4634 {  
4635         struct r5conf *conf = mddev->private;  
4636         int handled;  
4637         struct blk_plug plug;  
4638  
4639         pr_debug("+++ raid5d activen");  
4640  
4641         md_check_recovery(mddev);  
4642  
4643         blk_start_plug(&plug);  
4644         handled = 0;  
4645         spin_lock_irq(&conf->device_lock);  
4646         while (1) {  
4647                 struct bio *bio;  
4648                 int batch_size;  
4649  
4650                 if (  
4651                     !list_empty(&conf->bitmap_list)) {  
4652                         /* Now is a good time to flush some bitmap updates */
4653                         conf->seq_flush++;  
4654                         spin_unlock_irq(&conf->device_lock);  
4655                         bitmap_unplug(mddev->bitmap);  
4656                         spin_lock_irq(&conf->device_lock);  
4657                         conf->seq_write = conf->seq_flush;  
4658                         activate_bit_delay(conf);  
4659                 }

4641行,md_check_recovery这个函数前面看过了,用来检查触发同步

4643行,blk_start_plug和4688行blk_finish_plug是一对,用于合并请求。

4646行,这里为什么要来个大循环呢?刚开始看4629行注释可能有点迷糊,可是看到这个循环就知道原来讲的是这里,4629行注释说我们不必等到下次唤醒raid5线程,可以继续处理stripes,因为可能有stripes已经在中断处理函数里处理完成返回了。

4651行,判断阵列对应的bitmap_list是否为空,如果这个链表不为空则进入分支。bitmap跟条带处理有什么关系呢?这个问题就比较有历史性了。对于raid5阵列来说,最可怕的事情莫过于在写的过程中异常掉电,这就意味阵列不知道哪些数据是一致的,哪些是不一致的?这就是safemode干的事情,用来记录阵列数据是否一致。然而数据不一致导致的代码是全盘同步,这个是raid5最头疼的问题。好了,现在有bitmap了可以解决这个问题啦,太happy啦。那bitmap是如何解决这个问题的呢?bitmap说你写每个条带的时候我都记录一下,写完成就清除一下。如果异常掉电就只要同步掉电时未写完成的条带就可以啦。娃哈哈太happy了!!!但是请别高兴的太早,bitmap也不是一个好侍候的爷,bitmap必须要在写条带之前写完成,这里的写完成就是要Write Through即同步写。这下悲催了,bitmap的写过程太慢了,完全拖垮了raid5的性能。于是有了这个的bitmap_list,raid5说,bitmap老弟你批量写吧,有点类似bio的合并请求。但是这也只能部分弥补bitmap带来的负面性能作用。

4655行,下发bitmap批量写请求。
4657行,更新bitmap批量写请求的序号。

4658行,将等待bitmap写的条带下发。

4660                 raid5_activate_delayed(conf);  

4660行,看函数名就是激活延迟条带的意思。那么为什么要延迟条带的处理呢?按照块设备常用的手段,延迟处理是为了合并请求,这里也是同样的道理。那么条带什么时候做延迟处理呢?我们跟进raid5_activate_delayed函数:

3691static void raid5_activate_delayed(struct r5conf *conf)  
3692{  
3693     if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) {  
3694          while (!list_empty(&conf->delayed_list)) {  
3695               struct list_head *l = conf->delayed_list.next;  
3696               struct stripe_head *sh;  
3697               sh = list_entry(l, struct stripe_head, lru);  
3698               list_del_init(l);  
3699               clear_bit(STRIPE_DELAYED, &sh->state);  
3700               if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))  
3701                    atomic_inc(&conf->preread_active_stripes);  
3702               list_add_tail(&sh->lru, &conf->hold_list);  
3703          }  
3704     }  
3705}

3693行,这里控制预读数量。

3694行,遍历阵列延迟处理链表

3695行,获取阵列延迟处理链表表头

3697行,获取阵列延迟处理链表第一个条带

3698行,从阵列延迟处理链表取出一个条带

3700行,设置预读标志

3702行,添加到预读链表中

(编辑:应用网_镇江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!