diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2013-05-06 13:06:56 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-10 10:47:53 -0400 |
commit | 8526cb114f771851d84425d85d8735a6e0816ba2 (patch) | |
tree | dabc65e70ea5ca635f9fae207da3e717f7a2bf87 /drivers/scsi | |
parent | aa9f8328fc51460e15da129caf622b6560fa8c99 (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.c | 6 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 90 |
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 | */ |
1031 | static struct iscsi_bus_flash_session * | 1030 | static struct iscsi_bus_flash_session * |
1032 | iscsi_get_flashnode_by_index(struct Scsi_Host *shost, void *data, | 1031 | iscsi_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 * | |||
1059 | iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, | 1058 | iscsi_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 | } |
1067 | EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess); | 1063 | EXPORT_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 | */ |
1082 | struct device * | 1076 | struct device * |
1083 | iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, | 1077 | iscsi_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 | } |
1092 | EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn); | 1082 | EXPORT_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 | |||
2836 | put_sess: | ||
2837 | put_device(&fnode_sess->dev); | ||
2846 | 2838 | ||
2847 | put_host: | 2839 | put_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 | ||
2922 | put_host: | 2914 | put_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 | |||
2963 | put_sess: | ||
2964 | put_device(&fnode_sess->dev); | ||
2971 | 2965 | ||
2972 | put_host: | 2966 | put_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 | |||
3016 | put_sess: | ||
3017 | put_device(&fnode_sess->dev); | ||
3022 | 3018 | ||
3023 | put_host: | 3019 | put_host: |
3024 | scsi_host_put(shost); | 3020 | scsi_host_put(shost); |