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

linux内核奇遇记之md源代码解读之六
linux内核奇遇记之md源代码解读之六
转载请注明出处:http://blog.csdn.net/liumangxiong
raid10的run函数与raid5的run函数最大区别在于setup_conf,那就直接深入核心:
3540 static struct r10conf *setup_conf(struct mddev *mddev)
3541 {
3542         struct r10conf *conf = NULL;
3543         int err = -EINVAL;
3544         struct geom geo;
3545         int copies;
3546 
3547         copies = setup_geo(&geo, mddev, geo_new);
3548 
3549         if (copies == -2) {
3550                 printk(KERN_ERR "md/raid10:%s: chunk size must be "
3551                        "at least PAGE_SIZE(%ld) and be a power of 2.\n",
3552                        mdname(mddev), PAGE_SIZE);
3553                 goto out;
3554         }
3555 
3556         if (copies < 2 || copies > mddev->raid_disks) {
3557                 printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n",
3558                        mdname(mddev), mddev->new_layout);
3559                 goto out;
3560         }
3561 
3562         err = -ENOMEM;
3563         conf = kzalloc(sizeof(struct r10conf), GFP_KERNEL);
3564         if (!conf)
3565                 goto out;
3566 
3567         /* FIXME calc properly */
3568         conf->mirrors = kzalloc(sizeof(struct raid10_info)*(mddev->raid_disks +
3569                                                             max(0,-mddev->delta_disks)),
3570                                 GFP_KERNEL);
3571         if (!conf->mirrors)
3572                 goto out;
3573 
3574         conf->tmppage = alloc_page(GFP_KERNEL);
3575         if (!conf->tmppage)
3576                 goto out;
3577 
3578         conf->geo = geo;
3579         conf->copies = copies;
3580         conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc,
3581                                            r10bio_pool_free, conf);
3582         if (!conf->r10bio_pool)
3583                 goto out;
3584 
3585         calc_sectors(conf, mddev->dev_sectors);
3586         if (mddev->reshape_position == MaxSector) {
3587                 conf->prev = conf->geo;
3588                 conf->reshape_progress = MaxSector;
3589         } else {
3590                 if (setup_geo(&conf->prev, mddev, geo_old) != conf->copies) {
3591                         err = -EINVAL;
3592                         goto out;
3593                 }
3594                 conf->reshape_progress = mddev->reshape_position;
3595                 if (conf->prev.far_offset)
3596                         conf->prev.stride = 1 << conf->prev.chunk_shift;
3597                 else
3598                         /* far_copies must be 1 */
3599                         conf->prev.stride = conf->dev_sectors;
3600         }
3601         spin_lock_init(&conf->device_lock);
3602         INIT_LIST_HEAD(&conf->retry_list);
3603 
3604         spin_lock_init(&conf->resync_lock);
3605         init_waitqueue_head(&conf->wait_barrier);
3606 
3607         conf->thread = md_register_thread(raid10d, mddev, "raid10");
3608         if (!conf->thread)
3609                 goto out;
3610 
3611         conf->mddev = mddev;
3612         return conf;

3547行,设置raid10布局,这个函数代码很简单,但意义很重要,特别是在处理读写流程里要对这个布局十分清楚。看setup_geo函数:
3498 enum geo_type {geo_new, geo_old, geo_start};
3499 static int setup_geo(struct geom *geo,