linux核心md原始碼解讀 十二 raid讀寫

來源:互聯網
上載者:User

我們都知道,對一個linux塊裝置來說,都有一個對應的請求隊列。註冊在這個請求隊列上的請求就是該塊裝置的請求入口。對於raid來說,分配struct mddev時就已經設定好了,在函數md_alloc中有這樣的代碼:

4846 blk_queue_make_request(mddev->queue, md_make_request);  4847 blk_set_stacking_limits(&mddev->queue->limits);

雖然全國的PM一直保持著穩健的增長,但絲毫也阻擋不了我們看代碼的慧眼,在成千上萬行的代碼裡我們依然能夠迅速地找出raid讀寫入口就是md_make_request。

328/* Rather than calling directly into the personality make_request function,  329 * IO requests come here first so that we can check if the device is  330 * being suspended pending a reconfiguration.  331 * We hold a refcount over the call to ->make_request.  By the time that  332 * call has finished, the bio has been linked into some internal structure  333 * and so is visible to ->quiesce(), so we don't need the refcount any more.  334 */

我們在調用make_request函數之前,先檢查裝置是否因為重配置而掛起。在調用make_request函數之前,我們增加裝置的引用計數,在make_request調用完成時再遞減。增加裝置引用計數主要是為調用->quiesce()之前保證下發到裝置的IO已經完成。

335static void md_make_request(struct request_queue *q, struct bio *bio)  336{  337     const int rw = bio_data_dir(bio);  338     struct mddev *mddev = q->queuedata;  339     int cpu;  340     unsigned int sectors;  341  342     if (mddev == NULL || mddev->pers == NULL  343         || !mddev->ready) {  344          bio_io_error(bio);  345          return;  346     }  347     smp_rmb(); /* Ensure implications of  'active' are visible */348     rcu_read_lock();  349     if (mddev->suspended) {  350          DEFINE_WAIT(__wait);  351          for (;;) {  352               prepare_to_wait(&mddev->sb_wait, &__wait,  353                         TASK_UNINTERRUPTIBLE);  354               if (!mddev->suspended)  355                    break;  356               rcu_read_unlock();  357               schedule();  358               rcu_read_lock();  359          }  360          finish_wait(&mddev->sb_wait, &__wait);  361     }  362     atomic_inc(&mddev->active_io);  363     rcu_read_unlock();  364  365     /* 366     * save the sectors now since our bio can 367     * go away inside make_request 368     */369     sectors = bio_sectors(bio);  370     mddev->pers->make_request(mddev, bio);  371  372     cpu = part_stat_lock();  373     part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);  374     part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors);  375     part_stat_unlock();  376  377     if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)  378          wake_up(&mddev->sb_wait);  379}

337行,擷取IO方向,用於裝置資訊統計

338行,擷取陣列指標,該指標是在md_alloc中賦值的

342行,基本檢查

348行,訪問struct mddev資訊加rcu讀鎖

349行,陣列suspend

350行,如果陣列suspend,即前面注釋中講的正在重配置,則加入sb_wait等待隊列

360行,陣列完成suspend,從等待隊列中移除

362行,遞增陣列引用計數,在前面注釋裡有原因說明

370行,下發bio到陣列

372行,這個開始是資訊統計

377行,遞減陣列引用計數,如果正在重配置,則喚醒該進程

真正的資料通道命令也就370行這一句,其他的都是控制通道的。

對於raid5陣列,這個請求函數對應的是raid5.c中的make_request函數:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.