Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

block: check_events: don't bother with events if unsupported

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.

Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Martin Wilck and committed by
Jens Axboe
cdf3e3de 773008f6

+16 -11
+16 -11
block/genhd.c
··· 1904 1904 { 1905 1905 struct gendisk *disk = dev_to_disk(dev); 1906 1906 1907 + if (!disk->ev) 1908 + return sprintf(buf, "-1\n"); 1909 + 1907 1910 return sprintf(buf, "%ld\n", disk->ev->poll_msecs); 1908 1911 } 1909 1912 ··· 1922 1919 1923 1920 if (intv < 0 && intv != -1) 1924 1921 return -EINVAL; 1922 + 1923 + if (!disk->ev) 1924 + return -ENODEV; 1925 1925 1926 1926 disk_block_events(disk); 1927 1927 disk->ev->poll_msecs = intv; ··· 1990 1984 { 1991 1985 struct disk_events *ev; 1992 1986 1993 - if (!disk->fops->check_events) 1987 + if (!disk->fops->check_events || !disk->events) 1994 1988 return; 1995 1989 1996 1990 ev = kzalloc(sizeof(*ev), GFP_KERNEL); ··· 2012 2006 2013 2007 static void disk_add_events(struct gendisk *disk) 2014 2008 { 2015 - if (!disk->ev) 2016 - return; 2017 - 2018 2009 /* FIXME: error handling */ 2019 2010 if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0) 2020 2011 pr_warn("%s: failed to create sysfs files for events\n", 2021 2012 disk->disk_name); 2013 + 2014 + if (!disk->ev) 2015 + return; 2022 2016 2023 2017 mutex_lock(&disk_events_mutex); 2024 2018 list_add_tail(&disk->ev->node, &disk_events); ··· 2033 2027 2034 2028 static void disk_del_events(struct gendisk *disk) 2035 2029 { 2036 - if (!disk->ev) 2037 - return; 2030 + if (disk->ev) { 2031 + disk_block_events(disk); 2038 2032 2039 - disk_block_events(disk); 2040 - 2041 - mutex_lock(&disk_events_mutex); 2042 - list_del_init(&disk->ev->node); 2043 - mutex_unlock(&disk_events_mutex); 2033 + mutex_lock(&disk_events_mutex); 2034 + list_del_init(&disk->ev->node); 2035 + mutex_unlock(&disk_events_mutex); 2036 + } 2044 2037 2045 2038 sysfs_remove_files(&disk_to_dev(disk)->kobj, disk_events_attrs); 2046 2039 }