[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>

authored by

Brian King and committed by
James Bottomley
b3c10489 0ae808e0

+28 -20
+28 -20
drivers/scsi/ibmvscsi/ibmvfc.c
··· 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 858 * @starget: scsi target struct 859 859 * 860 860 * Return value: 861 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 865 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 866 866 struct ibmvfc_host *vhost = shost_priv(shost); 867 867 struct ibmvfc_target *tgt; 868 868 869 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 872 return tgt; 873 + } 872 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 879 * @starget: scsi target struct 878 880 * 879 881 * Return value: 880 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 886 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 885 887 struct ibmvfc_target *tgt; 886 888 unsigned long flags; 887 889 888 890 spin_lock_irqsave(shost->host_lock, flags); 889 - tgt = __ibmvfc_find_target(starget); 891 + tgt = __ibmvfc_get_target(starget); 890 892 spin_unlock_irqrestore(shost->host_lock, flags); 891 893 return tgt; 892 894 } ··· 993 991 } 994 992 995 993 /** 994 + * ibmvfc_release_tgt - Free memory allocated for a target 995 + * @kref: kref struct 996 + * 997 + **/ 998 + static void ibmvfc_release_tgt(struct kref *kref) 999 + { 1000 + struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); 1001 + kfree(tgt); 1002 + } 1003 + 1004 + /** 996 1005 * ibmvfc_get_starget_node_name - Get SCSI target's node name 997 1006 * @starget: scsi target struct 998 1007 * ··· 1012 999 **/ 1013 1000 static void ibmvfc_get_starget_node_name(struct scsi_target *starget) 1014 1001 { 1015 - struct ibmvfc_target *tgt = ibmvfc_find_target(starget); 1002 + struct ibmvfc_target *tgt = ibmvfc_get_target(starget); 1016 1003 fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; 1004 + if (tgt) 1005 + kref_put(&tgt->kref, ibmvfc_release_tgt); 1017 1006 } 1018 1007 1019 1008 /** ··· 1027 1012 **/ 1028 1013 static void ibmvfc_get_starget_port_name(struct scsi_target *starget) 1029 1014 { 1030 - struct ibmvfc_target *tgt = ibmvfc_find_target(starget); 1015 + struct ibmvfc_target *tgt = ibmvfc_get_target(starget); 1031 1016 fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; 1017 + if (tgt) 1018 + kref_put(&tgt->kref, ibmvfc_release_tgt); 1032 1019 } 1033 1020 1034 1021 /** ··· 1042 1025 **/ 1043 1026 static void ibmvfc_get_starget_port_id(struct scsi_target *starget) 1044 1027 { 1045 - struct ibmvfc_target *tgt = ibmvfc_find_target(starget); 1028 + struct ibmvfc_target *tgt = ibmvfc_get_target(starget); 1046 1029 fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; 1030 + if (tgt) 1031 + kref_put(&tgt->kref, ibmvfc_release_tgt); 1047 1032 } 1048 1033 1049 1034 /** ··· 2667 2648 wake_up(&tgt->vhost->work_wait_q); 2668 2649 } else 2669 2650 ibmvfc_init_tgt(tgt, job_step); 2670 - } 2671 - 2672 - /** 2673 - * ibmvfc_release_tgt - Free memory allocated for a target 2674 - * @kref: kref struct 2675 - * 2676 - **/ 2677 - static void ibmvfc_release_tgt(struct kref *kref) 2678 - { 2679 - struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); 2680 - kfree(tgt); 2681 2651 } 2682 2652 2683 2653 /**