加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

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

发布时间:2016-10-29 18:57:24 所属栏目:Linux 来源:站长网
导读:副标题#e# 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 in

3585行,计算磁盘实际用于阵列条带的扇区数和阵列存放远拷贝的跨度大小。假设我们用整个磁盘空间创建阵列raid10,但是由于每个磁盘空间大小有差别,阵列会按最小的磁盘空间来创建,这里实际用于阵列的磁盘空间将小于磁盘空间。再次,如果磁盘空间不是整数倍条块大小,这时多余部分还会被空闲出来。同样地,如果raid10远拷贝为2,这时磁盘条块数不能整除3,那么又有一部分磁盘空间空闲出来。正是因为如此,conf->dev_sectors会小于等于mddev->dev_sectors。理解了这些,那么看calc_sectors函数就容易了:

3468 static void calc_sectors(struct r10conf *conf, sector_t size)  
3469 {  
3470         /* Calculate the number of sectors-per-device that will 
3471          * actually be used, and set conf->dev_sectors and 
3472          * conf->stride 
3473          */
3474   
3475         size = size >> conf->geo.chunk_shift;  
3476         sector_div(size, conf->geo.far_copies);  
3477         size = size * conf->geo.raid_disks;  
3478         sector_div(size, conf->geo.near_copies);  
3479         /* 'size' is now the number of chunks in the array */
3480         /* calculate "used chunks per device" */
3481         size = size * conf->copies;  
3482   
3483         /* We need to round up when dividing by raid_disks to 
3484          * get the stride size. 
3485          */
3486         size = DIV_ROUND_UP_SECTOR_T(size, conf->geo.raid_disks);  
3487   
3488         conf->dev_sectors = size << conf->geo.chunk_shift;  
3489   
3490         if (conf->geo.far_offset)  
3491                 conf->geo.stride = 1 << conf->geo.chunk_shift;  
3492         else {  
3493                 sector_div(size, conf->geo.far_copies);  
3494                 conf->geo.stride = size << conf->geo.chunk_shift;  
3495         }  
3496 }

3470行,计算每个磁盘实际使用扇区数,并设置conf->dev_sectors和conf->stride。stride是什么意思呢?大步,跨幅。就是同一磁盘上每个far_copies之间的距离,这里有两个可能,一是远拷贝数据间隔存放,一是远拷贝数据相邻存放。conf->geo.far_offset不为0时表示相邻存放,为0时表示间隔存放,间隔多远呢?就由conf->geo.stride决定。3475行,函数传入参数size为磁盘空间大小,这里转换为条块数。3476行,除以远拷贝数,转换为单份数据空间大小。3477-3478行,乘以数据盘数,再除以近拷贝数,转换为总数据空间大小(没有拷贝)。3481行,乘以拷贝数,可用阵列空间大小。3486行,除以数据盘数,每个磁盘用于阵列的实际使用空间大小。3488行,乘以条块大小,单位由条块数转换为扇区数。

这里为什么又乘又除的呢?这就好比有一张长方形的纸,我们要用这张纸分出四个最大的正方形出来,那么就选个角按45度折起来,然后把之外的部分裁掉。3490行,远拷贝是相邻存放的,那么跨幅就是一个条块。

3493行,远拷贝是间隔存放的,那么跨幅就是磁盘实际使用空间大小size除以远拷贝数。

再次返回到setup_conf函数中。3586行,没有reshape操作,reshape等于MaxSector。3601-3611行,conf初始化。3607行,创建raid10d主线程。这样setup_conf函数就结束了,run函数剩余部分都是按步就班。小结一下,各种级别阵列运行函数建立与磁盘之间的关联,建立数据流通道,申请数据流所需要的资源。不同的是,由于阵列级别差异,阵列与磁盘之间关联不一样,申请资源也不一样。阵列已经运行起来了,,那么第一件事情就是同步了。下一节开始介绍阵列同步。

出处:http://blog.csdn.net/liumangxiong

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读