]> err.no Git - linux-2.6/commitdiff
[SCSI] scsi: Handle device_add failure in scsi_alloc_target
authorBrian King <brking@us.ibm.com>
Wed, 22 Feb 2006 20:28:24 +0000 (14:28 -0600)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Tue, 28 Feb 2006 05:38:59 +0000 (23:38 -0600)
Fixes scsi to handle device_add failure in scsi_alloc_target.
Without this patch, if this call were to fail, we can oops
when we free the target.

Signed-off-by: Brian King <brking@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/scsi_scan.c

index 84f01fd0c8fde8fbc7c5a404bfbc775c6d286280..be14f9d82fde36418e0c0f3e90a67c7c401f0ea6 100644 (file)
@@ -332,6 +332,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
                + shost->transportt->target_size;
        struct scsi_target *starget;
        struct scsi_target *found_target;
+       int error;
 
        starget = kzalloc(size, GFP_KERNEL);
        if (!starget) {
@@ -361,10 +362,20 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
        spin_unlock_irqrestore(shost->host_lock, flags);
        /* allocate and add */
        transport_setup_device(dev);
-       device_add(dev);
+       error = device_add(dev);
+       if (error) {
+               dev_err(dev, "target device_add failed, error %d\n", error);
+               spin_lock_irqsave(shost->host_lock, flags);
+               list_del_init(&starget->siblings);
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               transport_destroy_device(dev);
+               put_device(parent);
+               kfree(starget);
+               return NULL;
+       }
        transport_add_device(dev);
        if (shost->hostt->target_alloc) {
-               int error = shost->hostt->target_alloc(starget);
+               error = shost->hostt->target_alloc(starget);
 
                if(error) {
                        dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);