diff options
| -rw-r--r-- | drivers/md/md.c | 9 | ||||
| -rw-r--r-- | include/linux/raid/md_k.h | 3 |
2 files changed, 8 insertions, 4 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4bfbc1982cda..450f30b6edf9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -273,6 +273,7 @@ static mddev_t * mddev_find(dev_t unit) | |||
| 273 | INIT_LIST_HEAD(&new->all_mddevs); | 273 | INIT_LIST_HEAD(&new->all_mddevs); |
| 274 | init_timer(&new->safemode_timer); | 274 | init_timer(&new->safemode_timer); |
| 275 | atomic_set(&new->active, 1); | 275 | atomic_set(&new->active, 1); |
| 276 | atomic_set(&new->openers, 0); | ||
| 276 | spin_lock_init(&new->write_lock); | 277 | spin_lock_init(&new->write_lock); |
| 277 | init_waitqueue_head(&new->sb_wait); | 278 | init_waitqueue_head(&new->sb_wait); |
| 278 | init_waitqueue_head(&new->recovery_wait); | 279 | init_waitqueue_head(&new->recovery_wait); |
| @@ -2695,14 +2696,14 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
| 2695 | break; | 2696 | break; |
| 2696 | case clear: | 2697 | case clear: |
| 2697 | /* stopping an active array */ | 2698 | /* stopping an active array */ |
| 2698 | if (atomic_read(&mddev->active) > 1) | 2699 | if (atomic_read(&mddev->openers) > 0) |
| 2699 | return -EBUSY; | 2700 | return -EBUSY; |
| 2700 | err = do_md_stop(mddev, 0, 0); | 2701 | err = do_md_stop(mddev, 0, 0); |
| 2701 | break; | 2702 | break; |
| 2702 | case inactive: | 2703 | case inactive: |
| 2703 | /* stopping an active array */ | 2704 | /* stopping an active array */ |
| 2704 | if (mddev->pers) { | 2705 | if (mddev->pers) { |
| 2705 | if (atomic_read(&mddev->active) > 1) | 2706 | if (atomic_read(&mddev->openers) > 0) |
| 2706 | return -EBUSY; | 2707 | return -EBUSY; |
| 2707 | err = do_md_stop(mddev, 2, 0); | 2708 | err = do_md_stop(mddev, 2, 0); |
| 2708 | } else | 2709 | } else |
| @@ -3816,7 +3817,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3816 | int err = 0; | 3817 | int err = 0; |
| 3817 | struct gendisk *disk = mddev->gendisk; | 3818 | struct gendisk *disk = mddev->gendisk; |
| 3818 | 3819 | ||
| 3819 | if (atomic_read(&mddev->active) > 1 + is_open) { | 3820 | if (atomic_read(&mddev->openers) > is_open) { |
| 3820 | printk("md: %s still in use.\n",mdname(mddev)); | 3821 | printk("md: %s still in use.\n",mdname(mddev)); |
| 3821 | return -EBUSY; | 3822 | return -EBUSY; |
| 3822 | } | 3823 | } |
| @@ -5014,6 +5015,7 @@ static int md_open(struct inode *inode, struct file *file) | |||
| 5014 | 5015 | ||
| 5015 | err = 0; | 5016 | err = 0; |
| 5016 | mddev_get(mddev); | 5017 | mddev_get(mddev); |
| 5018 | atomic_inc(&mddev->openers); | ||
| 5017 | mddev_unlock(mddev); | 5019 | mddev_unlock(mddev); |
| 5018 | 5020 | ||
| 5019 | check_disk_change(inode->i_bdev); | 5021 | check_disk_change(inode->i_bdev); |
| @@ -5026,6 +5028,7 @@ static int md_release(struct inode *inode, struct file * file) | |||
| 5026 | mddev_t *mddev = inode->i_bdev->bd_disk->private_data; | 5028 | mddev_t *mddev = inode->i_bdev->bd_disk->private_data; |
| 5027 | 5029 | ||
| 5028 | BUG_ON(!mddev); | 5030 | BUG_ON(!mddev); |
| 5031 | atomic_dec(&mddev->openers); | ||
| 5029 | mddev_put(mddev); | 5032 | mddev_put(mddev); |
| 5030 | 5033 | ||
| 5031 | return 0; | 5034 | return 0; |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 6f72b47ae41c..4bef4791d80d 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
| @@ -215,7 +215,8 @@ struct mddev_s | |||
| 215 | 215 | ||
| 216 | int in_sync; /* know to not need resync */ | 216 | int in_sync; /* know to not need resync */ |
| 217 | struct mutex reconfig_mutex; | 217 | struct mutex reconfig_mutex; |
| 218 | atomic_t active; | 218 | atomic_t active; /* general refcount */ |
| 219 | atomic_t openers; /* number of active opens */ | ||
| 219 | 220 | ||
| 220 | int changed; /* true if we might need to reread partition info */ | 221 | int changed; /* true if we might need to reread partition info */ |
| 221 | int degraded; /* whether md should consider | 222 | int degraded; /* whether md should consider |
