diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/linear.c | 2 | ||||
-rw-r--r-- | drivers/md/md.c | 58 | ||||
-rw-r--r-- | drivers/md/raid5.c | 19 |
3 files changed, 64 insertions, 15 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index c625ddb8833d..d5ecd2d53046 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -188,7 +188,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
188 | for (i=0; i < cnt-1 ; i++) { | 188 | for (i=0; i < cnt-1 ; i++) { |
189 | sector_t sz = 0; | 189 | sector_t sz = 0; |
190 | int j; | 190 | int j; |
191 | for (j=i; i<cnt-1 && sz < min_spacing ; j++) | 191 | for (j = i; j < cnt - 1 && sz < min_spacing; j++) |
192 | sz += conf->disks[j].size; | 192 | sz += conf->disks[j].size; |
193 | if (sz >= min_spacing && sz < conf->hash_spacing) | 193 | if (sz >= min_spacing && sz < conf->hash_spacing) |
194 | conf->hash_spacing = sz; | 194 | conf->hash_spacing = sz; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 6c06e825cff5..509171ca7fa8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1318,6 +1318,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1318 | char b[BDEVNAME_SIZE]; | 1318 | char b[BDEVNAME_SIZE]; |
1319 | struct kobject *ko; | 1319 | struct kobject *ko; |
1320 | char *s; | 1320 | char *s; |
1321 | int err; | ||
1321 | 1322 | ||
1322 | if (rdev->mddev) { | 1323 | if (rdev->mddev) { |
1323 | MD_BUG(); | 1324 | MD_BUG(); |
@@ -1352,20 +1353,35 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1352 | while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL) | 1353 | while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL) |
1353 | *s = '!'; | 1354 | *s = '!'; |
1354 | 1355 | ||
1355 | list_add(&rdev->same_set, &mddev->disks); | ||
1356 | rdev->mddev = mddev; | 1356 | rdev->mddev = mddev; |
1357 | printk(KERN_INFO "md: bind<%s>\n", b); | 1357 | printk(KERN_INFO "md: bind<%s>\n", b); |
1358 | 1358 | ||
1359 | rdev->kobj.parent = &mddev->kobj; | 1359 | rdev->kobj.parent = &mddev->kobj; |
1360 | kobject_add(&rdev->kobj); | 1360 | if ((err = kobject_add(&rdev->kobj))) |
1361 | goto fail; | ||
1361 | 1362 | ||
1362 | if (rdev->bdev->bd_part) | 1363 | if (rdev->bdev->bd_part) |
1363 | ko = &rdev->bdev->bd_part->kobj; | 1364 | ko = &rdev->bdev->bd_part->kobj; |
1364 | else | 1365 | else |
1365 | ko = &rdev->bdev->bd_disk->kobj; | 1366 | ko = &rdev->bdev->bd_disk->kobj; |
1366 | sysfs_create_link(&rdev->kobj, ko, "block"); | 1367 | if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) { |
1368 | kobject_del(&rdev->kobj); | ||
1369 | goto fail; | ||
1370 | } | ||
1371 | list_add(&rdev->same_set, &mddev->disks); | ||
1367 | bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk); | 1372 | bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk); |
1368 | return 0; | 1373 | return 0; |
1374 | |||
1375 | fail: | ||
1376 | printk(KERN_WARNING "md: failed to register dev-%s for %s\n", | ||
1377 | b, mdname(mddev)); | ||
1378 | return err; | ||
1379 | } | ||
1380 | |||
1381 | static void delayed_delete(struct work_struct *ws) | ||
1382 | { | ||
1383 | mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work); | ||
1384 | kobject_del(&rdev->kobj); | ||
1369 | } | 1385 | } |
1370 | 1386 | ||
1371 | static void unbind_rdev_from_array(mdk_rdev_t * rdev) | 1387 | static void unbind_rdev_from_array(mdk_rdev_t * rdev) |
@@ -1380,7 +1396,12 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) | |||
1380 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); | 1396 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); |
1381 | rdev->mddev = NULL; | 1397 | rdev->mddev = NULL; |
1382 | sysfs_remove_link(&rdev->kobj, "block"); | 1398 | sysfs_remove_link(&rdev->kobj, "block"); |
1383 | kobject_del(&rdev->kobj); | 1399 | |
1400 | /* We need to delay this, otherwise we can deadlock when | ||
1401 | * writing to 'remove' to "dev/state" | ||
1402 | */ | ||
1403 | INIT_WORK(&rdev->del_work, delayed_delete); | ||
1404 | schedule_work(&rdev->del_work); | ||
1384 | } | 1405 | } |
1385 | 1406 | ||
1386 | /* | 1407 | /* |
@@ -2966,7 +2987,9 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
2966 | mddev->kobj.k_name = NULL; | 2987 | mddev->kobj.k_name = NULL; |
2967 | snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); | 2988 | snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); |
2968 | mddev->kobj.ktype = &md_ktype; | 2989 | mddev->kobj.ktype = &md_ktype; |
2969 | kobject_register(&mddev->kobj); | 2990 | if (kobject_register(&mddev->kobj)) |
2991 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", | ||
2992 | disk->disk_name); | ||
2970 | return NULL; | 2993 | return NULL; |
2971 | } | 2994 | } |
2972 | 2995 | ||
@@ -3144,9 +3167,12 @@ static int do_md_run(mddev_t * mddev) | |||
3144 | bitmap_destroy(mddev); | 3167 | bitmap_destroy(mddev); |
3145 | return err; | 3168 | return err; |
3146 | } | 3169 | } |
3147 | if (mddev->pers->sync_request) | 3170 | if (mddev->pers->sync_request) { |
3148 | sysfs_create_group(&mddev->kobj, &md_redundancy_group); | 3171 | if (sysfs_create_group(&mddev->kobj, &md_redundancy_group)) |
3149 | else if (mddev->ro == 2) /* auto-readonly not meaningful */ | 3172 | printk(KERN_WARNING |
3173 | "md: cannot register extra attributes for %s\n", | ||
3174 | mdname(mddev)); | ||
3175 | } else if (mddev->ro == 2) /* auto-readonly not meaningful */ | ||
3150 | mddev->ro = 0; | 3176 | mddev->ro = 0; |
3151 | 3177 | ||
3152 | atomic_set(&mddev->writes_pending,0); | 3178 | atomic_set(&mddev->writes_pending,0); |
@@ -3160,7 +3186,9 @@ static int do_md_run(mddev_t * mddev) | |||
3160 | if (rdev->raid_disk >= 0) { | 3186 | if (rdev->raid_disk >= 0) { |
3161 | char nm[20]; | 3187 | char nm[20]; |
3162 | sprintf(nm, "rd%d", rdev->raid_disk); | 3188 | sprintf(nm, "rd%d", rdev->raid_disk); |
3163 | sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); | 3189 | if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm)) |
3190 | printk("md: cannot register %s for %s\n", | ||
3191 | nm, mdname(mddev)); | ||
3164 | } | 3192 | } |
3165 | 3193 | ||
3166 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3194 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
@@ -3325,6 +3353,7 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3325 | mddev->queue->merge_bvec_fn = NULL; | 3353 | mddev->queue->merge_bvec_fn = NULL; |
3326 | mddev->queue->unplug_fn = NULL; | 3354 | mddev->queue->unplug_fn = NULL; |
3327 | mddev->queue->issue_flush_fn = NULL; | 3355 | mddev->queue->issue_flush_fn = NULL; |
3356 | mddev->queue->backing_dev_info.congested_fn = NULL; | ||
3328 | if (mddev->pers->sync_request) | 3357 | if (mddev->pers->sync_request) |
3329 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | 3358 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); |
3330 | 3359 | ||
@@ -3371,6 +3400,9 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3371 | sysfs_remove_link(&mddev->kobj, nm); | 3400 | sysfs_remove_link(&mddev->kobj, nm); |
3372 | } | 3401 | } |
3373 | 3402 | ||
3403 | /* make sure all delayed_delete calls have finished */ | ||
3404 | flush_scheduled_work(); | ||
3405 | |||
3374 | export_array(mddev); | 3406 | export_array(mddev); |
3375 | 3407 | ||
3376 | mddev->array_size = 0; | 3408 | mddev->array_size = 0; |
@@ -5385,8 +5417,12 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5385 | if (mddev->pers->hot_add_disk(mddev,rdev)) { | 5417 | if (mddev->pers->hot_add_disk(mddev,rdev)) { |
5386 | char nm[20]; | 5418 | char nm[20]; |
5387 | sprintf(nm, "rd%d", rdev->raid_disk); | 5419 | sprintf(nm, "rd%d", rdev->raid_disk); |
5388 | sysfs_create_link(&mddev->kobj, | 5420 | if (sysfs_create_link(&mddev->kobj, |
5389 | &rdev->kobj, nm); | 5421 | &rdev->kobj, nm)) |
5422 | printk(KERN_WARNING | ||
5423 | "md: cannot register " | ||
5424 | "%s for %s\n", | ||
5425 | nm, mdname(mddev)); | ||
5390 | spares++; | 5426 | spares++; |
5391 | md_new_event(mddev); | 5427 | md_new_event(mddev); |
5392 | } else | 5428 | } else |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 54a1ad5eef42..8d59914f2057 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3642,12 +3642,15 @@ static int run(mddev_t *mddev) | |||
3642 | } | 3642 | } |
3643 | 3643 | ||
3644 | /* Ok, everything is just fine now */ | 3644 | /* Ok, everything is just fine now */ |
3645 | sysfs_create_group(&mddev->kobj, &raid5_attrs_group); | 3645 | if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) |
3646 | printk(KERN_WARNING | ||
3647 | "raid5: failed to create sysfs attributes for %s\n", | ||
3648 | mdname(mddev)); | ||
3646 | 3649 | ||
3647 | mddev->queue->unplug_fn = raid5_unplug_device; | 3650 | mddev->queue->unplug_fn = raid5_unplug_device; |
3648 | mddev->queue->issue_flush_fn = raid5_issue_flush; | 3651 | mddev->queue->issue_flush_fn = raid5_issue_flush; |
3649 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; | ||
3650 | mddev->queue->backing_dev_info.congested_data = mddev; | 3652 | mddev->queue->backing_dev_info.congested_data = mddev; |
3653 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; | ||
3651 | 3654 | ||
3652 | mddev->array_size = mddev->size * (conf->previous_raid_disks - | 3655 | mddev->array_size = mddev->size * (conf->previous_raid_disks - |
3653 | conf->max_degraded); | 3656 | conf->max_degraded); |
@@ -3678,6 +3681,7 @@ static int stop(mddev_t *mddev) | |||
3678 | mddev->thread = NULL; | 3681 | mddev->thread = NULL; |
3679 | shrink_stripes(conf); | 3682 | shrink_stripes(conf); |
3680 | kfree(conf->stripe_hashtbl); | 3683 | kfree(conf->stripe_hashtbl); |
3684 | mddev->queue->backing_dev_info.congested_fn = NULL; | ||
3681 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 3685 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
3682 | sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); | 3686 | sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); |
3683 | kfree(conf->disks); | 3687 | kfree(conf->disks); |
@@ -3950,7 +3954,12 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
3950 | added_devices++; | 3954 | added_devices++; |
3951 | rdev->recovery_offset = 0; | 3955 | rdev->recovery_offset = 0; |
3952 | sprintf(nm, "rd%d", rdev->raid_disk); | 3956 | sprintf(nm, "rd%d", rdev->raid_disk); |
3953 | sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); | 3957 | if (sysfs_create_link(&mddev->kobj, |
3958 | &rdev->kobj, nm)) | ||
3959 | printk(KERN_WARNING | ||
3960 | "raid5: failed to create " | ||
3961 | " link %s for %s\n", | ||
3962 | nm, mdname(mddev)); | ||
3954 | } else | 3963 | } else |
3955 | break; | 3964 | break; |
3956 | } | 3965 | } |
@@ -4104,6 +4113,10 @@ static struct mdk_personality raid4_personality = | |||
4104 | .spare_active = raid5_spare_active, | 4113 | .spare_active = raid5_spare_active, |
4105 | .sync_request = sync_request, | 4114 | .sync_request = sync_request, |
4106 | .resize = raid5_resize, | 4115 | .resize = raid5_resize, |
4116 | #ifdef CONFIG_MD_RAID5_RESHAPE | ||
4117 | .check_reshape = raid5_check_reshape, | ||
4118 | .start_reshape = raid5_start_reshape, | ||
4119 | #endif | ||
4107 | .quiesce = raid5_quiesce, | 4120 | .quiesce = raid5_quiesce, |
4108 | }; | 4121 | }; |
4109 | 4122 | ||