aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2013-05-06 13:06:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-10 10:47:53 -0400
commit8526cb114f771851d84425d85d8735a6e0816ba2 (patch)
treedabc65e70ea5ca635f9fae207da3e717f7a2bf87 /drivers/scsi
parentaa9f8328fc51460e15da129caf622b6560fa8c99 (diff)
[SCSI] iscsi class, qla4xxx: fix sess/conn refcounting when find fns are used
This fixes a bug where the iscsi class/driver did not do a put_device when a sess/conn device was found. This also simplifies the interface by not having to pass in some arguments that were duplicated and did not need to be exported. Reported-by: Zhao Hongjiang <zhaohongjiang@huawei.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Acked-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c6
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c90
2 files changed, 47 insertions, 49 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index d777332dbed8..4d231c12463e 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -5605,6 +5605,7 @@ static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,
5605 ql4_printk(KERN_ERR, ha, 5605 ql4_printk(KERN_ERR, ha,
5606 "%s: A non-persistent entry %s found\n", 5606 "%s: A non-persistent entry %s found\n",
5607 __func__, dev->kobj.name); 5607 __func__, dev->kobj.name);
5608 put_device(dev);
5608 goto exit_ddb_add; 5609 goto exit_ddb_add;
5609 } 5610 }
5610 5611
@@ -6112,8 +6113,7 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
6112 int parent_type, parent_index = 0xffff; 6113 int parent_type, parent_index = 0xffff;
6113 int rc = 0; 6114 int rc = 0;
6114 6115
6115 dev = iscsi_find_flashnode_conn(fnode_sess, NULL, 6116 dev = iscsi_find_flashnode_conn(fnode_sess);
6116 iscsi_is_flashnode_conn_dev);
6117 if (!dev) 6117 if (!dev)
6118 return -EIO; 6118 return -EIO;
6119 6119
@@ -6347,6 +6347,8 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
6347 rc = -ENOSYS; 6347 rc = -ENOSYS;
6348 break; 6348 break;
6349 } 6349 }
6350
6351 put_device(dev);
6350 return rc; 6352 return rc;
6351} 6353}
6352 6354
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 475265a51a51..133926b1bb78 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1019,8 +1019,7 @@ exit_match_index:
1019/** 1019/**
1020 * iscsi_get_flashnode_by_index -finds flashnode session entry by index 1020 * iscsi_get_flashnode_by_index -finds flashnode session entry by index
1021 * @shost: pointer to host data 1021 * @shost: pointer to host data
1022 * @data: pointer to data containing value to use for comparison 1022 * @idx: index to match
1023 * @fn: function pointer that does actual comparison
1024 * 1023 *
1025 * Finds the flashnode session object for the passed index 1024 * Finds the flashnode session object for the passed index
1026 * 1025 *
@@ -1029,13 +1028,13 @@ exit_match_index:
1029 * %NULL on failure 1028 * %NULL on failure
1030 */ 1029 */
1031static struct iscsi_bus_flash_session * 1030static struct iscsi_bus_flash_session *
1032iscsi_get_flashnode_by_index(struct Scsi_Host *shost, void *data, 1031iscsi_get_flashnode_by_index(struct Scsi_Host *shost, uint32_t idx)
1033 int (*fn)(struct device *dev, void *data))
1034{ 1032{
1035 struct iscsi_bus_flash_session *fnode_sess = NULL; 1033 struct iscsi_bus_flash_session *fnode_sess = NULL;
1036 struct device *dev; 1034 struct device *dev;
1037 1035
1038 dev = device_find_child(&shost->shost_gendev, data, fn); 1036 dev = device_find_child(&shost->shost_gendev, &idx,
1037 flashnode_match_index);
1039 if (dev) 1038 if (dev)
1040 fnode_sess = iscsi_dev_to_flash_session(dev); 1039 fnode_sess = iscsi_dev_to_flash_session(dev);
1041 1040
@@ -1059,18 +1058,13 @@ struct device *
1059iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, 1058iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
1060 int (*fn)(struct device *dev, void *data)) 1059 int (*fn)(struct device *dev, void *data))
1061{ 1060{
1062 struct device *dev; 1061 return device_find_child(&shost->shost_gendev, data, fn);
1063
1064 dev = device_find_child(&shost->shost_gendev, data, fn);
1065 return dev;
1066} 1062}
1067EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess); 1063EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess);
1068 1064
1069/** 1065/**
1070 * iscsi_find_flashnode_conn - finds flashnode connection entry 1066 * iscsi_find_flashnode_conn - finds flashnode connection entry
1071 * @fnode_sess: pointer to parent flashnode session entry 1067 * @fnode_sess: pointer to parent flashnode session entry
1072 * @data: pointer to data containing value to use for comparison
1073 * @fn: function pointer that does actual comparison
1074 * 1068 *
1075 * Finds the flashnode connection object comparing the data passed using logic 1069 * Finds the flashnode connection object comparing the data passed using logic
1076 * defined in passed function pointer 1070 * defined in passed function pointer
@@ -1080,14 +1074,10 @@ EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess);
1080 * %NULL on failure 1074 * %NULL on failure
1081 */ 1075 */
1082struct device * 1076struct device *
1083iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, 1077iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess)
1084 void *data,
1085 int (*fn)(struct device *dev, void *data))
1086{ 1078{
1087 struct device *dev; 1079 return device_find_child(&fnode_sess->dev, NULL,
1088 1080 iscsi_is_flashnode_conn_dev);
1089 dev = device_find_child(&fnode_sess->dev, data, fn);
1090 return dev;
1091} 1081}
1092EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn); 1082EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn);
1093 1083
@@ -2808,7 +2798,7 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
2808 struct iscsi_bus_flash_session *fnode_sess; 2798 struct iscsi_bus_flash_session *fnode_sess;
2809 struct iscsi_bus_flash_conn *fnode_conn; 2799 struct iscsi_bus_flash_conn *fnode_conn;
2810 struct device *dev; 2800 struct device *dev;
2811 uint32_t *idx; 2801 uint32_t idx;
2812 int err = 0; 2802 int err = 0;
2813 2803
2814 if (!transport->set_flashnode_param) { 2804 if (!transport->set_flashnode_param) {
@@ -2824,25 +2814,27 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
2824 goto put_host; 2814 goto put_host;
2825 } 2815 }
2826 2816
2827 idx = &ev->u.set_flashnode.flashnode_idx; 2817 idx = ev->u.set_flashnode.flashnode_idx;
2828 fnode_sess = iscsi_get_flashnode_by_index(shost, idx, 2818 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2829 flashnode_match_index);
2830 if (!fnode_sess) { 2819 if (!fnode_sess) {
2831 pr_err("%s could not find flashnode %u for host no %u\n", 2820 pr_err("%s could not find flashnode %u for host no %u\n",
2832 __func__, *idx, ev->u.set_flashnode.host_no); 2821 __func__, idx, ev->u.set_flashnode.host_no);
2833 err = -ENODEV; 2822 err = -ENODEV;
2834 goto put_host; 2823 goto put_host;
2835 } 2824 }
2836 2825
2837 dev = iscsi_find_flashnode_conn(fnode_sess, NULL, 2826 dev = iscsi_find_flashnode_conn(fnode_sess);
2838 iscsi_is_flashnode_conn_dev);
2839 if (!dev) { 2827 if (!dev) {
2840 err = -ENODEV; 2828 err = -ENODEV;
2841 goto put_host; 2829 goto put_sess;
2842 } 2830 }
2843 2831
2844 fnode_conn = iscsi_dev_to_flash_conn(dev); 2832 fnode_conn = iscsi_dev_to_flash_conn(dev);
2845 err = transport->set_flashnode_param(fnode_sess, fnode_conn, data, len); 2833 err = transport->set_flashnode_param(fnode_sess, fnode_conn, data, len);
2834 put_device(dev);
2835
2836put_sess:
2837 put_device(&fnode_sess->dev);
2846 2838
2847put_host: 2839put_host:
2848 scsi_host_put(shost); 2840 scsi_host_put(shost);
@@ -2891,7 +2883,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
2891{ 2883{
2892 struct Scsi_Host *shost; 2884 struct Scsi_Host *shost;
2893 struct iscsi_bus_flash_session *fnode_sess; 2885 struct iscsi_bus_flash_session *fnode_sess;
2894 uint32_t *idx; 2886 uint32_t idx;
2895 int err = 0; 2887 int err = 0;
2896 2888
2897 if (!transport->del_flashnode) { 2889 if (!transport->del_flashnode) {
@@ -2907,17 +2899,17 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
2907 goto put_host; 2899 goto put_host;
2908 } 2900 }
2909 2901
2910 idx = &ev->u.del_flashnode.flashnode_idx; 2902 idx = ev->u.del_flashnode.flashnode_idx;
2911 fnode_sess = iscsi_get_flashnode_by_index(shost, idx, 2903 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2912 flashnode_match_index);
2913 if (!fnode_sess) { 2904 if (!fnode_sess) {
2914 pr_err("%s could not find flashnode %u for host no %u\n", 2905 pr_err("%s could not find flashnode %u for host no %u\n",
2915 __func__, *idx, ev->u.del_flashnode.host_no); 2906 __func__, idx, ev->u.del_flashnode.host_no);
2916 err = -ENODEV; 2907 err = -ENODEV;
2917 goto put_host; 2908 goto put_host;
2918 } 2909 }
2919 2910
2920 err = transport->del_flashnode(fnode_sess); 2911 err = transport->del_flashnode(fnode_sess);
2912 put_device(&fnode_sess->dev);
2921 2913
2922put_host: 2914put_host:
2923 scsi_host_put(shost); 2915 scsi_host_put(shost);
@@ -2933,7 +2925,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
2933 struct iscsi_bus_flash_session *fnode_sess; 2925 struct iscsi_bus_flash_session *fnode_sess;
2934 struct iscsi_bus_flash_conn *fnode_conn; 2926 struct iscsi_bus_flash_conn *fnode_conn;
2935 struct device *dev; 2927 struct device *dev;
2936 uint32_t *idx; 2928 uint32_t idx;
2937 int err = 0; 2929 int err = 0;
2938 2930
2939 if (!transport->login_flashnode) { 2931 if (!transport->login_flashnode) {
@@ -2949,25 +2941,27 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
2949 goto put_host; 2941 goto put_host;
2950 } 2942 }
2951 2943
2952 idx = &ev->u.login_flashnode.flashnode_idx; 2944 idx = ev->u.login_flashnode.flashnode_idx;
2953 fnode_sess = iscsi_get_flashnode_by_index(shost, idx, 2945 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2954 flashnode_match_index);
2955 if (!fnode_sess) { 2946 if (!fnode_sess) {
2956 pr_err("%s could not find flashnode %u for host no %u\n", 2947 pr_err("%s could not find flashnode %u for host no %u\n",
2957 __func__, *idx, ev->u.login_flashnode.host_no); 2948 __func__, idx, ev->u.login_flashnode.host_no);
2958 err = -ENODEV; 2949 err = -ENODEV;
2959 goto put_host; 2950 goto put_host;
2960 } 2951 }
2961 2952
2962 dev = iscsi_find_flashnode_conn(fnode_sess, NULL, 2953 dev = iscsi_find_flashnode_conn(fnode_sess);
2963 iscsi_is_flashnode_conn_dev);
2964 if (!dev) { 2954 if (!dev) {
2965 err = -ENODEV; 2955 err = -ENODEV;
2966 goto put_host; 2956 goto put_sess;
2967 } 2957 }
2968 2958
2969 fnode_conn = iscsi_dev_to_flash_conn(dev); 2959 fnode_conn = iscsi_dev_to_flash_conn(dev);
2970 err = transport->login_flashnode(fnode_sess, fnode_conn); 2960 err = transport->login_flashnode(fnode_sess, fnode_conn);
2961 put_device(dev);
2962
2963put_sess:
2964 put_device(&fnode_sess->dev);
2971 2965
2972put_host: 2966put_host:
2973 scsi_host_put(shost); 2967 scsi_host_put(shost);
@@ -2983,7 +2977,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
2983 struct iscsi_bus_flash_session *fnode_sess; 2977 struct iscsi_bus_flash_session *fnode_sess;
2984 struct iscsi_bus_flash_conn *fnode_conn; 2978 struct iscsi_bus_flash_conn *fnode_conn;
2985 struct device *dev; 2979 struct device *dev;
2986 uint32_t *idx; 2980 uint32_t idx;
2987 int err = 0; 2981 int err = 0;
2988 2982
2989 if (!transport->logout_flashnode) { 2983 if (!transport->logout_flashnode) {
@@ -2999,26 +2993,28 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
2999 goto put_host; 2993 goto put_host;
3000 } 2994 }
3001 2995
3002 idx = &ev->u.logout_flashnode.flashnode_idx; 2996 idx = ev->u.logout_flashnode.flashnode_idx;
3003 fnode_sess = iscsi_get_flashnode_by_index(shost, idx, 2997 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
3004 flashnode_match_index);
3005 if (!fnode_sess) { 2998 if (!fnode_sess) {
3006 pr_err("%s could not find flashnode %u for host no %u\n", 2999 pr_err("%s could not find flashnode %u for host no %u\n",
3007 __func__, *idx, ev->u.logout_flashnode.host_no); 3000 __func__, idx, ev->u.logout_flashnode.host_no);
3008 err = -ENODEV; 3001 err = -ENODEV;
3009 goto put_host; 3002 goto put_host;
3010 } 3003 }
3011 3004
3012 dev = iscsi_find_flashnode_conn(fnode_sess, NULL, 3005 dev = iscsi_find_flashnode_conn(fnode_sess);
3013 iscsi_is_flashnode_conn_dev);
3014 if (!dev) { 3006 if (!dev) {
3015 err = -ENODEV; 3007 err = -ENODEV;
3016 goto put_host; 3008 goto put_sess;
3017 } 3009 }
3018 3010
3019 fnode_conn = iscsi_dev_to_flash_conn(dev); 3011 fnode_conn = iscsi_dev_to_flash_conn(dev);
3020 3012
3021 err = transport->logout_flashnode(fnode_sess, fnode_conn); 3013 err = transport->logout_flashnode(fnode_sess, fnode_conn);
3014 put_device(dev);
3015
3016put_sess:
3017 put_device(&fnode_sess->dev);
3022 3018
3023put_host: 3019put_host:
3024 scsi_host_put(shost); 3020 scsi_host_put(shost);