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 | #define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */ | 147 | #define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */ |
| 148 | #define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */ | 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 | * CDROM IOCTL structures | 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 | * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336, | 318 | * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336, |
| 300 | * 2340, or 2352 bytes long. | 319 | * 2340, or 2352 bytes long. |