diff mbox series

[stable,5.10,3/3] dm: delay registering the gendisk

Message ID 20220729062356.1663513-4-yukuai1@huaweicloud.com (mailing list archive)
State New, archived
Headers show
Series dm: fix nullptr crash | expand

Commit Message

Yu Kuai July 29, 2022, 6:23 a.m. UTC
From: Christoph Hellwig <hch@lst.de>

commit 89f871af1b26d98d983cba7ed0e86effa45ba5f8 upstream.

device mapper is currently the only outlier that tries to call
register_disk after add_disk, leading to fairly inconsistent state
of these block layer data structures.  Instead change device-mapper
to just register the gendisk later now that the holder mechanism
can cope with that.

Note that this introduces a user visible change: the dm kobject is
now only visible after the initial table has been loaded.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
 drivers/md/dm.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index ab0e2338e47e..85efe2f1995f 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1795,7 +1795,12 @@  static void cleanup_mapped_device(struct mapped_device *md)
 		spin_lock(&_minor_lock);
 		md->disk->private_data = NULL;
 		spin_unlock(&_minor_lock);
-		del_gendisk(md->disk);
+		if (dm_get_md_type(md) != DM_TYPE_NONE) {
+			dm_sysfs_exit(md);
+			del_gendisk(md->disk);
+		} else {
+			md->disk->queue = NULL;
+		}
 		put_disk(md->disk);
 	}
 
@@ -1900,7 +1905,6 @@  static struct mapped_device *alloc_dev(int minor)
 		}
 	}
 
-	add_disk_no_queue_reg(md->disk);
 	format_dev_t(md->name, MKDEV(_major, minor));
 
 	md->wq = alloc_workqueue("kdmflush", WQ_MEM_RECLAIM, 0);
@@ -2098,19 +2102,12 @@  static struct dm_table *__unbind(struct mapped_device *md)
  */
 int dm_create(int minor, struct mapped_device **result)
 {
-	int r;
 	struct mapped_device *md;
 
 	md = alloc_dev(minor);
 	if (!md)
 		return -ENXIO;
 
-	r = dm_sysfs_init(md);
-	if (r) {
-		free_dev(md);
-		return r;
-	}
-
 	*result = md;
 	return 0;
 }
@@ -2188,8 +2185,14 @@  int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
 		return r;
 	}
 	dm_table_set_restrictions(t, md->queue, &limits);
-	blk_register_queue(md->disk);
 
+	add_disk(md->disk);
+	r = dm_sysfs_init(md);
+	if (r) {
+		del_gendisk(md->disk);
+		return r;
+	}
+	md->type = type;
 	return 0;
 }
 
@@ -2295,7 +2298,6 @@  static void __dm_destroy(struct mapped_device *md, bool wait)
 		DMWARN("%s: Forcibly removing mapped_device still in use! (%d users)",
 		       dm_device_name(md), atomic_read(&md->holders));
 
-	dm_sysfs_exit(md);
 	dm_table_destroy(__unbind(md));
 	free_dev(md);
 }