linux内核md源代码解读 五 先容raidd5阵列的运行
发布时间:2016-11-12 16:53:46 所属栏目:Linux 来源:站长网
导读:副标题#e# 如果看懂了raid1阵列的run函数,那么看raid5阵列run就非常轻松了,因为两者要做的事情都是大同小异。 raid5的run函数很长,但很大一部分跟创建运行是没有关系的,特别是有一段跟reshape相关的,大多数系统都不关注该功能,因此可以直接跳过。经过
|
副标题[/!--empirenews.page--]
如果看懂了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 supportedn",
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 %dn",
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 else
5189 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 %dn",
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 else
5241 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 buffersn",
5255 mdname(mddev), memory);
5256 goto abort;
5257 } else
5258 printk(KERN_INFO "md/raid:%s: allocated %dkBn",
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;
(编辑:应用网_阳江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐

