linux内核md源代码解读 六 介绍raid10阵列的运行

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;

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索struct
, conf
, goto
, raid
, 10
, linux bio raid
, out
geo
raid磁盘阵列、raid阵列、raid磁盘阵列教程、raid阵列卡、磁盘阵列raid5,以便于您获取更多的相关知识。

时间: 2024-12-26 10:53:10

linux内核md源代码解读 六 介绍raid10阵列的运行的相关文章

linux内核md源代码解读 五 介绍raidd5阵列的运行

如果看懂了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

linux内核md源代码解读 七 阵列同步一 :介绍阵列同步

阵列同步在md_do_sync,那么入口在哪里呢?就是说阵列同步触发点在哪里呢?听说过md_check_recovery吧,但这还不是同步的入口点.那raid5d函数是入口点吧?如果要认真分析起来还不算是. 真正的同步入口点在do_md_run函数,就是在运行阵列run函数之后,有这么一行: 5171         md_wakeup_thread(mddev->thread); 是这一行把raid5d唤醒的,raid5d函数如下: 4823 static void raid5d(struct

linux内核md源代码解读 二 md模块初始化

在编译完成linux内核源代码的时候,drivers/md目录下会生成多个ko文件,那么这些内核模块哪一个先加载,哪一个后加载的呢?例如md-mod.ko, raid5.ko, raid10.ko,这些模块是一起加载的呢,还是有先后顺序呢?如果熟悉linux内核编程的话,知道有一个request_module函数,这个函数用于请求加载一个模块,但这个函数并不能说明一个模块对另一个模块的依赖关系.准确的信息还是来自于Kconfig,这里只抽取Kconfig中相关的部分: config BLK_DE

linux内核md源代码解读 一

最近花了一段时间认真地学习了一下md代码,并且在原代码的基础上开发了一系列的新功能,这些新功能让md更完善.更适合于企业大容量存储,通过增加阵列缓存和bitmap优化大大提升了存储速度,提高了数据的可靠性,在任何掉电的情况下保证数据一致性,超级块异常情况下完全不影响阵列使用,完全控制了踢盘问题,简化了用户操作.简单地概括一下,就是让存储不再有门槛.说了这么多,其实想表达的意思就是md的学习之路并非十分顺利,特此写此博文与所有兄弟姐妹们共享一下我的学习经验,如果您看完之后能有所收获,那就不枉费我下

linux内核md源代码解读 八 阵列同步二:同步过程

在上一小节里讲到启动同步线程: 7824 mddev->sync_thread = md_register_thread(md_do_sync, 7825 mddev, 7826 "resync"); md_register_thread函数如下: 6697 struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev *mddev, 6698 const char *name) 6

linux内核md源代码解读 三 阵列创建的过程

这一节我们阅读阵列的创建过程. 按照常理出牌,我们到ioctl中找阵列创建命令,md对应的ioctl函数是md_ioctl,当找对应的cmd命令字时,却完全没有类似CREATE_ARRAY的命令,那么就说明md设备并不是通过ioctl函数来创建的.其实如果我们仔细阅读一下md_ioctl函数的原型就会发现其实创建md设备根本就不在这个地方,函数原型如下: 6303 static int md_ioctl(struct block_device *bdev, fmode_t mode, 6304

linux内核md源代码解读 十三 raid5重试读

上节我们讲到条块内读失败,在回调函数raid5_align_endio中将请求加入阵列重试链表,在唤醒raid5d线程之后,raid5d线程将该请求调用retry_aligned_read函数进行重试读: 4539static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) 4540{ 4541 /* We may not be able to submit a whole bio at once as ther

linux内核md源代码解读 十二 raid读写

我们都知道,对一个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一直保持着稳健的增长,但丝

linux内核md源代码解读 十一 raid5d

正是有了上一篇的读写基础,我们才开始看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 * Du