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.
Showing the changes to include/uapi (1 of 5 files). Show all
Unified · Split
| @@ -147,6 +147,8 @@ · 146 unmodified lines | ||
| 147 | 147 | #define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */ |
| 148 | 148 | #define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */ |
| 149 | 149 | |
| 150 | +#define CDROM_TIMED_MEDIA_CHANGE 0x5396 /* get the timestamp of the last media change */ | |
| 151 | + | |
| 150 | 152 | /******************************************************* |
| 151 | 153 | * CDROM IOCTL structures |
| 152 | 154 | *******************************************************/ |
| @@ -295,6 +297,23 @@ struct cdrom_generic_command · 142 unmodified lines | ||
| 295 | 297 | }; |
| 296 | 298 | }; |
| 297 | 299 | |
| 300 | +/* This struct is used by CDROM_TIMED_MEDIA_CHANGE */ | |
| 301 | +struct cdrom_timed_media_change_info { | |
| 302 | + __s64 last_media_change; /* Timestamp of the last detected media | |
| 303 | + * change in ms. May be set by caller, | |
| 304 | + * updated upon successful return of | |
| 305 | + * ioctl. | |
| 306 | + */ | |
| 307 | + __u64 media_flags; /* Flags returned by ioctl to indicate | |
| 308 | + * media status. | |
| 309 | + */ | |
| 310 | +}; | |
| 311 | +#define MEDIA_CHANGED_FLAG 0x1 /* Last detected media change was more | |
| 312 | + * recent than last_media_change set by | |
| 313 | + * caller. | |
| 314 | + */ | |
| 315 | +/* other bits of media_flags available for future use */ | |
| 316 | + | |
| 298 | 317 | /* |
| 299 | 318 | * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336, |
| 300 | 319 | * 2340, or 2352 bytes long. |