Blob Blame History Raw
From e8bac0005b99f71190d276e06b30b6a4fae83532 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 18 Jan 2019 00:00:07 +0100
Subject: [PATCH v2 4/4] block: check_events: don't bother with events if
 unsupported
Patch-mainline: v5.2-rc1
Git-commit: cdf3e3deb747d5e193dee617ed37c83060eb576f
References: bsc#1110946, bsc#1119843

Drivers now report to the block layer if they support media change
events. If this is not the case, there's no need to allocate
the event structure, and all event handling code can effectively
be skipped. This simplifies code flow in particular for
non-removable sd devices.

This effectively reverts commit 75e3f3ee3c64 ("block: always allocate
genhd->ev if check_events is implemented").

The sysfs files for the events are kept in place even if no events
are supported, as user space may rely on them being present. The only
difference is that an error code is now returned if the user tries
to set poll_msecs.

Signed-off-by: Martin Wilck <mwilck@suse.com>
---
 block/genhd.c |   28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1855,6 +1855,9 @@ static ssize_t disk_events_poll_msecs_sh
 {
 	struct gendisk *disk = dev_to_disk(dev);
 
+	if (!disk->ev)
+		return sprintf(buf, "-1\n");
+
 	return sprintf(buf, "%ld\n", disk->ev->poll_msecs);
 }
 
@@ -1871,6 +1874,9 @@ static ssize_t disk_events_poll_msecs_st
 	if (intv < 0 && intv != -1)
 		return -EINVAL;
 
+	if (!disk->ev)
+		return -ENODEV;
+
 	disk_block_events(disk);
 	disk->ev->poll_msecs = intv;
 	__disk_unblock_events(disk, true);
@@ -1935,7 +1941,8 @@ static void disk_alloc_events(struct gen
 {
 	struct disk_events *ev;
 
-	if (!disk->fops->check_events)
+	if (!disk->fops->check_events ||
+	    !(disk->events & DISK_EVENT_TYPES_MASK))
 		return;
 
 	ev = kzalloc(sizeof(*ev), GFP_KERNEL);
@@ -1957,14 +1964,14 @@ static void disk_alloc_events(struct gen
 
 static void disk_add_events(struct gendisk *disk)
 {
-	if (!disk->ev)
-		return;
-
 	/* FIXME: error handling */
 	if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0)
 		pr_warn("%s: failed to create sysfs files for events\n",
 			disk->disk_name);
 
+	if (!disk->ev)
+		return;
+
 	mutex_lock(&disk_events_mutex);
 	list_add_tail(&disk->ev->node, &disk_events);
 	mutex_unlock(&disk_events_mutex);
@@ -1978,14 +1985,13 @@ static void disk_add_events(struct gendi
 
 static void disk_del_events(struct gendisk *disk)
 {
-	if (!disk->ev)
-		return;
-
-	disk_block_events(disk);
+	if (disk->ev) {
+		disk_block_events(disk);
 
-	mutex_lock(&disk_events_mutex);
-	list_del_init(&disk->ev->node);
-	mutex_unlock(&disk_events_mutex);
+		mutex_lock(&disk_events_mutex);
+		list_del_init(&disk->ev->node);
+		mutex_unlock(&disk_events_mutex);
+	}
 
 	sysfs_remove_files(&disk_to_dev(disk)->kobj, disk_events_attrs);
 }