Skip to content

Commit

Permalink
[SCSI] fc transport: bug fix: correct references
Browse files Browse the repository at this point in the history
Original post was incorrect as it didn't realize that we already had
a self-referenc due to device_initialize(), and we were really only
missing the put on our own reference. This was hidden by the other bug
which had the midlayer reusing stargets after they were already free,
which was doing too many puts on our rport.

Updating FC transport for:
- Add put in fc_rport_final_delete(), to release the rport.
  Prior, we were leaving the rport with a reference, thus the shost
  with references, etc. If the driver was unloaded, shosts and rports
  remained, along with work threads, etc
- Fix fc_rport_create failure path - too many put's on parent
- Add commenting to easily track ref taking.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
James Smart authored and James Bottomley committed Jun 27, 2006
1 parent 1c9e16e commit 3bdad7b
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions drivers/scsi/scsi_transport_fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,8 @@ fc_rport_final_delete(void *data)
transport_remove_device(dev);
device_del(dev);
transport_destroy_device(dev);
put_device(&shost->shost_gendev);
put_device(&shost->shost_gendev); /* for fc_host->rport list */
put_device(dev); /* for self-reference */
}


Expand Down Expand Up @@ -1537,13 +1538,13 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
else
rport->scsi_target_id = -1;
list_add_tail(&rport->peers, &fc_host->rports);
get_device(&shost->shost_gendev);
get_device(&shost->shost_gendev); /* for fc_host->rport list */

spin_unlock_irqrestore(shost->host_lock, flags);

dev = &rport->dev;
device_initialize(dev);
dev->parent = get_device(&shost->shost_gendev);
device_initialize(dev); /* takes self reference */
dev->parent = get_device(&shost->shost_gendev); /* parent reference */
dev->release = fc_rport_dev_release;
sprintf(dev->bus_id, "rport-%d:%d-%d",
shost->host_no, channel, rport->number);
Expand All @@ -1567,10 +1568,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel,

delete_rport:
transport_destroy_device(dev);
put_device(dev->parent);
spin_lock_irqsave(shost->host_lock, flags);
list_del(&rport->peers);
put_device(&shost->shost_gendev);
put_device(&shost->shost_gendev); /* for fc_host->rport list */
spin_unlock_irqrestore(shost->host_lock, flags);
put_device(dev->parent);
kfree(rport);
Expand Down

0 comments on commit 3bdad7b

Please sign in to comment.