linux核心md原始碼解讀 十一 raid5d

來源:互聯網
上載者:User

正是有了上一篇的讀寫基礎,我們才開始看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 active\n");  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行,添加到預讀鏈表中

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.