diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2008-07-22 09:31:41 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-07-26 15:14:57 -0400 |
commit | b3c10489cb464b12a74dda65f826433f71f2c2e2 (patch) | |
tree | b3d461f577e63708a6a5ab1bef48c8dc91283b92 /drivers | |
parent | 0ae808e02e000058cf65a47662c187dc061bcfd3 (diff) |
[SCSI] ibmvfc: Target refcounting fixes
Fix up some refcounting on the ibmvfc drivers internal target struct
when accessed through some sysfs attributes.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 8d393800f47e..1781cec97fba 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -854,39 +854,41 @@ static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost) | |||
854 | } | 854 | } |
855 | 855 | ||
856 | /** | 856 | /** |
857 | * __ibmvfc_find_target - Find the specified scsi_target (no locking) | 857 | * __ibmvfc_get_target - Find the specified scsi_target (no locking) |
858 | * @starget: scsi target struct | 858 | * @starget: scsi target struct |
859 | * | 859 | * |
860 | * Return value: | 860 | * Return value: |
861 | * ibmvfc_target struct / NULL if not found | 861 | * ibmvfc_target struct / NULL if not found |
862 | **/ | 862 | **/ |
863 | static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget) | 863 | static struct ibmvfc_target *__ibmvfc_get_target(struct scsi_target *starget) |
864 | { | 864 | { |
865 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 865 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
866 | struct ibmvfc_host *vhost = shost_priv(shost); | 866 | struct ibmvfc_host *vhost = shost_priv(shost); |
867 | struct ibmvfc_target *tgt; | 867 | struct ibmvfc_target *tgt; |
868 | 868 | ||
869 | list_for_each_entry(tgt, &vhost->targets, queue) | 869 | list_for_each_entry(tgt, &vhost->targets, queue) |
870 | if (tgt->target_id == starget->id) | 870 | if (tgt->target_id == starget->id) { |
871 | kref_get(&tgt->kref); | ||
871 | return tgt; | 872 | return tgt; |
873 | } | ||
872 | return NULL; | 874 | return NULL; |
873 | } | 875 | } |
874 | 876 | ||
875 | /** | 877 | /** |
876 | * ibmvfc_find_target - Find the specified scsi_target | 878 | * ibmvfc_get_target - Find the specified scsi_target |
877 | * @starget: scsi target struct | 879 | * @starget: scsi target struct |
878 | * | 880 | * |
879 | * Return value: | 881 | * Return value: |
880 | * ibmvfc_target struct / NULL if not found | 882 | * ibmvfc_target struct / NULL if not found |
881 | **/ | 883 | **/ |
882 | static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget) | 884 | static struct ibmvfc_target *ibmvfc_get_target(struct scsi_target *starget) |
883 | { | 885 | { |
884 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 886 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
885 | struct ibmvfc_target *tgt; | 887 | struct ibmvfc_target *tgt; |
886 | unsigned long flags; | 888 | unsigned long flags; |
887 | 889 | ||
888 | spin_lock_irqsave(shost->host_lock, flags); | 890 | spin_lock_irqsave(shost->host_lock, flags); |
889 | tgt = __ibmvfc_find_target(starget); | 891 | tgt = __ibmvfc_get_target(starget); |
890 | spin_unlock_irqrestore(shost->host_lock, flags); | 892 | spin_unlock_irqrestore(shost->host_lock, flags); |
891 | return tgt; | 893 | return tgt; |
892 | } | 894 | } |
@@ -991,6 +993,17 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
991 | } | 993 | } |
992 | 994 | ||
993 | /** | 995 | /** |
996 | * ibmvfc_release_tgt - Free memory allocated for a target | ||
997 | * @kref: kref struct | ||
998 | * | ||
999 | **/ | ||
1000 | static void ibmvfc_release_tgt(struct kref *kref) | ||
1001 | { | ||
1002 | struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); | ||
1003 | kfree(tgt); | ||
1004 | } | ||
1005 | |||
1006 | /** | ||
994 | * ibmvfc_get_starget_node_name - Get SCSI target's node name | 1007 | * ibmvfc_get_starget_node_name - Get SCSI target's node name |
995 | * @starget: scsi target struct | 1008 | * @starget: scsi target struct |
996 | * | 1009 | * |
@@ -999,8 +1012,10 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
999 | **/ | 1012 | **/ |
1000 | static void ibmvfc_get_starget_node_name(struct scsi_target *starget) | 1013 | static void ibmvfc_get_starget_node_name(struct scsi_target *starget) |
1001 | { | 1014 | { |
1002 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1015 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
1003 | fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; | 1016 | fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; |
1017 | if (tgt) | ||
1018 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
1004 | } | 1019 | } |
1005 | 1020 | ||
1006 | /** | 1021 | /** |
@@ -1012,8 +1027,10 @@ static void ibmvfc_get_starget_node_name(struct scsi_target *starget) | |||
1012 | **/ | 1027 | **/ |
1013 | static void ibmvfc_get_starget_port_name(struct scsi_target *starget) | 1028 | static void ibmvfc_get_starget_port_name(struct scsi_target *starget) |
1014 | { | 1029 | { |
1015 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1030 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
1016 | fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; | 1031 | fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; |
1032 | if (tgt) | ||
1033 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
1017 | } | 1034 | } |
1018 | 1035 | ||
1019 | /** | 1036 | /** |
@@ -1025,8 +1042,10 @@ static void ibmvfc_get_starget_port_name(struct scsi_target *starget) | |||
1025 | **/ | 1042 | **/ |
1026 | static void ibmvfc_get_starget_port_id(struct scsi_target *starget) | 1043 | static void ibmvfc_get_starget_port_id(struct scsi_target *starget) |
1027 | { | 1044 | { |
1028 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1045 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
1029 | fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; | 1046 | fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; |
1047 | if (tgt) | ||
1048 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
1030 | } | 1049 | } |
1031 | 1050 | ||
1032 | /** | 1051 | /** |
@@ -2651,17 +2670,6 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt, | |||
2651 | } | 2670 | } |
2652 | 2671 | ||
2653 | /** | 2672 | /** |
2654 | * ibmvfc_release_tgt - Free memory allocated for a target | ||
2655 | * @kref: kref struct | ||
2656 | * | ||
2657 | **/ | ||
2658 | static void ibmvfc_release_tgt(struct kref *kref) | ||
2659 | { | ||
2660 | struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); | ||
2661 | kfree(tgt); | ||
2662 | } | ||
2663 | |||
2664 | /** | ||
2665 | * ibmvfc_tgt_prli_done - Completion handler for Process Login | 2673 | * ibmvfc_tgt_prli_done - Completion handler for Process Login |
2666 | * @evt: ibmvfc event struct | 2674 | * @evt: ibmvfc event struct |
2667 | * | 2675 | * |