Skip to content

Commit 8526cb1

Browse files
Mike ChristieJames Bottomley
authored andcommitted
[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>
1 parent aa9f832 commit 8526cb1

File tree

3 files changed

+49
-55
lines changed

3 files changed

+49
-55
lines changed

drivers/scsi/qla4xxx/ql4_os.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5605,6 +5605,7 @@ static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,
56055605
ql4_printk(KERN_ERR, ha,
56065606
"%s: A non-persistent entry %s found\n",
56075607
__func__, dev->kobj.name);
5608+
put_device(dev);
56085609
goto exit_ddb_add;
56095610
}
56105611

@@ -6112,8 +6113,7 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
61126113
int parent_type, parent_index = 0xffff;
61136114
int rc = 0;
61146115

6115-
dev = iscsi_find_flashnode_conn(fnode_sess, NULL,
6116-
iscsi_is_flashnode_conn_dev);
6116+
dev = iscsi_find_flashnode_conn(fnode_sess);
61176117
if (!dev)
61186118
return -EIO;
61196119

@@ -6347,6 +6347,8 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
63476347
rc = -ENOSYS;
63486348
break;
63496349
}
6350+
6351+
put_device(dev);
63506352
return rc;
63516353
}
63526354

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,8 +1019,7 @@ static int flashnode_match_index(struct device *dev, void *data)
10191019
/**
10201020
* iscsi_get_flashnode_by_index -finds flashnode session entry by index
10211021
* @shost: pointer to host data
1022-
* @data: pointer to data containing value to use for comparison
1023-
* @fn: function pointer that does actual comparison
1022+
* @idx: index to match
10241023
*
10251024
* Finds the flashnode session object for the passed index
10261025
*
@@ -1029,13 +1028,13 @@ static int flashnode_match_index(struct device *dev, void *data)
10291028
* %NULL on failure
10301029
*/
10311030
static struct iscsi_bus_flash_session *
1032-
iscsi_get_flashnode_by_index(struct Scsi_Host *shost, void *data,
1033-
int (*fn)(struct device *dev, void *data))
1031+
iscsi_get_flashnode_by_index(struct Scsi_Host *shost, uint32_t idx)
10341032
{
10351033
struct iscsi_bus_flash_session *fnode_sess = NULL;
10361034
struct device *dev;
10371035

1038-
dev = device_find_child(&shost->shost_gendev, data, fn);
1036+
dev = device_find_child(&shost->shost_gendev, &idx,
1037+
flashnode_match_index);
10391038
if (dev)
10401039
fnode_sess = iscsi_dev_to_flash_session(dev);
10411040

@@ -1059,18 +1058,13 @@ struct device *
10591058
iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
10601059
int (*fn)(struct device *dev, void *data))
10611060
{
1062-
struct device *dev;
1063-
1064-
dev = device_find_child(&shost->shost_gendev, data, fn);
1065-
return dev;
1061+
return device_find_child(&shost->shost_gendev, data, fn);
10661062
}
10671063
EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess);
10681064

10691065
/**
10701066
* iscsi_find_flashnode_conn - finds flashnode connection entry
10711067
* @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
10741068
*
10751069
* Finds the flashnode connection object comparing the data passed using logic
10761070
* defined in passed function pointer
@@ -1080,14 +1074,10 @@ EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess);
10801074
* %NULL on failure
10811075
*/
10821076
struct device *
1083-
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess,
1084-
void *data,
1085-
int (*fn)(struct device *dev, void *data))
1077+
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess)
10861078
{
1087-
struct device *dev;
1088-
1089-
dev = device_find_child(&fnode_sess->dev, data, fn);
1090-
return dev;
1079+
return device_find_child(&fnode_sess->dev, NULL,
1080+
iscsi_is_flashnode_conn_dev);
10911081
}
10921082
EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn);
10931083

@@ -2808,7 +2798,7 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
28082798
struct iscsi_bus_flash_session *fnode_sess;
28092799
struct iscsi_bus_flash_conn *fnode_conn;
28102800
struct device *dev;
2811-
uint32_t *idx;
2801+
uint32_t idx;
28122802
int err = 0;
28132803

28142804
if (!transport->set_flashnode_param) {
@@ -2824,25 +2814,27 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
28242814
goto put_host;
28252815
}
28262816

2827-
idx = &ev->u.set_flashnode.flashnode_idx;
2828-
fnode_sess = iscsi_get_flashnode_by_index(shost, idx,
2829-
flashnode_match_index);
2817+
idx = ev->u.set_flashnode.flashnode_idx;
2818+
fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
28302819
if (!fnode_sess) {
28312820
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);
28332822
err = -ENODEV;
28342823
goto put_host;
28352824
}
28362825

2837-
dev = iscsi_find_flashnode_conn(fnode_sess, NULL,
2838-
iscsi_is_flashnode_conn_dev);
2826+
dev = iscsi_find_flashnode_conn(fnode_sess);
28392827
if (!dev) {
28402828
err = -ENODEV;
2841-
goto put_host;
2829+
goto put_sess;
28422830
}
28432831

