drivers/cdrom: improved ioctl for media change detection

The current implementation of the CDROM_MEDIA_CHANGED ioctl relies on
global state, meaning that only one process can detect a disc change
while the ioctl call will return 0 for other calling processes afterwards
(see bug 213267).

This introduces a new cdrom ioctl, CDROM_TIMED_MEDIA_CHANGE, that
works by maintaining a timestamp of the last detected disc change instead
of a boolean flag: Processes calling this ioctl command can provide
a timestamp of the last disc change known to them and receive
an indication whether the disc was changed since then and the updated
timestamp.

I considered fixing the buggy behavior in the original
CDROM_MEDIA_CHANGED ioctl but that would require maintaining state
for each calling process in the kernel, which seems like a worse
solution than introducing this new ioctl.

Signed-off-by: Lukas Prediger <lumip@lumip.de>
Link: https://lore.kernel.org/all/20210912191207.74449-1-lumip@lumip.de
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
Link: https://lore.kernel.org/r/20210913230942.1188-1-phil@philpotter.co.uk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Lukas Prediger
2021-09-14 00:09:42 +01:00
committed by Jens Axboe
parent 316346243b
commit 67f1e027c2
5 changed files with 89 additions and 4 deletions

View File

@@ -147,6 +147,8 @@
#define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */
#define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */
#define CDROM_TIMED_MEDIA_CHANGE 0x5396 /* get the timestamp of the last media change */
/*******************************************************
* CDROM IOCTL structures
*******************************************************/
@@ -295,6 +297,23 @@ struct cdrom_generic_command
};
};
/* This struct is used by CDROM_TIMED_MEDIA_CHANGE */
struct cdrom_timed_media_change_info {
__s64 last_media_change; /* Timestamp of the last detected media
* change in ms. May be set by caller,
* updated upon successful return of
* ioctl.
*/
__u64 media_flags; /* Flags returned by ioctl to indicate
* media status.
*/
};
#define MEDIA_CHANGED_FLAG 0x1 /* Last detected media change was more
* recent than last_media_change set by
* caller.
*/
/* other bits of media_flags available for future use */
/*
* A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
* 2340, or 2352 bytes long.