日期:2014-05-16  浏览次数:20776 次

linux内核奇遇记之md源代码解读之五
linux内核奇遇记之md源代码解读之五
转载请注明出处:http://blog.csdn.net/liumangxiong
如果看懂了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         else
5429                 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(mdd