28442832
fnode_conn = iscsi_dev_to_flash_conn(dev);
28452833
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);
28462838

28472839
put_host:
28482840
scsi_host_put(shost);
@@ -2891,7 +2883,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
28912883
{
28922884
struct Scsi_Host *shost;
28932885
struct iscsi_bus_flash_session *fnode_sess;
2894-
uint32_t *idx;
2886+
uint32_t idx;
28952887
int err = 0;
28962888

28972889
if (!transport->del_flashnode) {
@@ -2907,17 +2899,17 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
29072899
goto put_host;
29082900
}
29092901

2910-
idx = &ev->u.del_flashnode.flashnode_idx;
2911-
fnode_sess = iscsi_get_flashnode_by_index(shost, idx,
2912-
flashnode_match_index);
2902+
idx = ev->u.del_flashnode.flashnode_idx;
2903+
fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
29132904
if (!fnode_sess) {
29142905
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);
29162907
err = -ENODEV;
29172908
goto put_host;
29182909
}
29192910

29202911
err = transport->del_flashnode(fnode_sess);
2912+
put_device(&fnode_sess->dev);
29212913

29222914
put_host:
29232915
scsi_host_put(shost);
@@ -2933,7 +2925,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
29332925
struct iscsi_bus_flash_session *fnode_sess;
29342926
struct iscsi_bus_flash_conn *fnode_conn;
29352927
struct device *dev;
2936-
uint32_t *idx;
2928+
uint32_t idx;
29372929
int err = 0;
29382930

29392931
if (!transport->login_flashnode) {
@@ -2949,25 +2941,27 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
29492941
goto put_host;
29502942
}
29512943

2952-
idx = &ev->u.login_flashnode.flashnode_idx;
2953-
fnode_sess = iscsi_get_flashnode_by_index(shost, idx,
2954-
flashnode_match_index);
2944+
idx = ev->u.login_flashnode.flashnode_idx;
2945+
fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
29552946
if (!fnode_sess) {
29562947
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);
29582949
err = -ENODEV;
29592950
goto put_host;
29602951
}
29612952

2962-
dev = iscsi_find_flashnode_conn(fnode_sess, NULL,
2963-
iscsi_is_flashnode_conn_dev);
2953+
dev = iscsi_find_flashnode_conn(fnode_sess);
29642954
if (!dev) {
29652955
err = -ENODEV;
2966-
goto put_host;
2956+
goto put_sess;
29672957
}
29682958

29692959
fnode_conn = iscsi_dev_to_flash_conn(dev);
29702960
err = transport->login_flashnode(fnode_sess, fnode_conn);
2961+
put_device(dev);
2962+
2963+
put_sess:
2964+
put_device(&fnode_sess->dev);
29712965

29722966
put_host:
29732967
scsi_host_put(shost);
@@ -2983,7 +2977,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
29832977
struct iscsi_bus_flash_session *fnode_sess;
29842978
struct iscsi_bus_flash_conn *fnode_conn;
29852979
struct device *dev;
2986-
uint32_t *idx;
2980+
uint32_t idx;
29872981
int err = 0;
29882982

29892983
if (!transport->logout_flashnode) {
@@ -2999,26 +2993,28 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
29992993
goto put_host;
30002994
}
30012995

3002-
idx = &ev->u.logout_flashnode.flashnode_idx;
3003-
fnode_sess = iscsi_get_flashnode_by_index(shost, idx,
3004-
flashnode_match_index);
2996+
idx = ev->u.logout_flashnode.flashnode_idx;
2997+
fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
30052998
if (!fnode_sess) {
30062999
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);
30083001
err = -ENODEV;
30093002
goto put_host;
30103003
}
30113004

3012-
dev = iscsi_find_flashnode_conn(fnode_sess, NULL,
3013-
iscsi_is_flashnode_conn_dev);
3005+
dev = iscsi_find_flashnode_conn(fnode_sess);
30143006
if (!dev) {
30153007
err = -ENODEV;
3016-
goto put_host;
3008+
goto put_sess;
30173009
}
30183010

30193011
fnode_conn = iscsi_dev_to_flash_conn(dev);
30203012

30213013
err = transport->logout_flashnode(fnode_sess, fnode_conn);
3014+
put_device(dev);
3015+
3016+
put_sess:
3017+
put_device(&fnode_sess->dev);
30223018

30233019
put_host:
30243020
scsi_host_put(shost);

include/scsi/scsi_transport_iscsi.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,10 @@ iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess);
471471
extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost);
472472
extern int iscsi_flashnode_bus_match(struct device *dev,
473473
struct device_driver *drv);
474-
extern int iscsi_is_flashnode_conn_dev(struct device *dev, void *data);
475-
476474
extern struct device *
477475
iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
478476
int (*fn)(struct device *dev, void *data));
479-
480477
extern struct device *
481-
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess,
482-
void *data,
483-
int (*fn)(struct device *dev, void *data));
478+
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);
479+
484480
#endif

0 commit comments

Comments
 (0)