linux核心md原始碼解讀 五 介紹raidd5陣列的運行

來源:互聯網
上載者:User

如果看懂了raid1陣列的run函數,那麼看raid5陣列run就非常輕鬆了,因為兩者要做的事情都是大同小異。

raid5的run函數很長,但很大一部分跟建立運行是沒有關係的,特別是有一段跟reshape相關的,大多數系統都不關注該功能,因此可以直接跳過。經過刪減之後的run函數如下:

5307 static int run(struct mddev *mddev)  5308 {  5309         struct r5conf *conf;  5310         int working_disks = 0;  5311         int dirty_parity_disks = 0;  5312         struct md_rdev *rdev;  5313         sector_t reshape_offset = 0;  5314         int i;  5315         long long min_offset_diff = 0;  5316         int first = 1;  ...  5426         if (mddev->private == NULL)  5427                 conf = setup_conf(mddev);  5428         else5429                 conf = mddev->private;  5430  5431         if (IS_ERR(conf))  5432                 return PTR_ERR(conf);  5433  5434         conf->min_offset_diff = min_offset_diff;  5435         mddev->thread = conf->thread;  5436         conf->thread = NULL;  5437         mddev->private = conf;  ...  5491         /* 5492          * 0 for a fully functional array, 1 or 2 for a degraded array. 5493          */5494         mddev->degraded = calc_degraded(conf);  ...  5503         /* device size must be a multiple of chunk size */5504         mddev->dev_sectors &= ~(mddev->chunk_sectors - 1);  5505         mddev->resync_max_sectors = mddev->dev_sectors;  ...  5556         md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));  5557  5558         if (mddev->queue) {  ...  5628         }  5629  5630         return 0;

是不是感覺超級簡單呢,就像有些事情表面上看起來很複雜,但只要認真地去分析之後發現其實是有規律可循的。就像這個run函數,做的事情與raid1的run是相同的,就是建立讀寫的上下文環境。

5427行,建立struct r5conf,跟進函數:

