diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/md/dm.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 9b641b38b857..8001fe9e3434 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -433,7 +433,6 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode) | |||
| 433 | 433 | ||
| 434 | dm_get(md); | 434 | dm_get(md); |
| 435 | atomic_inc(&md->open_count); | 435 | atomic_inc(&md->open_count); |
| 436 | |||
| 437 | out: | 436 | out: |
| 438 | spin_unlock(&_minor_lock); | 437 | spin_unlock(&_minor_lock); |
| 439 | 438 | ||
| @@ -442,16 +441,20 @@ out: | |||
| 442 | 441 | ||
| 443 | static void dm_blk_close(struct gendisk *disk, fmode_t mode) | 442 | static void dm_blk_close(struct gendisk *disk, fmode_t mode) |
| 444 | { | 443 | { |
| 445 | struct mapped_device *md = disk->private_data; | 444 | struct mapped_device *md; |
| 446 | 445 | ||
| 447 | spin_lock(&_minor_lock); | 446 | spin_lock(&_minor_lock); |
| 448 | 447 | ||
| 448 | md = disk->private_data; | ||
| 449 | if (WARN_ON(!md)) | ||
| 450 | goto out; | ||
| 451 | |||
| 449 | if (atomic_dec_and_test(&md->open_count) && | 452 | if (atomic_dec_and_test(&md->open_count) && |
| 450 | (test_bit(DMF_DEFERRED_REMOVE, &md->flags))) | 453 | (test_bit(DMF_DEFERRED_REMOVE, &md->flags))) |
| 451 | queue_work(deferred_remove_workqueue, &deferred_remove_work); | 454 | queue_work(deferred_remove_workqueue, &deferred_remove_work); |
| 452 | 455 | ||
| 453 | dm_put(md); | 456 | dm_put(md); |
| 454 | 457 | out: | |
| 455 | spin_unlock(&_minor_lock); | 458 | spin_unlock(&_minor_lock); |
| 456 | } | 459 | } |
| 457 | 460 | ||
| @@ -2241,7 +2244,6 @@ static void free_dev(struct mapped_device *md) | |||
| 2241 | int minor = MINOR(disk_devt(md->disk)); | 2244 | int minor = MINOR(disk_devt(md->disk)); |
| 2242 | 2245 | ||
| 2243 | unlock_fs(md); | 2246 | unlock_fs(md); |
| 2244 | bdput(md->bdev); | ||
| 2245 | destroy_workqueue(md->wq); | 2247 | destroy_workqueue(md->wq); |
| 2246 | 2248 | ||
| 2247 | if (md->kworker_task) | 2249 | if (md->kworker_task) |
| @@ -2252,19 +2254,22 @@ static void free_dev(struct mapped_device *md) | |||
| 2252 | mempool_destroy(md->rq_pool); | 2254 | mempool_destroy(md->rq_pool); |
| 2253 | if (md->bs) | 2255 | if (md->bs) |
| 2254 | bioset_free(md->bs); | 2256 | bioset_free(md->bs); |
| 2255 | blk_integrity_unregister(md->disk); | 2257 | |
| 2256 | del_gendisk(md->disk); | ||
| 2257 | cleanup_srcu_struct(&md->io_barrier); | 2258 | cleanup_srcu_struct(&md->io_barrier); |
| 2258 | free_table_devices(&md->table_devices); | 2259 | free_table_devices(&md->table_devices); |
| 2259 | free_minor(minor); | 2260 | dm_stats_cleanup(&md->stats); |
| 2260 | 2261 | ||
| 2261 | spin_lock(&_minor_lock); | 2262 | spin_lock(&_minor_lock); |
| 2262 | md->disk->private_data = NULL; | 2263 | md->disk->private_data = NULL; |
| 2263 | spin_unlock(&_minor_lock); | 2264 | spin_unlock(&_minor_lock); |
| 2264 | 2265 | if (blk_get_integrity(md->disk)) | |
| 2266 | blk_integrity_unregister(md->disk); | ||
| 2267 | del_gendisk(md->disk); | ||
| 2265 | put_disk(md->disk); | 2268 | put_disk(md->disk); |
| 2266 | blk_cleanup_queue(md->queue); | 2269 | blk_cleanup_queue(md->queue); |
| 2267 | dm_stats_cleanup(&md->stats); | 2270 | bdput(md->bdev); |
| 2271 | free_minor(minor); | ||
| 2272 | |||
| 2268 | module_put(THIS_MODULE); | 2273 | module_put(THIS_MODULE); |
| 2269 | kfree(md); | 2274 | kfree(md); |
| 2270 | } | 2275 | } |
| @@ -2642,8 +2647,9 @@ static void __dm_destroy(struct mapped_device *md, bool wait) | |||
| 2642 | 2647 | ||
| 2643 | might_sleep(); | 2648 | might_sleep(); |
| 2644 | 2649 | ||
| 2645 | spin_lock(&_minor_lock); | ||
| 2646 | map = dm_get_live_table(md, &srcu_idx); | 2650 | map = dm_get_live_table(md, &srcu_idx); |
| 2651 | |||
| 2652 | spin_lock(&_minor_lock); | ||
| 2647 | idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); | 2653 | idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); |
| 2648 | set_bit(DMF_FREEING, &md->flags); | 2654 | set_bit(DMF_FREEING, &md->flags); |
| 2649 | spin_unlock(&_minor_lock); | 2655 | spin_unlock(&_minor_lock); |
