diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 41e2509bf896..a307f87eb90e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -214,12 +214,7 @@ static inline mddev_t *mddev_get(mddev_t *mddev) | |||
214 | return mddev; | 214 | return mddev; |
215 | } | 215 | } |
216 | 216 | ||
217 | static void mddev_delayed_delete(struct work_struct *ws) | 217 | static void mddev_delayed_delete(struct work_struct *ws); |
218 | { | ||
219 | mddev_t *mddev = container_of(ws, mddev_t, del_work); | ||
220 | kobject_del(&mddev->kobj); | ||
221 | kobject_put(&mddev->kobj); | ||
222 | } | ||
223 | 218 | ||
224 | static void mddev_put(mddev_t *mddev) | 219 | static void mddev_put(mddev_t *mddev) |
225 | { | 220 | { |
@@ -474,7 +469,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | |||
474 | * causes ENOTSUPP, we allocate a spare bio... | 469 | * causes ENOTSUPP, we allocate a spare bio... |
475 | */ | 470 | */ |
476 | struct bio *bio = bio_alloc(GFP_NOIO, 1); | 471 | struct bio *bio = bio_alloc(GFP_NOIO, 1); |
477 | int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC); | 472 | int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG); |
478 | 473 | ||
479 | bio->bi_bdev = rdev->bdev; | 474 | bio->bi_bdev = rdev->bdev; |
480 | bio->bi_sector = sector; | 475 | bio->bi_sector = sector; |
@@ -531,7 +526,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size, | |||
531 | struct completion event; | 526 | struct completion event; |
532 | int ret; | 527 | int ret; |
533 | 528 | ||
534 | rw |= (1 << BIO_RW_SYNC); | 529 | rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); |
535 | 530 | ||
536 | bio->bi_bdev = bdev; | 531 | bio->bi_bdev = bdev; |
537 | bio->bi_sector = sector; | 532 | bio->bi_sector = sector; |
@@ -1481,6 +1476,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1481 | if (find_rdev_nr(mddev, rdev->desc_nr)) | 1476 | if (find_rdev_nr(mddev, rdev->desc_nr)) |
1482 | return -EBUSY; | 1477 | return -EBUSY; |
1483 | } | 1478 | } |
1479 | if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { | ||
1480 | printk(KERN_WARNING "md: %s: array is limited to %d devices\n", | ||
1481 | mdname(mddev), mddev->max_disks); | ||
1482 | return -EBUSY; | ||
1483 | } | ||
1484 | bdevname(rdev->bdev,b); | 1484 | bdevname(rdev->bdev,b); |
1485 | while ( (s=strchr(b, '/')) != NULL) | 1485 | while ( (s=strchr(b, '/')) != NULL) |
1486 | *s = '!'; | 1486 | *s = '!'; |
@@ -2441,6 +2441,15 @@ static void analyze_sbs(mddev_t * mddev) | |||
2441 | 2441 | ||
2442 | i = 0; | 2442 | i = 0; |
2443 | rdev_for_each(rdev, tmp, mddev) { | 2443 | rdev_for_each(rdev, tmp, mddev) { |
2444 | if (rdev->desc_nr >= mddev->max_disks || | ||
2445 | i > mddev->max_disks) { | ||
2446 | printk(KERN_WARNING | ||
2447 | "md: %s: %s: only %d devices permitted\n", | ||
2448 | mdname(mddev), bdevname(rdev->bdev, b), | ||
2449 | mddev->max_disks); | ||
2450 | kick_rdev_from_array(rdev); | ||
2451 | continue; | ||
2452 | } | ||
2444 | if (rdev != freshest) | 2453 | if (rdev != freshest) |
2445 | if (super_types[mddev->major_version]. | 2454 | if (super_types[mddev->major_version]. |
2446 | validate_super(mddev, rdev)) { | 2455 | validate_super(mddev, rdev)) { |
@@ -3528,6 +3537,21 @@ static struct kobj_type md_ktype = { | |||
3528 | 3537 | ||
3529 | int mdp_major = 0; | 3538 | int mdp_major = 0; |
3530 | 3539 | ||
3540 | static void mddev_delayed_delete(struct work_struct *ws) | ||
3541 | { | ||
3542 | mddev_t *mddev = container_of(ws, mddev_t, del_work); | ||
3543 | |||
3544 | if (mddev->private == &md_redundancy_group) { | ||
3545 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | ||
3546 | if (mddev->sysfs_action) | ||
3547 | sysfs_put(mddev->sysfs_action); | ||
3548 | mddev->sysfs_action = NULL; | ||
3549 | mddev->private = NULL; | ||
3550 | } | ||
3551 | kobject_del(&mddev->kobj); | ||
3552 | kobject_put(&mddev->kobj); | ||
3553 | } | ||
3554 | |||
3531 | static int md_alloc(dev_t dev, char *name) | 3555 | static int md_alloc(dev_t dev, char *name) |
3532 | { | 3556 | { |
3533 | static DEFINE_MUTEX(disks_mutex); | 3557 | static DEFINE_MUTEX(disks_mutex); |
@@ -4019,13 +4043,9 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
4019 | mddev->queue->merge_bvec_fn = NULL; | 4043 | mddev->queue->merge_bvec_fn = NULL; |
4020 | mddev->queue->unplug_fn = NULL; | 4044 | mddev->queue->unplug_fn = NULL; |
4021 | mddev->queue->backing_dev_info.congested_fn = NULL; | 4045 | mddev->queue->backing_dev_info.congested_fn = NULL; |
4022 | if (mddev->pers->sync_request) { | ||
4023 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | ||
4024 | if (mddev->sysfs_action) | ||
4025 | sysfs_put(mddev->sysfs_action); | ||
4026 | mddev->sysfs_action = NULL; | ||
4027 | } | ||
4028 | module_put(mddev->pers->owner); | 4046 | module_put(mddev->pers->owner); |
4047 | if (mddev->pers->sync_request) | ||
4048 | mddev->private = &md_redundancy_group; | ||
4029 | mddev->pers = NULL; | 4049 | mddev->pers = NULL; |
4030 | /* tell userspace to handle 'inactive' */ | 4050 | /* tell userspace to handle 'inactive' */ |
4031 | sysfs_notify_dirent(mddev->sysfs_state); | 4051 | sysfs_notify_dirent(mddev->sysfs_state); |
@@ -4614,13 +4634,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
4614 | * noticed in interrupt contexts ... | 4634 | * noticed in interrupt contexts ... |
4615 | */ | 4635 | */ |
4616 | 4636 | ||
4617 | if (rdev->desc_nr == mddev->max_disks) { | ||
4618 | printk(KERN_WARNING "%s: can not hot-add to full array!\n", | ||
4619 | mdname(mddev)); | ||
4620 | err = -EBUSY; | ||
4621 | goto abort_unbind_export; | ||
4622 | } | ||
4623 | |||
4624 | rdev->raid_disk = -1; | 4637 | rdev->raid_disk = -1; |
4625 | 4638 | ||
4626 | md_update_sb(mddev, 1); | 4639 | md_update_sb(mddev, 1); |
@@ -4634,9 +4647,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
4634 | md_new_event(mddev); | 4647 | md_new_event(mddev); |
4635 | return 0; | 4648 | return 0; |
4636 | 4649 | ||
4637 | abort_unbind_export: | ||
4638 | unbind_rdev_from_array(rdev); | ||
4639 | |||
4640 | abort_export: | 4650 | abort_export: |
4641 | export_rdev(rdev); | 4651 | export_rdev(rdev); |
4642 | return err; | 4652 | return err; |