diff options
author | Hannes Reinecke <hare@suse.de> | 2016-04-26 02:06:58 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-05-22 14:53:06 -0400 |
commit | eb72d0bb84eee5d0dc3044fd17b75e7101dabb57 (patch) | |
tree | 746f6c67d19372ca2b336027a4e5b1f8d8be6e62 | |
parent | a621bac3044ed6f7ec5fa0326491b2d4838bfa93 (diff) |
sd: get disk reference in sd_check_events()
sd_check_events() is called asynchronously, and might race
with device removal. So always take a disk reference when
processing the event to avoid the device being removed while
the event is processed.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/sd.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 428c03ef02b2..f459dff30512 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1398,11 +1398,15 @@ static int media_not_present(struct scsi_disk *sdkp, | |||
1398 | **/ | 1398 | **/ |
1399 | static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) | 1399 | static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) |
1400 | { | 1400 | { |
1401 | struct scsi_disk *sdkp = scsi_disk(disk); | 1401 | struct scsi_disk *sdkp = scsi_disk_get(disk); |
1402 | struct scsi_device *sdp = sdkp->device; | 1402 | struct scsi_device *sdp; |
1403 | struct scsi_sense_hdr *sshdr = NULL; | 1403 | struct scsi_sense_hdr *sshdr = NULL; |
1404 | int retval; | 1404 | int retval; |
1405 | 1405 | ||
1406 | if (!sdkp) | ||
1407 | return 0; | ||
1408 | |||
1409 | sdp = sdkp->device; | ||
1406 | SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); | 1410 | SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); |
1407 | 1411 | ||
1408 | /* | 1412 | /* |
@@ -1459,6 +1463,7 @@ out: | |||
1459 | kfree(sshdr); | 1463 | kfree(sshdr); |
1460 | retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; | 1464 | retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; |
1461 | sdp->changed = 0; | 1465 | sdp->changed = 0; |
1466 | scsi_disk_put(sdkp); | ||
1462 | return retval; | 1467 | return retval; |
1463 | } | 1468 | } |
1464 | 1469 | ||