|
@@ -2166,6 +2166,40 @@ static void dm_init_old_md_queue(struct mapped_device *md)
|
|
|
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
|
|
|
}
|
|
|
|
|
|
+static void cleanup_mapped_device(struct mapped_device *md)
|
|
|
+{
|
|
|
+ cleanup_srcu_struct(&md->io_barrier);
|
|
|
+
|
|
|
+ if (md->wq)
|
|
|
+ destroy_workqueue(md->wq);
|
|
|
+ if (md->kworker_task)
|
|
|
+ kthread_stop(md->kworker_task);
|
|
|
+ if (md->io_pool)
|
|
|
+ mempool_destroy(md->io_pool);
|
|
|
+ if (md->rq_pool)
|
|
|
+ mempool_destroy(md->rq_pool);
|
|
|
+ if (md->bs)
|
|
|
+ bioset_free(md->bs);
|
|
|
+
|
|
|
+ if (md->disk) {
|
|
|
+ spin_lock(&_minor_lock);
|
|
|
+ md->disk->private_data = NULL;
|
|
|
+ spin_unlock(&_minor_lock);
|
|
|
+ if (blk_get_integrity(md->disk))
|
|
|
+ blk_integrity_unregister(md->disk);
|
|
|
+ del_gendisk(md->disk);
|
|
|
+ put_disk(md->disk);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (md->queue)
|
|
|
+ blk_cleanup_queue(md->queue);
|
|
|
+
|
|
|
+ if (md->bdev) {
|
|
|
+ bdput(md->bdev);
|
|
|
+ md->bdev = NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Allocate and initialise a blank device with a given minor.
|
|
|
*/
|
|
@@ -2211,13 +2245,13 @@ static struct mapped_device *alloc_dev(int minor)
|
|
|
|
|
|
md->queue = blk_alloc_queue(GFP_KERNEL);
|
|
|
if (!md->queue)
|
|
|
- goto bad_queue;
|
|
|
+ goto bad;
|
|
|
|
|
|
dm_init_md_queue(md);
|
|
|
|
|
|
md->disk = alloc_disk(1);
|
|
|
if (!md->disk)
|
|
|
- goto bad_disk;
|
|
|
+ goto bad;
|
|
|
|
|
|
atomic_set(&md->pending[0], 0);
|
|
|
atomic_set(&md->pending[1], 0);
|
|
@@ -2238,11 +2272,11 @@ static struct mapped_device *alloc_dev(int minor)
|
|
|
|
|
|
md->wq = alloc_workqueue("kdmflush", WQ_MEM_RECLAIM, 0);
|
|
|
if (!md->wq)
|
|
|
- goto bad_thread;
|
|
|
+ goto bad;
|
|
|
|
|
|
md->bdev = bdget_disk(md->disk, 0);
|
|
|
if (!md->bdev)
|
|
|
- goto bad_bdev;
|
|
|
+ goto bad;
|
|
|
|
|
|
bio_init(&md->flush_bio);
|
|
|
md->flush_bio.bi_bdev = md->bdev;
|
|
@@ -2259,15 +2293,8 @@ static struct mapped_device *alloc_dev(int minor)
|
|
|
|
|
|
return md;
|
|
|
|
|
|
-bad_bdev:
|
|
|
- destroy_workqueue(md->wq);
|
|
|
-bad_thread:
|
|
|
- del_gendisk(md->disk);
|
|
|
- put_disk(md->disk);
|
|
|
-bad_disk:
|
|
|
- blk_cleanup_queue(md->queue);
|
|
|
-bad_queue:
|
|
|
- cleanup_srcu_struct(&md->io_barrier);
|
|
|
+bad:
|
|
|
+ cleanup_mapped_device(md);
|
|
|
bad_io_barrier:
|
|
|
free_minor(minor);
|
|
|
bad_minor:
|
|
@@ -2284,32 +2311,13 @@ static void free_dev(struct mapped_device *md)
|
|
|
int minor = MINOR(disk_devt(md->disk));
|
|
|
|
|
|
unlock_fs(md);
|
|
|
- destroy_workqueue(md->wq);
|
|
|
|
|
|
- if (md->kworker_task)
|
|
|
- kthread_stop(md->kworker_task);
|
|
|
- if (md->io_pool)
|
|
|
- mempool_destroy(md->io_pool);
|
|
|
- if (md->rq_pool)
|
|
|
- mempool_destroy(md->rq_pool);
|
|
|
- if (md->bs)
|
|
|
- bioset_free(md->bs);
|
|
|
+ cleanup_mapped_device(md);
|
|
|
+ if (md->use_blk_mq)
|
|
|
+ blk_mq_free_tag_set(&md->tag_set);
|
|
|
|
|
|
- cleanup_srcu_struct(&md->io_barrier);
|
|
|
free_table_devices(&md->table_devices);
|
|
|
dm_stats_cleanup(&md->stats);
|
|
|
-
|
|
|
- spin_lock(&_minor_lock);
|
|
|
- md->disk->private_data = NULL;
|
|
|
- spin_unlock(&_minor_lock);
|
|
|
- if (blk_get_integrity(md->disk))
|
|
|
- blk_integrity_unregister(md->disk);
|
|
|
- del_gendisk(md->disk);
|
|
|
- put_disk(md->disk);
|
|
|
- blk_cleanup_queue(md->queue);
|
|
|
- if (md->use_blk_mq)
|
|
|
- blk_mq_free_tag_set(&md->tag_set);
|
|
|
- bdput(md->bdev);
|
|
|
free_minor(minor);
|
|
|
|
|
|
module_put(THIS_MODULE);
|