2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

cdrom: Call cdrom_mrw_exit from cdrom_release function

Remove the cdrom_mrw_exit call from unregister_cdrom, as it invokes
block commands that can fail due to a NULL pointer dereference from the
call happening too late, during the unloading of the driver (e.g.
unplugging of USB optical drives).

Instead perform the call inside cdrom_release, thus also removing the
need for the exit function pointer inside the cdrom_device_info struct.

Reported-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Closes: https://lore.kernel.org/linux-block/uxgzea5ibqxygv3x7i4ojbpvcpv2wziorvb3ns5cdtyvobyn7h@y4g4l5ezv2ec
Suggested-by: Jens Axboe <axboe@kernel.dk>
Link: https://lore.kernel.org/linux-block/6686fe78-a050-4a1d-aa27-b7bf7ca6e912@kernel.dk
Tested-by: Phillip Potter <phil@philpotter.co.uk>
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
Link: https://lore.kernel.org/r/20250722231900.1164-2-phil@philpotter.co.uk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Phillip Potter 2025-07-23 00:19:00 +01:00 committed by Jens Axboe
parent 63ce537246
commit 5ec9d26b78
3 changed files with 2 additions and 8 deletions

View File

@ -273,7 +273,6 @@ The drive-specific, minor-like information that is registered with
__u8 media_written; /* dirty flag, DVD+RW bookkeeping */ __u8 media_written; /* dirty flag, DVD+RW bookkeeping */
unsigned short mmc3_profile; /* current MMC3 profile */ unsigned short mmc3_profile; /* current MMC3 profile */
int for_data; /* unknown:TBD */ int for_data; /* unknown:TBD */
int (*exit)(struct cdrom_device_info *);/* unknown:TBD */
int mrw_mode_page; /* which MRW mode page is in use */ int mrw_mode_page; /* which MRW mode page is in use */
}; };

View File

@ -624,9 +624,6 @@ int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi)
if (check_media_type == 1) if (check_media_type == 1)
cdi->options |= (int) CDO_CHECK_TYPE; cdi->options |= (int) CDO_CHECK_TYPE;
if (CDROM_CAN(CDC_MRW_W))
cdi->exit = cdrom_mrw_exit;
if (cdi->ops->read_cdda_bpc) if (cdi->ops->read_cdda_bpc)
cdi->cdda_method = CDDA_BPC_FULL; cdi->cdda_method = CDDA_BPC_FULL;
else else
@ -651,9 +648,6 @@ void unregister_cdrom(struct cdrom_device_info *cdi)
list_del(&cdi->list); list_del(&cdi->list);
mutex_unlock(&cdrom_mutex); mutex_unlock(&cdrom_mutex);
if (cdi->exit)
cdi->exit(cdi);
cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
} }
EXPORT_SYMBOL(unregister_cdrom); EXPORT_SYMBOL(unregister_cdrom);
@ -1264,6 +1258,8 @@ void cdrom_release(struct cdrom_device_info *cdi)
cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n",
cdi->name); cdi->name);
cdrom_dvd_rw_close_write(cdi); cdrom_dvd_rw_close_write(cdi);
if (CDROM_CAN(CDC_MRW_W))
cdrom_mrw_exit(cdi);
if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) { if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
cd_dbg(CD_CLOSE, "Unlocking door!\n"); cd_dbg(CD_CLOSE, "Unlocking door!\n");

View File

@ -62,7 +62,6 @@ struct cdrom_device_info {
__u8 last_sense; __u8 last_sense;
__u8 media_written; /* dirty flag, DVD+RW bookkeeping */ __u8 media_written; /* dirty flag, DVD+RW bookkeeping */
unsigned short mmc3_profile; /* current MMC3 profile */ unsigned short mmc3_profile; /* current MMC3 profile */
int (*exit)(struct cdrom_device_info *);
int mrw_mode_page; int mrw_mode_page;
bool opened_for_data; bool opened_for_data;
__s64 last_media_change_ms; __s64 last_media_change_ms;