linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] block: emit disk ro uevent in device_add_disk()
@ 2022-03-03 17:52 Uday Shankar
  2022-03-04 16:08 ` Christoph Hellwig
  2022-03-07  6:39 ` Hannes Reinecke
  0 siblings, 2 replies; 6+ messages in thread
From: Uday Shankar @ 2022-03-03 17:52 UTC (permalink / raw)
  To: linux-block; +Cc: Jens Axboe, Uday Shankar

Userspace learns of disk ro state via the change event emitted by
set_disk_ro_uevent. This function has cyclic dependency with
device_add_disk: the latter performs kobject initialization that is
necessary for uevents to go through, but we want to set up properties
like ro state before exposing the disk to userspace via device_add_disk.

The usual workaround is to call set_disk_ro both before and after
device_add_disk; the purpose of the "after" call is just to emit the
uevent. Moreover, because set_disk_ro only emits a uevent when the ro
state changes, set_disk_ro needs to be called twice in the "after"
position to ensure that the ro state flips. See drivers/scsi/sd.c for an
example of this pattern.

The nvme driver does not implement this pattern. It only calls
set_disk_ro before device_add_disk, and so the ro uevent is never
emitted. This breaks applications such as dm-multipath. To avoid
introducing the messy pattern above into the nvme driver, emit the disk
ro uevent immediately after announcing addition of the disk.

Signed-off-by: Uday Shankar <ushankar@purestorage.com>
---
 block/genhd.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 11c761afd64f..89a110f0b002 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -394,6 +394,16 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
 	return 0;
 }
 
+static void set_disk_ro_uevent(struct gendisk *gd, int ro)
+{
+	char event[] = "DISK_RO=1";
+	char *envp[] = { event, NULL };
+
+	if (!ro)
+		event[8] = '0';
+	kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
+}
+
 /**
  * device_add_disk - add disk information to kernel list
  * @parent: parent device for the disk
@@ -522,6 +532,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
 		 */
 		dev_set_uevent_suppress(ddev, 0);
 		disk_uevent(disk, KOBJ_ADD);
+		set_disk_ro_uevent(disk, get_disk_ro(disk));
 	}
 
 	disk_update_readahead(disk);
@@ -1419,16 +1430,6 @@ void blk_cleanup_disk(struct gendisk *disk)
 }
 EXPORT_SYMBOL(blk_cleanup_disk);
 
-static void set_disk_ro_uevent(struct gendisk *gd, int ro)
-{
-	char event[] = "DISK_RO=1";
-	char *envp[] = { event, NULL };
-
-	if (!ro)
-		event[8] = '0';
-	kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
-}
-
 /**
  * set_disk_ro - set a gendisk read-only
  * @disk:	gendisk to operate on
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-03-08  6:47 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-03 17:52 [PATCH] block: emit disk ro uevent in device_add_disk() Uday Shankar
2022-03-04 16:08 ` Christoph Hellwig
2022-03-07  6:39 ` Hannes Reinecke
2022-03-07 20:54   ` Uday Shankar
2022-03-08  6:42     ` Hannes Reinecke
2022-03-08  6:47       ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).