5131 static struct r5conf *setup_conf(struct mddev *mddev)  5132 {  5133         struct r5conf *conf;  5134         int raid_disk, memory, max_disks;  5135         struct md_rdev *rdev;  5136         struct disk_info *disk;  5137         char pers_name[6];  5138  5139         if (mddev->new_level != 5  5140             && mddev->new_level != 4  5141             && mddev->new_level != 6) {  5142                 printk(KERN_ERR "md/raid:%s: raid level not set to 4/5/6 (%d)\n",  5143                        mdname(mddev), mddev->new_level);  5144                 return ERR_PTR(-EIO);  5145         }  5146         if ((mddev->new_level == 5  5147              && !algorithm_valid_raid5(mddev->new_layout)) ||  5148             (mddev->new_level == 6  5149              && !algorithm_valid_raid6(mddev->new_layout))) {  5150                 printk(KERN_ERR "md/raid:%s: layout %d not supported\n",  5151                        mdname(mddev), mddev->new_layout);  5152                 return ERR_PTR(-EIO);  5153         }  5154         if (mddev->new_level == 6 && mddev->raid_disks < 4) {  5155                 printk(KERN_ERR "md/raid:%s: not enough configured devices (%d, minimum 4)\n",  5156                        mdname(mddev), mddev->raid_disks);  5157                 return ERR_PTR(-EINVAL);  5158         }  5159  5160         if (!mddev->new_chunk_sectors ||  5161             (mddev->new_chunk_sectors << 9) % PAGE_SIZE ||  5162             !is_power_of_2(mddev->new_chunk_sectors)) {  5163                 printk(KERN_ERR "md/raid:%s: invalid chunk size %d\n",  5164                        mdname(mddev), mddev->new_chunk_sectors << 9);  5165                 return ERR_PTR(-EINVAL);  5166         }  5167  5168         conf = kzalloc(sizeof(struct r5conf), GFP_KERNEL);  5169         if (conf == NULL)  5170                 goto abort;  5171         spin_lock_init(&conf->device_lock);  5172         init_waitqueue_head(&conf->wait_for_stripe);  5173         init_waitqueue_head(&conf->wait_for_overlap);  5174         INIT_LIST_HEAD(&conf->handle_list);  5175         INIT_LIST_HEAD(&conf->hold_list);  5176         INIT_LIST_HEAD(&conf->delayed_list);  5177         INIT_LIST_HEAD(&conf->bitmap_list);  5178         INIT_LIST_HEAD(&conf->inactive_list);  5179         atomic_set(&conf->active_stripes, 0);  5180         atomic_set(&conf->preread_active_stripes, 0);  5181         atomic_set(&conf->active_aligned_reads, 0);  5182         conf->bypass_threshold = BYPASS_THRESHOLD;  5183         conf->recovery_disabled = mddev->recovery_disabled - 1;  5184  5185         conf->raid_disks = mddev->raid_disks;  5186         if (mddev->reshape_position == MaxSector)  5187                 conf->previous_raid_disks = mddev->raid_disks;  5188         else5189                 conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;  5190         max_disks = max(conf->raid_disks, conf->previous_raid_disks);  5191         conf->scribble_len = scribble_len(max_disks);  5192  5193         conf->disks = kzalloc(max_disks * sizeof(struct disk_info),  5194                               GFP_KERNEL);  5195         if (!conf->disks)  5196                 goto abort;  5197  5198         conf->mddev = mddev;  5199  5200         if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)  5201                 goto abort;  5202  5203         conf->level = mddev->new_level;  5204         if (raid5_alloc_percpu(conf) != 0)  5205                 goto abort;  5206  5207         pr_debug("raid456: run(%s) called.\n", mdname(mddev));  5208  5209         rdev_for_each(rdev, mddev) {  5210                 raid_disk = rdev->raid_disk;  5211                 if (raid_disk >= max_disks  5212                     || raid_disk < 0)  5213                         continue;  5214                 disk = conf->disks + raid_disk;  5215  5216                 if (test_bit(Replacement, &rdev->flags)) {  5217                         if (disk->replacement)  5218                                 goto abort;  5219                         disk->replacement = rdev;  5220                 } else {  5221                         if (disk->rdev)  5222                                 goto abort;  5223                         disk->rdev = rdev;  5224                 }  5225  5226                 if (test_bit(In_sync, &rdev->flags)) {  5227                         char b[BDEVNAME_SIZE];  5228                         printk(KERN_INFO "md/raid:%s: device %s operational as raid"5229                                " disk %d\n",  5230                                mdname(mddev), bdevname(rdev->bdev, b), raid_disk);  5231                 } else if (rdev->saved_raid_disk != raid_disk)  5232                         /* Cannot rely on bitmap to complete recovery */5233                         conf->fullsync = 1;  5234         }  5235  5236         conf->chunk_sectors = mddev->new_chunk_sectors;  5237         conf->level = mddev->new_level;  5238         if (conf->level == 6)  5239                 conf->max_degraded = 2;  5240         else5241                 conf->max_degraded = 1;  5242         conf->algorithm = mddev->new_layout;  5243         conf->max_nr_stripes = NR_STRIPES;  5244         conf->reshape_progress = mddev->reshape_position;  5245         if (conf->reshape_progress != MaxSector) {  5246                 conf->prev_chunk_sectors = mddev->chunk_sectors;  5247                 conf->prev_algo = mddev->layout;  5248         }  5249  5250         memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +  5251                  max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;  5252         if (grow_stripes(conf, conf->max_nr_stripes)) {  5253                 printk(KERN_ERR  5254                        "md/raid:%s: couldn't allocate %dkB for buffers\n",  5255                        mdname(mddev), memory);  5256                 goto abort;  5257         } else5258                 printk(KERN_INFO "md/raid:%s: allocated %dkB\n",  5259                        mdname(mddev), memory);  5260  5261         sprintf(pers_name, "raid%d", mddev->new_level);  5262         conf->thread = md_register_thread(raid5d, mddev, pers_name);  5263         if (!conf->thread) {  5264                 printk(KERN_ERR  5265                        "md/raid:%s: couldn't allocate thread.\n",  5266                        mdname(mddev));  5267                 goto abort;  5268         }  5269  5270         return conf;

聯繫我們

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