The I/O submission and completion pathes call into the device handler without any synchronization agains detachment. So disallow detaching device handlers at runtime. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- drivers/scsi/device_handler/scsi_dh.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 0d6ab33..1e945aa 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -142,17 +142,6 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev, } /* - * scsi_dh_handler_detach - Detach a device handler from a device - * @sdev - SCSI device the device handler should be detached from - */ -static void scsi_dh_handler_detach(struct scsi_device *sdev) -{ - sdev->handler->detach(sdev); - sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name); - module_put(sdev->handler->module); -} - -/* * Functions for sysfs attribute 'dh_state' */ static ssize_t @@ -179,8 +168,9 @@ store_dh_state(struct device *dev, struct device_attribute *attr, /* * Detach from a device handler */ - scsi_dh_handler_detach(sdev); - err = 0; + sdev_printk(KERN_WARNING, sdev, + "can't detach handler %s!\n", buf); + err = -EINVAL; } else if (!strncmp(buf, "activate", 8)) { /* * Activate a device handler @@ -230,8 +220,11 @@ int scsi_dh_add_device(struct scsi_device *sdev) void scsi_dh_remove_device(struct scsi_device *sdev) { - if (sdev->handler) - scsi_dh_handler_detach(sdev); + if (sdev->handler) { + sdev->handler->detach(sdev); + module_put(sdev->handler->module); + } + device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr); } @@ -393,15 +386,19 @@ int scsi_dh_attach(struct request_queue *q, const char *name) goto out_put_device; } + if (err) + return err; + if (sdev->handler) { if (sdev->handler == scsi_dh) goto out_put_device; sdev_printk(KERN_WARNING, sdev, - "replacing device handler %s with %s!, " + "can't replace device handler %s with %s!, " "please fix the device handler tables.\n", sdev->handler->name, name); - scsi_dh_handler_detach(sdev); + err = -EINVAL; + goto out_put_device; } err = scsi_dh_handler_attach(sdev, scsi_dh); -- 1.9.1 -- 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