diff options
author | Brian King <brking@us.ibm.com> | 2006-02-22 14:28:24 -0600 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-02-27 23:38:59 -0600 |
commit | 32f95792500794a0a7cce266b7dafb2bee323bf8 (patch) | |
tree | f7565bd227ffbb71b72f306de84bb1dca3bd0917 /drivers/scsi/scsi_scan.c | |
parent | ffedb4522571ac170f941678d138a31bc0884ab4 (diff) |
[SCSI] scsi: Handle device_add failure in scsi_alloc_target
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>
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 84f01fd0c8f..be14f9d82fd 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -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); |