The following patch fixes an oops which was observed during device scanning. If LUN 0 does not exist for a valid target, but non-zero LUNs do exist, a struct scsi_device exists only when probing the target and is deleted by the scanning code, by checking to see if the device's state is SDEV_CREATED. If, while scanning, the rport is deleted, such that target is placed into the blocked state, and then later the rport is added again, the LUN 0 sdev finds its way into the SDEV_RUNNING state. This causes the scanning code to NOT delete the sdev when scanning is complete. Later on, if the target is deleted, we will oops when we try to free up everything that gets allocated in scsi_sysfs_add_sdev, since it was never added. This patch fixes this issue, by adding a added_to_sysfs flag to struct scsi_device, which is then checked to determine what to do, both in the device probe exit code and the device remove code. Signed-off-by: Brian King <brking@xxxxxxxxxxxxxxxxxx> --- drivers/scsi/scsi_scan.c | 4 ++-- drivers/scsi/scsi_sysfs.c | 11 +++++++---- include/scsi/scsi_device.h | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff -puN include/scsi/scsi_device.h~scsi_add_sysfs_flag include/scsi/scsi_device.h --- linux-2.6/include/scsi/scsi_device.h~scsi_add_sysfs_flag 2008-08-11 10:49:06.000000000 -0500 +++ linux-2.6-bjking1/include/scsi/scsi_device.h 2008-08-11 10:49:06.000000000 -0500 @@ -142,6 +142,7 @@ struct scsi_device { unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ unsigned last_sector_bug:1; /* do not use multisector accesses on SD_LAST_BUGGY_SECTORS */ + unsigned added_to_sysfs:1; /* Device added to sysfs */ DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ struct list_head event_list; /* asserted events */ diff -puN drivers/scsi/scsi_sysfs.c~scsi_add_sysfs_flag drivers/scsi/scsi_sysfs.c --- linux-2.6/drivers/scsi/scsi_sysfs.c~scsi_add_sysfs_flag 2008-08-11 10:49:06.000000000 -0500 +++ linux-2.6-bjking1/drivers/scsi/scsi_sysfs.c 2008-08-11 10:49:06.000000000 -0500 @@ -922,6 +922,7 @@ int scsi_sysfs_add_sdev(struct scsi_devi } transport_add_device(&sdev->sdev_gendev); + sdev->added_to_sysfs = 1; out: return error; @@ -942,10 +943,12 @@ void __scsi_remove_device(struct scsi_de if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) return; - bsg_unregister_queue(sdev->request_queue); - device_unregister(&sdev->sdev_dev); - transport_remove_device(dev); - device_del(dev); + if (sdev->added_to_sysfs) { + bsg_unregister_queue(sdev->request_queue); + device_unregister(&sdev->sdev_dev); + transport_remove_device(dev); + device_del(dev); + } scsi_device_set_state(sdev, SDEV_DEL); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); diff -puN drivers/scsi/scsi_scan.c~scsi_add_sysfs_flag drivers/scsi/scsi_scan.c --- linux-2.6/drivers/scsi/scsi_scan.c~scsi_add_sysfs_flag 2008-08-11 10:49:06.000000000 -0500 +++ linux-2.6-bjking1/drivers/scsi/scsi_scan.c 2008-08-11 10:49:06.000000000 -0500 @@ -994,7 +994,7 @@ static int scsi_probe_and_add_lun(struct */ sdev = scsi_device_lookup_by_target(starget, lun); if (sdev) { - if (rescan || sdev->sdev_state != SDEV_CREATED) { + if (rescan || sdev->added_to_sysfs) { SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: device exists on %s\n", sdev->sdev_gendev.bus_id)); @@ -1466,7 +1466,7 @@ static int scsi_report_lun_scan(struct s kfree(lun_data); out: scsi_device_put(sdev); - if (sdev->sdev_state == SDEV_CREATED) + if (!sdev->added_to_sysfs) /* * the sdev we used didn't appear in the report luns scan */ _ -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html