aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c58
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
217static void mddev_delayed_delete(struct work_struct *ws) 217static 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
224static void mddev_put(mddev_t *mddev) 219static 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
3529int mdp_major = 0; 3538int mdp_major = 0;
3530 3539
3540static 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
3531static int md_alloc(dev_t dev, char *name) 3555static 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
4637abort_unbind_export:
4638 unbind_rdev_from_array(rdev);
4639
4640abort_export: 4650abort_export:
4641 export_rdev(rdev); 4651 export_rdev(rdev);
4642 return err; 4652 return err;