[RFC 0/9] Make iscsid-kernel communications namespace-aware

15 views
Skip to first unread message

Lee Duncan

unread,
Feb 8, 2023, 12:41:02 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
From: Lee Duncan <ldu...@suse.com>

This is a request for comment on a set of patches that
modify the kernel iSCSI initiator communications so that
they are namespace-aware. The goal is to allow multiple
iSCSI daemon (iscsid) to run at once as long as they
are in separate namespaces, and so that iscsid can
run in containers.

Comments and suggestions are more than welcome. I do not
expect that this code is production-ready yet, and
networking isn't my strongest suit (yet).

These patches were originally posted in 2015 by Chris
Leech. There were some issues at the time about how
to handle namespaces going away. I hope to address
any issues raised with this patchset and then
to merge these changes upstream to address working
in working in containers.

My contribution thus far has been to update these patches
to work with the current upstream kernel.

Chris Leech/Lee Duncan (9):
iscsi: create per-net iscsi netlink kernel sockets
iscsi: associate endpoints with a host
iscsi: sysfs filtering by network namespace
iscsi: make all iSCSI netlink multicast namespace aware
iscsi: set netns for iscsi_tcp hosts
iscsi: check net namespace for all iscsi lookup
iscsi: convert flashnode devices from bus to class
iscsi: rename iscsi_bus_flash_* to iscsi_flash_*
iscsi: filter flashnode sysfs by net namespace

drivers/infiniband/ulp/iser/iscsi_iser.c | 7 +-
drivers/scsi/be2iscsi/be_iscsi.c | 6 +-
drivers/scsi/bnx2i/bnx2i_iscsi.c | 6 +-
drivers/scsi/cxgbi/libcxgbi.c | 6 +-
drivers/scsi/iscsi_tcp.c | 7 +
drivers/scsi/qedi/qedi_iscsi.c | 6 +-
drivers/scsi/qla4xxx/ql4_os.c | 64 +--
drivers/scsi/scsi_transport_iscsi.c | 625 ++++++++++++++++-------
include/scsi/scsi_transport_iscsi.h | 63 ++-
9 files changed, 537 insertions(+), 253 deletions(-)

--
2.39.1

Lee Duncan

unread,
Feb 8, 2023, 12:41:03 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
From: Lee Duncan <ldu...@suse.com>

Right now the iscsi_endpoint is only linked to a connection once that
connection has been established. For net namespace filtering of the
sysfs objects, associate an endpoint with the host that it was
allocated for when it is created.

Signed-off-by: Chris Leech <cle...@redhat.com>
Signed-off-by: Lee Duncan <ldu...@suse.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 2 +-
drivers/scsi/be2iscsi/be_iscsi.c | 2 +-
drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +-
drivers/scsi/cxgbi/libcxgbi.c | 2 +-
drivers/scsi/qedi/qedi_iscsi.c | 2 +-
drivers/scsi/qla4xxx/ql4_os.c | 2 +-
drivers/scsi/scsi_transport_iscsi.c | 3 ++-
include/scsi/scsi_transport_iscsi.h | 6 +++++-
8 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 620ae5b2d80d..d38c909b462f 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -802,7 +802,7 @@ static struct iscsi_endpoint *iscsi_iser_ep_connect(struct Scsi_Host *shost,
struct iser_conn *iser_conn;
struct iscsi_endpoint *ep;

- ep = iscsi_create_endpoint(0);
+ ep = iscsi_create_endpoint(shost, 0);
if (!ep)
return ERR_PTR(-ENOMEM);

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 8aeaddc93b16..c893d193f5ef 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1168,7 +1168,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
return ERR_PTR(ret);
}

- ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
+ ep = iscsi_create_endpoint(shost, sizeof(struct beiscsi_endpoint));
if (!ep) {
ret = -ENOMEM;
return ERR_PTR(ret);
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index a3c800e04a2e..ac63e93e07c6 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -384,7 +384,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba)
struct bnx2i_endpoint *bnx2i_ep;
u32 ec_div;

- ep = iscsi_create_endpoint(sizeof(*bnx2i_ep));
+ ep = iscsi_create_endpoint(hba->shost, sizeof(*bnx2i_ep));
if (!ep) {
printk(KERN_ERR "bnx2i: Could not allocate ep\n");
return NULL;
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index af281e271f88..94edf8e1fb0c 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -2926,7 +2926,7 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost,
goto release_conn;
}

- ep = iscsi_create_endpoint(sizeof(*cep));
+ ep = iscsi_create_endpoint(shost, sizeof(*cep));
if (!ep) {
err = -ENOMEM;
pr_info("iscsi alloc ep, OOM.\n");
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 31ec429104e2..4baf1dbb8e92 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -931,7 +931,7 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
return ERR_PTR(-ENXIO);
}

- ep = iscsi_create_endpoint(sizeof(struct qedi_endpoint));
+ ep = iscsi_create_endpoint(shost, sizeof(struct qedi_endpoint));
if (!ep) {
QEDI_ERR(&qedi->dbg_ctx, "endpoint create fail\n");
ret = -ENOMEM;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 005502125b27..acebf9c92c04 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1717,7 +1717,7 @@ qla4xxx_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
}

ha = iscsi_host_priv(shost);
- ep = iscsi_create_endpoint(sizeof(struct qla_endpoint));
+ ep = iscsi_create_endpoint(shost, sizeof(struct qla_endpoint));
if (!ep) {
ret = -ENOMEM;
return ERR_PTR(ret);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index be69cea9c6f8..86bafdb862a5 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -204,7 +204,7 @@ static struct attribute_group iscsi_endpoint_group = {
};

struct iscsi_endpoint *
-iscsi_create_endpoint(int dd_size)
+iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size)
{
struct iscsi_endpoint *ep;
int err, id;
@@ -230,6 +230,7 @@ iscsi_create_endpoint(int dd_size)

ep->id = id;
ep->dev.class = &iscsi_endpoint_class;
+ ep->dev.parent = &shost->shost_gendev;
dev_set_name(&ep->dev, "ep-%d", id);
err = device_register(&ep->dev);
if (err)
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 34c03707fb6e..268ccaac1c05 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -287,6 +287,9 @@ struct iscsi_cls_session {
#define iscsi_session_to_shost(_session) \
dev_to_shost(_session->dev.parent)

+#define iscsi_endpoint_to_shost(_ep) \
+ dev_to_shost(_ep->dev.parent)
+
#define starget_to_session(_stgt) \
iscsi_dev_to_session(_stgt->dev.parent)

@@ -462,7 +465,8 @@ extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
extern void iscsi_unblock_session(struct iscsi_cls_session *session);
extern void iscsi_block_session(struct iscsi_cls_session *session);
-extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
+extern struct iscsi_endpoint *iscsi_create_endpoint(struct Scsi_Host *shost,
+ int dd_size);
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
extern void iscsi_put_endpoint(struct iscsi_endpoint *ep);
--
2.39.1

Lee Duncan

unread,
Feb 8, 2023, 12:41:04 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
From: Lee Duncan <ldu...@suse.com>

This lets iscsi_tcp operate in multiple namespaces. It uses current
during session creation to find the net namespace, but it might be
better to manage to pass it along from the iscsi netlink socket.

Signed-off-by: Chris Leech <cle...@redhat.com>
Signed-off-by: Lee Duncan <ldu...@suse.com>
---
drivers/scsi/iscsi_tcp.c | 7 +++++++
drivers/scsi/scsi_transport_iscsi.c | 7 ++++++-
include/scsi/scsi_transport_iscsi.h | 1 +
3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 0454d94e8cf0..22e7a5c93627 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1069,6 +1069,11 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
return 0;
}

+static struct net *iscsi_sw_tcp_netns(struct Scsi_Host *shost)
+{
+ return current->nsproxy->net_ns;
+}
+
static struct scsi_host_template iscsi_sw_tcp_sht = {
.module = THIS_MODULE,
.name = "iSCSI Initiator over TCP/IP",
@@ -1124,6 +1129,8 @@ static struct iscsi_transport iscsi_sw_tcp_transport = {
.alloc_pdu = iscsi_sw_tcp_pdu_alloc,
/* recovery */
.session_recovery_timedout = iscsi_session_recovery_timedout,
+ /* net namespace */
+ .get_netns = iscsi_sw_tcp_netns,
};

static int __init iscsi_sw_tcp_init(void)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 230b43d34c5f..996a9abfa1f5 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1600,10 +1600,15 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
{
struct Scsi_Host *shost = dev_to_shost(dev);
struct iscsi_cls_host *ihost = shost->shost_data;
+ struct iscsi_internal *priv = to_iscsi_internal(shost->transportt);
+ struct iscsi_transport *transport = priv->iscsi_transport;

memset(ihost, 0, sizeof(*ihost));
mutex_init(&ihost->mutex);
- ihost->netns = &init_net;
+ if (transport->get_netns)
+ ihost->netns = transport->get_netns(shost);
+ else
+ ihost->netns = &init_net;

iscsi_bsg_host_add(shost, ihost);
/* ignore any bsg add error - we just can't do sgio */
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index af0c5a15f316..f8885d0c37d8 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -156,6 +156,7 @@ struct iscsi_transport {
int (*logout_flashnode_sid) (struct iscsi_cls_session *cls_sess);
int (*get_host_stats) (struct Scsi_Host *shost, char *buf, int len);
u8 (*check_protection)(struct iscsi_task *task, sector_t *sector);
+ struct net *(*get_netns)(struct Scsi_Host *shost);
};

/*
--
2.39.1

Lee Duncan

unread,
Feb 8, 2023, 12:41:04 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
From: Lee Duncan <ldu...@suse.com>

The flashnode session and connection devices should be filtered by net
namespace along with the iscsi_host, but we can't do that with a bus
device. As these don't use any of the bus matching functionality, they
make more sense as a class device anyway.

Signed-off-by: Chris Leech <cle...@redhat.com>
Signed-off-by: Lee Duncan <ldu...@suse.com>
---
drivers/scsi/qla4xxx/ql4_os.c | 2 +-
drivers/scsi/scsi_transport_iscsi.c | 36 ++++++++++++-----------------
include/scsi/scsi_transport_iscsi.h | 2 ++
3 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 390b89bdec8f..18e382b6be18 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -7185,7 +7185,7 @@ static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data)
{
struct iscsi_bus_flash_session *fnode_sess;

- if (!iscsi_flashnode_bus_match(dev, NULL))
+ if (!iscsi_is_flashnode_session_dev(dev))
return 0;

fnode_sess = iscsi_dev_to_flash_session(dev);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 008adde4dc51..c065763b1fc6 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1060,6 +1060,12 @@ static const struct device_type iscsi_flashnode_sess_dev_type = {
.release = iscsi_flashnode_sess_release,
};

+bool iscsi_is_flashnode_session_dev(struct device *dev)
+{
+ return dev->type == &iscsi_flashnode_sess_dev_type;
+}
+EXPORT_SYMBOL_GPL(iscsi_is_flashnode_session_dev);
+
/* flash node connection attrs show */
#define iscsi_flashnode_conn_attr_show(type, name, param) \
static ssize_t \
@@ -1246,20 +1252,8 @@ static const struct device_type iscsi_flashnode_conn_dev_type = {
.release = iscsi_flashnode_conn_release,
};

-static struct bus_type iscsi_flashnode_bus;
-
-int iscsi_flashnode_bus_match(struct device *dev,
- struct device_driver *drv)
-{
- if (dev->bus == &iscsi_flashnode_bus)
- return 1;
- return 0;
-}
-EXPORT_SYMBOL_GPL(iscsi_flashnode_bus_match);
-
-static struct bus_type iscsi_flashnode_bus = {
+static struct class iscsi_flashnode_bus = {
.name = "iscsi_flashnode",
- .match = &iscsi_flashnode_bus_match,
};

/**
@@ -1290,7 +1284,7 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
fnode_sess->transport = transport;
fnode_sess->target_id = index;
fnode_sess->dev.type = &iscsi_flashnode_sess_dev_type;
- fnode_sess->dev.bus = &iscsi_flashnode_bus;
+ fnode_sess->dev.class = &iscsi_flashnode_bus;
fnode_sess->dev.parent = &shost->shost_gendev;
dev_set_name(&fnode_sess->dev, "flashnode_sess-%u:%u",
shost->host_no, index);
@@ -1338,7 +1332,7 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,

fnode_conn->transport = transport;
fnode_conn->dev.type = &iscsi_flashnode_conn_dev_type;
- fnode_conn->dev.bus = &iscsi_flashnode_bus;
+ fnode_conn->dev.class = &iscsi_flashnode_bus;
fnode_conn->dev.parent = &fnode_sess->dev;
dev_set_name(&fnode_conn->dev, "flashnode_conn-%u:%u:0",
shost->host_no, fnode_sess->target_id);
@@ -1371,7 +1365,7 @@ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
*/
static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
{
- return dev->bus == &iscsi_flashnode_bus;
+ return dev->type == &iscsi_flashnode_conn_dev_type;
}

static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn)
@@ -1385,7 +1379,7 @@ static int flashnode_match_index(struct device *dev, void *data)
struct iscsi_bus_flash_session *fnode_sess = NULL;
int ret = 0;

- if (!iscsi_flashnode_bus_match(dev, NULL))
+ if (dev->type != &iscsi_flashnode_sess_dev_type)
goto exit_match_index;

fnode_sess = iscsi_dev_to_flash_session(dev);
@@ -1491,7 +1485,7 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_flashnode_sess);

static int iscsi_iter_destroy_flashnode_fn(struct device *dev, void *data)
{
- if (!iscsi_flashnode_bus_match(dev, NULL))
+ if (dev->type != &iscsi_flashnode_sess_dev_type)
return 0;

iscsi_destroy_flashnode_sess(iscsi_dev_to_flash_session(dev));
@@ -5200,7 +5194,7 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_conn_class;

- err = bus_register(&iscsi_flashnode_bus);
+ err = class_register(&iscsi_flashnode_bus);
if (err)
goto unregister_session_class;

@@ -5223,7 +5217,7 @@ static __init int iscsi_transport_init(void)
unregister_pernet_subsys:
unregister_pernet_subsys(&iscsi_net_ops);
unregister_flashnode_bus:
- bus_unregister(&iscsi_flashnode_bus);
+ class_unregister(&iscsi_flashnode_bus);
unregister_session_class:
transport_class_unregister(&iscsi_session_class);
unregister_conn_class:
@@ -5243,7 +5237,7 @@ static void __exit iscsi_transport_exit(void)
{
destroy_workqueue(iscsi_conn_cleanup_workq);
unregister_pernet_subsys(&iscsi_net_ops);
- bus_unregister(&iscsi_flashnode_bus);
+ class_unregister(&iscsi_flashnode_bus);
transport_class_unregister(&iscsi_connection_class);
transport_class_unregister(&iscsi_session_class);
transport_class_unregister(&iscsi_host_class);
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 9ac1bc133693..580f06d1479b 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -512,6 +512,8 @@ iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
extern struct device *
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);

+extern bool iscsi_is_flashnode_session_dev(struct device *dev);
+
extern char *
iscsi_get_ipaddress_state_name(enum iscsi_ipaddress_state port_state);
extern char *iscsi_get_router_state_name(enum iscsi_router_state router_state);
--
2.39.1

Lee Duncan

unread,
Feb 8, 2023, 12:41:04 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
From: Lee Duncan <ldu...@suse.com>

All internal lookups of iSCSI transport objects need to be filtered by
net namespace.

Signed-off-by: Chris Leech <cle...@redhat.com>
Signed-off-by: Lee Duncan <ldu...@suse.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 5 +-
drivers/scsi/be2iscsi/be_iscsi.c | 4 +-
drivers/scsi/bnx2i/bnx2i_iscsi.c | 4 +-
drivers/scsi/cxgbi/libcxgbi.c | 4 +-
drivers/scsi/qedi/qedi_iscsi.c | 4 +-
drivers/scsi/qla4xxx/ql4_os.c | 8 +-
drivers/scsi/scsi_transport_iscsi.c | 202 ++++++++++++++---------
include/scsi/scsi_transport_iscsi.h | 5 +-
8 files changed, 149 insertions(+), 87 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index d38c909b462f..348bafb55e51 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -456,15 +456,18 @@ static int iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
struct iscsi_conn *conn = cls_conn->dd_data;
struct iser_conn *iser_conn;
struct iscsi_endpoint *ep;
+ struct net *net;
int error;

error = iscsi_conn_bind(cls_session, cls_conn, is_leading);
if (error)
return error;

+
/* the transport ep handle comes from user space so it must be
* verified against the global ib connections list */
- ep = iscsi_lookup_endpoint(transport_eph);
+ net = iscsi_sess_net(cls_session);
+ ep = iscsi_lookup_endpoint(net, transport_eph);
if (!ep) {
iser_err("can't bind eph %llx\n",
(unsigned long long)transport_eph);
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c893d193f5ef..10329ed6a9a8 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -183,8 +183,10 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
struct iscsi_endpoint *ep;
uint16_t cri_index;
int rc = 0;
+ struct net *net;

- ep = iscsi_lookup_endpoint(transport_fd);
+ net = iscsi_sess_net(cls_session);
+ ep = iscsi_lookup_endpoint(net, transport_fd);
if (!ep)
return -EINVAL;

diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index ac63e93e07c6..e889c5585c87 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1411,9 +1411,11 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
struct bnx2i_hba *hba = iscsi_host_priv(shost);
struct bnx2i_endpoint *bnx2i_ep;
struct iscsi_endpoint *ep;
+ struct net *net;
int ret_code;

- ep = iscsi_lookup_endpoint(transport_fd);
+ net = iscsi_sess_net(cls_session);
+ ep = iscsi_lookup_endpoint(net, transport_fd);
if (!ep)
return -EINVAL;
/*
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 94edf8e1fb0c..b492b57dbb2a 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -2676,9 +2676,11 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
struct iscsi_endpoint *ep;
struct cxgbi_endpoint *cep;
struct cxgbi_sock *csk;
+ struct net *net;
int err;

- ep = iscsi_lookup_endpoint(transport_eph);
+ net = iscsi_sess_net(cls_session);
+ ep = iscsi_lookup_endpoint(net, transport_eph);
if (!ep)
return -EINVAL;

diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 4baf1dbb8e92..fc3406e6f82c 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -389,8 +389,10 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,
struct qedi_endpoint *qedi_ep;
struct iscsi_endpoint *ep;
int rc = 0;
+ struct net *net;

- ep = iscsi_lookup_endpoint(transport_fd);
+ net = iscsi_sess_net(cls_session);
+ ep = iscsi_lookup_endpoint(net, transport_fd);
if (!ep)
return -EINVAL;

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index acebf9c92c04..390b89bdec8f 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -3217,6 +3217,7 @@ static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session,
struct ddb_entry *ddb_entry;
struct scsi_qla_host *ha;
struct iscsi_session *sess;
+ struct net *net;

sess = cls_session->dd_data;
ddb_entry = sess->dd_data;
@@ -3225,11 +3226,12 @@ static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session,
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: sid = %d, cid = %d\n", __func__,
cls_session->sid, cls_conn->cid));

- if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
- return -EINVAL;
- ep = iscsi_lookup_endpoint(transport_fd);
+ net = iscsi_sess_net(cls_session);
+ ep = iscsi_lookup_endpoint(net, transport_fd);
if (!ep)
return -EINVAL;
+ if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
+ return -EINVAL;
conn = cls_conn->dd_data;
qla_conn = conn->dd_data;
qla_conn->qla_ep = ep->dd_data;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 996a9abfa1f5..008adde4dc51 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -301,12 +301,16 @@ EXPORT_SYMBOL_GPL(iscsi_put_endpoint);
*
* Caller must do a iscsi_put_endpoint.
*/
-struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
+struct iscsi_endpoint *iscsi_lookup_endpoint(struct net *net, u64 handle)
{
struct iscsi_endpoint *ep;
+ struct net *ns;

mutex_lock(&iscsi_ep_idr_mutex);
ep = idr_find(&iscsi_ep_idr, handle);
+ ns = iscsi_endpoint_net(ep);
+ if (ns != net)
+ ep = NULL;
if (!ep)
goto unlock;

@@ -1654,13 +1658,14 @@ static DECLARE_TRANSPORT_CLASS_NS(iscsi_host_class,
&net_ns_type_operations,
iscsi_host_namespace);

-static struct net *iscsi_sess_net(struct iscsi_cls_session *cls_session)
+struct net *iscsi_sess_net(struct iscsi_cls_session *cls_session)
{
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
struct iscsi_cls_host *ihost = shost->shost_data;

return iscsi_host_net(ihost);
}
+EXPORT_SYMBOL_GPL(iscsi_sess_net);

static const void *iscsi_sess_namespace(const struct device *dev)
{
@@ -1721,14 +1726,19 @@ static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
/*
* Returns the matching session to a given sid
*/
-static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
+static struct iscsi_cls_session *iscsi_session_lookup(struct net *net,
+ uint32_t sid)
{
unsigned long flags;
struct iscsi_cls_session *sess;
+ struct net *ns;

spin_lock_irqsave(&sesslock, flags);
list_for_each_entry(sess, &sesslist, sess_list) {
if (sess->sid == sid) {
+ ns = iscsi_sess_net(sess);
+ if (ns != net)
+ continue;
spin_unlock_irqrestore(&sesslock, flags);
return sess;
}
@@ -1740,14 +1750,19 @@ static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
/*
* Returns the matching connection to a given sid / cid tuple
*/
-static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
+static struct iscsi_cls_conn *iscsi_conn_lookup(struct net *net, uint32_t sid,
+ uint32_t cid)
{
unsigned long flags;
struct iscsi_cls_conn *conn;
+ struct net *ns;

spin_lock_irqsave(&connlock, flags);
list_for_each_entry(conn, &connlist, conn_list) {
if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
+ ns = iscsi_conn_net(conn);
+ if (ns != net)
+ continue;
spin_unlock_irqrestore(&connlock, flags);
return conn;
}
@@ -2971,7 +2986,7 @@ iscsi_if_get_stats(struct net *net, struct iscsi_transport *transport, struct nl
if (!priv)
return -EINVAL;

- conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
+ conn = iscsi_conn_lookup(net, ev->u.get_stats.sid, ev->u.get_stats.cid);
if (!conn)
return -EEXIST;

@@ -3113,12 +3128,13 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
}

static int
-iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_if_create_conn(struct net *net, struct iscsi_transport *transport,
+ struct iscsi_uevent *ev)
{
struct iscsi_cls_conn *conn;
struct iscsi_cls_session *session;

- session = iscsi_session_lookup(ev->u.c_conn.sid);
+ session = iscsi_session_lookup(net, ev->u.c_conn.sid);
if (!session) {
printk(KERN_ERR "iscsi: invalid session %d.\n",
ev->u.c_conn.sid);
@@ -3140,11 +3156,12 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
}

static int
-iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_if_destroy_conn(struct net *net, struct iscsi_transport *transport,
+ struct iscsi_uevent *ev)
{
struct iscsi_cls_conn *conn;

- conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
+ conn = iscsi_conn_lookup(net, ev->u.d_conn.sid, ev->u.d_conn.cid);
if (!conn)
return -EINVAL;

@@ -3158,7 +3175,8 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev
}

static int
-iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_if_set_param(struct net *net, struct iscsi_transport *transport,
+ struct iscsi_uevent *ev)
{
char *data = (char*)ev + sizeof(*ev);
struct iscsi_cls_conn *conn;
@@ -3168,8 +3186,8 @@ iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
if (ev->u.set_param.len > PAGE_SIZE)
return -EINVAL;

- session = iscsi_session_lookup(ev->u.set_param.sid);
- conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
+ session = iscsi_session_lookup(net, ev->u.set_param.sid);
+ conn = iscsi_conn_lookup(net, ev->u.set_param.sid, ev->u.set_param.cid);
if (!conn || !session)
return -EINVAL;

@@ -3192,7 +3210,21 @@ iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
return err;
}

-static int iscsi_if_ep_connect(struct iscsi_transport *transport,
+static struct Scsi_Host *iscsi_host_lookup(struct net *net,
+ unsigned short hostnum)
+{
+ struct Scsi_Host *shost;
+
+ shost = scsi_host_lookup(hostnum);
+ if (shost && iscsi_host_net(shost->shost_data) != net) {
+ scsi_host_put(shost);
+ shost = NULL;
+ }
+ return shost;
+}
+
+static int iscsi_if_ep_connect(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev, int msg_type)
{
struct iscsi_endpoint *ep;
@@ -3204,7 +3236,8 @@ static int iscsi_if_ep_connect(struct iscsi_transport *transport,
return -EINVAL;

if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) {
- shost = scsi_host_lookup(ev->u.ep_connect_through_host.host_no);
+ shost = iscsi_host_lookup(net,
+ ev->u.ep_connect_through_host.host_no);
if (!shost) {
printk(KERN_ERR "ep connect failed. Could not find "
"host no %u\n",
@@ -3229,7 +3262,8 @@ static int iscsi_if_ep_connect(struct iscsi_transport *transport,
return err;
}

-static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+static int iscsi_if_ep_disconnect(struct net *net,
+ struct iscsi_transport *transport,
u64 ep_handle)
{
struct iscsi_cls_conn *conn;
@@ -3238,7 +3272,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
if (!transport->ep_disconnect)
return -EINVAL;

- ep = iscsi_lookup_endpoint(ep_handle);
+ ep = iscsi_lookup_endpoint(net, ep_handle);
if (!ep)
return -EINVAL;

@@ -3261,7 +3295,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
}

static int
-iscsi_if_transport_ep(struct iscsi_transport *transport,
+iscsi_if_transport_ep(struct net *net, struct iscsi_transport *transport,
struct iscsi_uevent *ev, int msg_type)
{
struct iscsi_endpoint *ep;
@@ -3270,13 +3304,13 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
switch (msg_type) {
case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
- rc = iscsi_if_ep_connect(transport, ev, msg_type);
+ rc = iscsi_if_ep_connect(net, transport, ev, msg_type);
break;
case ISCSI_UEVENT_TRANSPORT_EP_POLL:
if (!transport->ep_poll)
return -EINVAL;

- ep = iscsi_lookup_endpoint(ev->u.ep_poll.ep_handle);
+ ep = iscsi_lookup_endpoint(net, ev->u.ep_poll.ep_handle);
if (!ep)
return -EINVAL;

@@ -3285,7 +3319,7 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
iscsi_put_endpoint(ep);
break;
case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
- rc = iscsi_if_ep_disconnect(transport,
+ rc = iscsi_if_ep_disconnect(net, transport,
ev->u.ep_disconnect.ep_handle);
break;
}
@@ -3293,7 +3327,7 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
}

static int
-iscsi_tgt_dscvr(struct iscsi_transport *transport,
+iscsi_tgt_dscvr(struct net *net, struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
@@ -3303,7 +3337,7 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
if (!transport->tgt_dscvr)
return -EINVAL;

- shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no);
+ shost = iscsi_host_lookup(net, ev->u.tgt_dscvr.host_no);
if (!shost) {
printk(KERN_ERR "target discovery could not find host no %u\n",
ev->u.tgt_dscvr.host_no);
@@ -3319,7 +3353,7 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
}

static int
-iscsi_set_host_param(struct iscsi_transport *transport,
+iscsi_set_host_param(struct net *net, struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
char *data = (char*)ev + sizeof(*ev);
@@ -3332,7 +3366,7 @@ iscsi_set_host_param(struct iscsi_transport *transport,
if (ev->u.set_host_param.len > PAGE_SIZE)
return -EINVAL;

- shost = scsi_host_lookup(ev->u.set_host_param.host_no);
+ shost = iscsi_host_lookup(net, ev->u.set_host_param.host_no);
if (!shost) {
printk(KERN_ERR "set_host_param could not find host no %u\n",
ev->u.set_host_param.host_no);
@@ -3346,7 +3380,8 @@ iscsi_set_host_param(struct iscsi_transport *transport,
}

static int
-iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_set_path(struct net *net, struct iscsi_transport *transport,
+ struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
struct iscsi_path *params;
@@ -3355,7 +3390,7 @@ iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
if (!transport->set_path)
return -ENOSYS;

- shost = scsi_host_lookup(ev->u.set_path.host_no);
+ shost = iscsi_host_lookup(net, ev->u.set_path.host_no);
if (!shost) {
printk(KERN_ERR "set path could not find host no %u\n",
ev->u.set_path.host_no);
@@ -3388,7 +3423,7 @@ static int iscsi_session_has_conns(int sid)
}

static int
-iscsi_set_iface_params(struct iscsi_transport *transport,
+iscsi_set_iface_params(struct net *net, struct iscsi_transport *transport,
struct iscsi_uevent *ev, uint32_t len)
{
char *data = (char *)ev + sizeof(*ev);
@@ -3398,7 +3433,7 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
if (!transport->set_iface_param)
return -ENOSYS;

- shost = scsi_host_lookup(ev->u.set_iface_params.host_no);
+ shost = iscsi_host_lookup(net, ev->u.set_iface_params.host_no);
if (!shost) {
printk(KERN_ERR "set_iface_params could not find host no %u\n",
ev->u.set_iface_params.host_no);
@@ -3411,7 +3446,8 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
}

static int
-iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_send_ping(struct net *net, struct iscsi_transport *transport,
+ struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
struct sockaddr *dst_addr;
@@ -3420,7 +3456,7 @@ iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
if (!transport->send_ping)
return -ENOSYS;

- shost = scsi_host_lookup(ev->u.iscsi_ping.host_no);
+ shost = iscsi_host_lookup(net, ev->u.iscsi_ping.host_no);
if (!shost) {
printk(KERN_ERR "iscsi_ping could not find host no %u\n",
ev->u.iscsi_ping.host_no);
@@ -3462,7 +3498,7 @@ iscsi_get_chap(struct net *net, struct iscsi_transport *transport,
chap_buf_size = (ev->u.get_chap.num_entries * sizeof(*chap_rec));
len = nlmsg_total_size(sizeof(*ev) + chap_buf_size);

- shost = scsi_host_lookup(ev->u.get_chap.host_no);
+ shost = iscsi_host_lookup(net, ev->u.get_chap.host_no);
if (!shost) {
printk(KERN_ERR "%s: failed. Could not find host no %u\n",
__func__, ev->u.get_chap.host_no);
@@ -3507,7 +3543,7 @@ iscsi_get_chap(struct net *net, struct iscsi_transport *transport,
return err;
}

-static int iscsi_set_chap(struct iscsi_transport *transport,
+static int iscsi_set_chap(struct net *net, struct iscsi_transport *transport,
struct iscsi_uevent *ev, uint32_t len)
{
char *data = (char *)ev + sizeof(*ev);
@@ -3517,7 +3553,7 @@ static int iscsi_set_chap(struct iscsi_transport *transport,
if (!transport->set_chap)
return -ENOSYS;

- shost = scsi_host_lookup(ev->u.set_path.host_no);
+ shost = iscsi_host_lookup(net, ev->u.set_path.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.set_path.host_no);
@@ -3529,7 +3565,7 @@ static int iscsi_set_chap(struct iscsi_transport *transport,
return err;
}

-static int iscsi_delete_chap(struct iscsi_transport *transport,
+static int iscsi_delete_chap(struct net *net, struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
@@ -3538,7 +3574,7 @@ static int iscsi_delete_chap(struct iscsi_transport *transport,
if (!transport->delete_chap)
return -ENOSYS;

- shost = scsi_host_lookup(ev->u.delete_chap.host_no);
+ shost = iscsi_host_lookup(net, ev->u.delete_chap.host_no);
if (!shost) {
printk(KERN_ERR "%s could not find host no %u\n",
__func__, ev->u.delete_chap.host_no);
@@ -3574,7 +3610,8 @@ char *iscsi_get_discovery_parent_name(int parent_type)
}
EXPORT_SYMBOL_GPL(iscsi_get_discovery_parent_name);

-static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
+static int iscsi_set_flashnode_param(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev, uint32_t len)
{
char *data = (char *)ev + sizeof(*ev);
@@ -3590,7 +3627,7 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
goto exit_set_fnode;
}

- shost = scsi_host_lookup(ev->u.set_flashnode.host_no);
+ shost = iscsi_host_lookup(net, ev->u.set_flashnode.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.set_flashnode.host_no);
@@ -3627,7 +3664,8 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
return err;
}

-static int iscsi_new_flashnode(struct iscsi_transport *transport,
+static int iscsi_new_flashnode(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev, uint32_t len)
{
char *data = (char *)ev + sizeof(*ev);
@@ -3640,7 +3678,7 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport,
goto exit_new_fnode;
}

- shost = scsi_host_lookup(ev->u.new_flashnode.host_no);
+ shost = iscsi_host_lookup(net, ev->u.new_flashnode.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.new_flashnode.host_no);
@@ -3662,7 +3700,8 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport,
return err;
}

-static int iscsi_del_flashnode(struct iscsi_transport *transport,
+static int iscsi_del_flashnode(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
@@ -3675,7 +3714,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
goto exit_del_fnode;
}

- shost = scsi_host_lookup(ev->u.del_flashnode.host_no);
+ shost = iscsi_host_lookup(net, ev->u.del_flashnode.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.del_flashnode.host_no);
@@ -3702,7 +3741,8 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
return err;
}

-static int iscsi_login_flashnode(struct iscsi_transport *transport,
+static int iscsi_login_flashnode(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
@@ -3717,7 +3757,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
goto exit_login_fnode;
}

- shost = scsi_host_lookup(ev->u.login_flashnode.host_no);
+ shost = iscsi_host_lookup(net, ev->u.login_flashnode.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.login_flashnode.host_no);
@@ -3754,7 +3794,8 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
return err;
}

-static int iscsi_logout_flashnode(struct iscsi_transport *transport,
+static int iscsi_logout_flashnode(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
@@ -3769,7 +3810,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
goto exit_logout_fnode;
}

- shost = scsi_host_lookup(ev->u.logout_flashnode.host_no);
+ shost = iscsi_host_lookup(net, ev->u.logout_flashnode.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.logout_flashnode.host_no);
@@ -3807,7 +3848,8 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
return err;
}

-static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport,
+static int iscsi_logout_flashnode_sid(struct net *net,
+ struct iscsi_transport *transport,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
@@ -3819,7 +3861,7 @@ static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport,
goto exit_logout_sid;
}

- shost = scsi_host_lookup(ev->u.logout_flashnode_sid.host_no);
+ shost = iscsi_host_lookup(net, ev->u.logout_flashnode_sid.host_no);
if (!shost) {
pr_err("%s could not find host no %u\n",
__func__, ev->u.logout_flashnode.host_no);
@@ -3827,7 +3869,7 @@ static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport,
goto put_host;
}

- session = iscsi_session_lookup(ev->u.logout_flashnode_sid.sid);
+ session = iscsi_session_lookup(net, ev->u.logout_flashnode_sid.sid);
if (!session) {
pr_err("%s could not find session id %u\n",
__func__, ev->u.logout_flashnode_sid.sid);
@@ -3868,7 +3910,7 @@ iscsi_get_host_stats(struct net *net, struct iscsi_transport *transport,
host_stats_size = sizeof(struct iscsi_offload_host_stats);
len = nlmsg_total_size(sizeof(*ev) + host_stats_size);

- shost = scsi_host_lookup(ev->u.get_host_stats.host_no);
+ shost = iscsi_host_lookup(net, ev->u.get_host_stats.host_no);
if (!shost) {
pr_err("%s: failed. Could not find host no %u\n",
__func__, ev->u.get_host_stats.host_no);
@@ -3915,7 +3957,8 @@ iscsi_get_host_stats(struct net *net, struct iscsi_transport *transport,
return err;
}

-static int iscsi_if_transport_conn(struct iscsi_transport *transport,
+static int iscsi_if_transport_conn(struct net *net,
+ struct iscsi_transport *transport,
struct nlmsghdr *nlh)
{
struct iscsi_uevent *ev = nlmsg_data(nlh);
@@ -3927,11 +3970,11 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,

switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_CONN:
- return iscsi_if_create_conn(transport, ev);
+ return iscsi_if_create_conn(net, transport, ev);
case ISCSI_UEVENT_DESTROY_CONN:
- return iscsi_if_destroy_conn(transport, ev);
+ return iscsi_if_destroy_conn(net, transport, ev);
case ISCSI_UEVENT_STOP_CONN:
- conn = iscsi_conn_lookup(ev->u.stop_conn.sid,
+ conn = iscsi_conn_lookup(net, ev->u.stop_conn.sid,
ev->u.stop_conn.cid);
if (!conn)
return -EINVAL;
@@ -3948,14 +3991,14 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
*/
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_START_CONN:
- conn = iscsi_conn_lookup(ev->u.start_conn.sid,
+ conn = iscsi_conn_lookup(net, ev->u.start_conn.sid,
ev->u.start_conn.cid);
break;
case ISCSI_UEVENT_BIND_CONN:
- conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
+ conn = iscsi_conn_lookup(net, ev->u.b_conn.sid, ev->u.b_conn.cid);
break;
case ISCSI_UEVENT_SEND_PDU:
- conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
+ conn = iscsi_conn_lookup(net, ev->u.send_pdu.sid, ev->u.send_pdu.cid);
break;
}

@@ -3974,7 +4017,7 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,

switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_BIND_CONN:
- session = iscsi_session_lookup(ev->u.b_conn.sid);
+ session = iscsi_session_lookup(net, ev->u.b_conn.sid);
if (!session) {
err = -EINVAL;
break;
@@ -3989,7 +4032,7 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
if (ev->r.retcode || !transport->ep_connect)
break;

- ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph);
+ ep = iscsi_lookup_endpoint(net, ev->u.b_conn.transport_eph);
if (ep) {
ep->conn = conn;
conn->ep = ep;
@@ -4066,8 +4109,10 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
ev->u.c_session.cmds_max,
ev->u.c_session.queue_depth);
break;
+ /* MARK */
case ISCSI_UEVENT_CREATE_BOUND_SESSION:
- ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle);
+ ep = iscsi_lookup_endpoint(net,
+ ev->u.c_bound_session.ep_handle);
if (!ep) {
err = -EINVAL;
break;
@@ -4081,7 +4126,7 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
iscsi_put_endpoint(ep);
break;
case ISCSI_UEVENT_DESTROY_SESSION:
- session = iscsi_session_lookup(ev->u.d_session.sid);
+ session = iscsi_session_lookup(net, ev->u.d_session.sid);
if (!session)
err = -EINVAL;
else if (iscsi_session_has_conns(ev->u.d_session.sid))
@@ -4090,7 +4135,7 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
transport->destroy_session(session);
break;
case ISCSI_UEVENT_DESTROY_SESSION_ASYNC:
- session = iscsi_session_lookup(ev->u.d_session.sid);
+ session = iscsi_session_lookup(net, ev->u.d_session.sid);
if (!session)
err = -EINVAL;
else if (iscsi_session_has_conns(ev->u.d_session.sid))
@@ -4107,14 +4152,14 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
}
break;
case ISCSI_UEVENT_UNBIND_SESSION:
- session = iscsi_session_lookup(ev->u.d_session.sid);
+ session = iscsi_session_lookup(net, ev->u.d_session.sid);
if (session)
queue_work(session->workq, &session->unbind_work);
else
err = -EINVAL;
break;
case ISCSI_UEVENT_SET_PARAM:
- err = iscsi_if_set_param(transport, ev);
+ err = iscsi_if_set_param(net, transport, ev);
break;
case ISCSI_UEVENT_CREATE_CONN:
case ISCSI_UEVENT_DESTROY_CONN:
@@ -4122,7 +4167,7 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
case ISCSI_UEVENT_START_CONN:
case ISCSI_UEVENT_BIND_CONN:
case ISCSI_UEVENT_SEND_PDU:
- err = iscsi_if_transport_conn(transport, nlh);
+ err = iscsi_if_transport_conn(net, transport, nlh);
break;
case ISCSI_UEVENT_GET_STATS:
err = iscsi_if_get_stats(net, transport, nlh);
@@ -4131,53 +4176,54 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
case ISCSI_UEVENT_TRANSPORT_EP_POLL:
case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
- err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
+ err = iscsi_if_transport_ep(net, transport, ev,
+ nlh->nlmsg_type);
break;
case ISCSI_UEVENT_TGT_DSCVR:
- err = iscsi_tgt_dscvr(transport, ev);
+ err = iscsi_tgt_dscvr(net, transport, ev);
break;
case ISCSI_UEVENT_SET_HOST_PARAM:
- err = iscsi_set_host_param(transport, ev);
+ err = iscsi_set_host_param(net, transport, ev);
break;
case ISCSI_UEVENT_PATH_UPDATE:
- err = iscsi_set_path(transport, ev);
+ err = iscsi_set_path(net, transport, ev);
break;
case ISCSI_UEVENT_SET_IFACE_PARAMS:
- err = iscsi_set_iface_params(transport, ev,
+ err = iscsi_set_iface_params(net, transport, ev,
nlmsg_attrlen(nlh, sizeof(*ev)));
break;
case ISCSI_UEVENT_PING:
- err = iscsi_send_ping(transport, ev);
+ err = iscsi_send_ping(net, transport, ev);
break;
case ISCSI_UEVENT_GET_CHAP:
err = iscsi_get_chap(net, transport, nlh);
break;
case ISCSI_UEVENT_DELETE_CHAP:
- err = iscsi_delete_chap(transport, ev);
+ err = iscsi_delete_chap(net, transport, ev);
break;
case ISCSI_UEVENT_SET_FLASHNODE_PARAMS:
- err = iscsi_set_flashnode_param(transport, ev,
+ err = iscsi_set_flashnode_param(net, transport, ev,
nlmsg_attrlen(nlh,
sizeof(*ev)));
break;
case ISCSI_UEVENT_NEW_FLASHNODE:
- err = iscsi_new_flashnode(transport, ev,
+ err = iscsi_new_flashnode(net, transport, ev,
nlmsg_attrlen(nlh, sizeof(*ev)));
break;
case ISCSI_UEVENT_DEL_FLASHNODE:
- err = iscsi_del_flashnode(transport, ev);
+ err = iscsi_del_flashnode(net, transport, ev);
break;
case ISCSI_UEVENT_LOGIN_FLASHNODE:
- err = iscsi_login_flashnode(transport, ev);
+ err = iscsi_login_flashnode(net, transport, ev);
break;
case ISCSI_UEVENT_LOGOUT_FLASHNODE:
- err = iscsi_logout_flashnode(transport, ev);
+ err = iscsi_logout_flashnode(net, transport, ev);
break;
case ISCSI_UEVENT_LOGOUT_FLASHNODE_SID:
- err = iscsi_logout_flashnode_sid(transport, ev);
+ err = iscsi_logout_flashnode_sid(net, transport, ev);
break;
case ISCSI_UEVENT_SET_CHAP:
- err = iscsi_set_chap(transport, ev,
+ err = iscsi_set_chap(net, transport, ev,
nlmsg_attrlen(nlh, sizeof(*ev)));
break;
case ISCSI_UEVENT_GET_HOST_STATS:
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index f8885d0c37d8..9ac1bc133693 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -291,6 +291,8 @@ struct iscsi_cls_session {
#define iscsi_endpoint_to_shost(_ep) \
dev_to_shost(_ep->dev.parent)

+extern struct net *iscsi_sess_net(struct iscsi_cls_session *session);
+
#define starget_to_session(_stgt) \
iscsi_dev_to_session(_stgt->dev.parent)

@@ -470,7 +472,8 @@ extern void iscsi_block_session(struct iscsi_cls_session *session);
extern struct iscsi_endpoint *iscsi_create_endpoint(struct Scsi_Host *shost,
int dd_size);
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
-extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
+extern struct iscsi_endpoint *iscsi_lookup_endpoint(struct net *net,
+ u64 handle);
extern void iscsi_put_endpoint(struct iscsi_endpoint *ep);
extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd);
extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
--
2.39.1

Lee Duncan

unread,
Feb 8, 2023, 12:41:04 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
From: Lee Duncan <ldu...@suse.com>

These are cleanups after the bus to class conversion
for flashnode devices.

Signed-off-by: Chris Leech <cle...@redhat.com>
Signed-off-by: Lee Duncan <ldu...@suse.com>
---
drivers/scsi/qla4xxx/ql4_os.c | 52 +++++++-------
drivers/scsi/scsi_transport_iscsi.c | 102 ++++++++++++++--------------
include/scsi/scsi_transport_iscsi.h | 48 ++++++-------
3 files changed, 102 insertions(+), 100 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 18e382b6be18..8af6847773e3 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -168,20 +168,20 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
* iSCSI Flash DDB sysfs entry points
*/
static int
-qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn,
+qla4xxx_sysfs_ddb_set_param(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn,
void *data, int len);
static int
-qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
+qla4xxx_sysfs_ddb_get_param(struct iscsi_flash_session *fnode_sess,
int param, char *buf);
static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,
int len);
static int
-qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess);
-static int qla4xxx_sysfs_ddb_login(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn);
-static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn);
+qla4xxx_sysfs_ddb_delete(struct iscsi_flash_session *fnode_sess);
+static int qla4xxx_sysfs_ddb_login(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn);
+static int qla4xxx_sysfs_ddb_logout(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn);
static int qla4xxx_sysfs_ddb_logout_sid(struct iscsi_cls_session *cls_sess);

static struct qla4_8xxx_legacy_intr_set legacy_intr[] =
@@ -3494,8 +3494,8 @@ static int qla4xxx_task_xmit(struct iscsi_task *task)
return -ENOSYS;
}

-static int qla4xxx_copy_from_fwddb_param(struct iscsi_bus_flash_session *sess,
- struct iscsi_bus_flash_conn *conn,
+static int qla4xxx_copy_from_fwddb_param(struct iscsi_flash_session *sess,
+ struct iscsi_flash_conn *conn,
struct dev_db_entry *fw_ddb_entry)
{
unsigned long options = 0;
@@ -3636,8 +3636,8 @@ static int qla4xxx_copy_from_fwddb_param(struct iscsi_bus_flash_session *sess,
return rc;
}

-static int qla4xxx_copy_to_fwddb_param(struct iscsi_bus_flash_session *sess,
- struct iscsi_bus_flash_conn *conn,
+static int qla4xxx_copy_to_fwddb_param(struct iscsi_flash_session *sess,
+ struct iscsi_flash_conn *conn,
struct dev_db_entry *fw_ddb_entry)
{
uint16_t options;
@@ -7183,7 +7183,7 @@ static void qla4xxx_build_new_nt_list(struct scsi_qla_host *ha,
**/
static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data)
{
- struct iscsi_bus_flash_session *fnode_sess;
+ struct iscsi_flash_session *fnode_sess;

if (!iscsi_is_flashnode_session_dev(dev))
return 0;
@@ -7213,8 +7213,8 @@ static int qla4xxx_sysfs_ddb_tgt_create(struct scsi_qla_host *ha,
struct dev_db_entry *fw_ddb_entry,
uint16_t *idx, int user)
{
- struct iscsi_bus_flash_session *fnode_sess = NULL;
- struct iscsi_bus_flash_conn *fnode_conn = NULL;
+ struct iscsi_flash_session *fnode_sess = NULL;
+ struct iscsi_flash_conn *fnode_conn = NULL;
int rc = QLA_ERROR;

fnode_sess = iscsi_create_flashnode_sess(ha->host, *idx,
@@ -7353,8 +7353,8 @@ static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,
* This writes the contents of target ddb buffer to Flash with a valid cookie
* value in order to make the ddb entry persistent.
**/
-static int qla4xxx_sysfs_ddb_apply(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn)
+static int qla4xxx_sysfs_ddb_apply(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn)
{
struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
struct scsi_qla_host *ha = to_qla_host(shost);
@@ -7543,8 +7543,8 @@ static int qla4xxx_ddb_login_nt(struct scsi_qla_host *ha,
*
* This logs in to the specified target
**/
-static int qla4xxx_sysfs_ddb_login(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn)
+static int qla4xxx_sysfs_ddb_login(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn)
{
struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
struct scsi_qla_host *ha = to_qla_host(shost);
@@ -7727,8 +7727,8 @@ static int qla4xxx_sysfs_ddb_logout_sid(struct iscsi_cls_session *cls_sess)
*
* This performs log out from the specified target
**/
-static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn)
+static int qla4xxx_sysfs_ddb_logout(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn)
{
struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
struct scsi_qla_host *ha = to_qla_host(shost);
@@ -7837,12 +7837,12 @@ static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,
}

static int
-qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
+qla4xxx_sysfs_ddb_get_param(struct iscsi_flash_session *fnode_sess,
int param, char *buf)
{
struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
struct scsi_qla_host *ha = to_qla_host(shost);
- struct iscsi_bus_flash_conn *fnode_conn;
+ struct iscsi_flash_conn *fnode_conn;
struct ql4_chap_table chap_tbl;
struct device *dev;
int parent_type;
@@ -8091,8 +8091,8 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
* This sets the parameter of flash ddb entry and writes them to flash
**/
static int
-qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn,
+qla4xxx_sysfs_ddb_set_param(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn,
void *data, int len)
{
struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
@@ -8319,7 +8319,7 @@ qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,
*
* This invalidates the flash ddb entry at the given index
**/
-static int qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess)
+static int qla4xxx_sysfs_ddb_delete(struct iscsi_flash_session *fnode_sess)
{
struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
struct scsi_qla_host *ha = to_qla_host(shost);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index c065763b1fc6..13393c025ccb 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -854,7 +854,7 @@ static ssize_t \
show_##type##_##name(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
- struct iscsi_bus_flash_session *fnode_sess = \
+ struct iscsi_flash_session *fnode_sess = \
iscsi_dev_to_flash_session(dev);\
struct iscsi_transport *t = fnode_sess->transport; \
return t->get_flashnode_param(fnode_sess, param, buf); \
@@ -954,7 +954,7 @@ static umode_t iscsi_flashnode_sess_attr_is_visible(struct kobject *kobj,
int i)
{
struct device *dev = container_of(kobj, struct device, kobj);
- struct iscsi_bus_flash_session *fnode_sess =
+ struct iscsi_flash_session *fnode_sess =
iscsi_dev_to_flash_session(dev);
struct iscsi_transport *t = fnode_sess->transport;
int param;
@@ -1045,7 +1045,7 @@ static const struct attribute_group *iscsi_flashnode_sess_attr_groups[] = {

static void iscsi_flashnode_sess_release(struct device *dev)
{
- struct iscsi_bus_flash_session *fnode_sess =
+ struct iscsi_flash_session *fnode_sess =
iscsi_dev_to_flash_session(dev);

kfree(fnode_sess->targetname);
@@ -1055,7 +1055,7 @@ static void iscsi_flashnode_sess_release(struct device *dev)
}

static const struct device_type iscsi_flashnode_sess_dev_type = {
- .name = "iscsi_flashnode_sess_dev_type",
+ .name = "iscsi_flashnode_sess",
.groups = iscsi_flashnode_sess_attr_groups,
.release = iscsi_flashnode_sess_release,
};
@@ -1072,8 +1072,8 @@ static ssize_t \
show_##type##_##name(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
- struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);\
- struct iscsi_bus_flash_session *fnode_sess = \
+ struct iscsi_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);\
+ struct iscsi_flash_session *fnode_sess = \
iscsi_flash_conn_to_flash_session(fnode_conn);\
struct iscsi_transport *t = fnode_conn->transport; \
return t->get_flashnode_param(fnode_sess, param, buf); \
@@ -1162,7 +1162,7 @@ static umode_t iscsi_flashnode_conn_attr_is_visible(struct kobject *kobj,
int i)
{
struct device *dev = container_of(kobj, struct device, kobj);
- struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);
+ struct iscsi_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);
struct iscsi_transport *t = fnode_conn->transport;
int param;

@@ -1238,7 +1238,7 @@ static const struct attribute_group *iscsi_flashnode_conn_attr_groups[] = {

static void iscsi_flashnode_conn_release(struct device *dev)
{
- struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);
+ struct iscsi_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);

kfree(fnode_conn->ipaddress);
kfree(fnode_conn->redirect_ipaddr);
@@ -1247,12 +1247,28 @@ static void iscsi_flashnode_conn_release(struct device *dev)
}

static const struct device_type iscsi_flashnode_conn_dev_type = {
- .name = "iscsi_flashnode_conn_dev_type",
+ .name = "iscsi_flashnode_conn",
.groups = iscsi_flashnode_conn_attr_groups,
.release = iscsi_flashnode_conn_release,
};

-static struct class iscsi_flashnode_bus = {
+/**
+ * iscsi_is_flashnode_conn_dev - verify passed device is to be flashnode conn
+ * @dev: device to verify
+ * @data: pointer to data containing value to use for verification
+ *
+ * Verifies if the passed device is flashnode conn device
+ *
+ * Returns:
+ * 1 on success
+ * 0 on failure
+ */
+static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
+{
+ return dev->type == &iscsi_flashnode_conn_dev_type;
+}
+
+static struct class iscsi_flashnode = {
.name = "iscsi_flashnode",
};

@@ -1269,12 +1285,12 @@ static struct class iscsi_flashnode_bus = {
* pointer to allocated flashnode sess on success
* %NULL on failure
*/
-struct iscsi_bus_flash_session *
+struct iscsi_flash_session *
iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
struct iscsi_transport *transport,
int dd_size)
{
- struct iscsi_bus_flash_session *fnode_sess;
+ struct iscsi_flash_session *fnode_sess;
int err;

fnode_sess = kzalloc(sizeof(*fnode_sess) + dd_size, GFP_KERNEL);
@@ -1284,7 +1300,7 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
fnode_sess->transport = transport;
fnode_sess->target_id = index;
fnode_sess->dev.type = &iscsi_flashnode_sess_dev_type;
- fnode_sess->dev.class = &iscsi_flashnode_bus;
+ fnode_sess->dev.class = &iscsi_flashnode;
fnode_sess->dev.parent = &shost->shost_gendev;
dev_set_name(&fnode_sess->dev, "flashnode_sess-%u:%u",
shost->host_no, index);
@@ -1317,13 +1333,13 @@ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
* pointer to allocated flashnode conn on success
* %NULL on failure
*/
-struct iscsi_bus_flash_conn *
+struct iscsi_flash_conn *
iscsi_create_flashnode_conn(struct Scsi_Host *shost,
- struct iscsi_bus_flash_session *fnode_sess,
+ struct iscsi_flash_session *fnode_sess,
struct iscsi_transport *transport,
int dd_size)
{
- struct iscsi_bus_flash_conn *fnode_conn;
+ struct iscsi_flash_conn *fnode_conn;
int err;

fnode_conn = kzalloc(sizeof(*fnode_conn) + dd_size, GFP_KERNEL);
@@ -1332,7 +1348,7 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,

fnode_conn->transport = transport;
fnode_conn->dev.type = &iscsi_flashnode_conn_dev_type;
- fnode_conn->dev.class = &iscsi_flashnode_bus;
+ fnode_conn->dev.class = &iscsi_flashnode;
fnode_conn->dev.parent = &fnode_sess->dev;
dev_set_name(&fnode_conn->dev, "flashnode_conn-%u:%u:0",
shost->host_no, fnode_sess->target_id);
@@ -1352,23 +1368,7 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
}
EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);

-/**
- * iscsi_is_flashnode_conn_dev - verify passed device is to be flashnode conn
- * @dev: device to verify
- * @data: pointer to data containing value to use for verification
- *
- * Verifies if the passed device is flashnode conn device
- *
- * Returns:
- * 1 on success
- * 0 on failure
- */
-static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
-{
- return dev->type == &iscsi_flashnode_conn_dev_type;
-}
-
-static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn)
+static int iscsi_destroy_flashnode_conn(struct iscsi_flash_conn *fnode_conn)
{
device_unregister(&fnode_conn->dev);
return 0;
@@ -1376,10 +1376,10 @@ static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn)

static int flashnode_match_index(struct device *dev, void *data)
{
- struct iscsi_bus_flash_session *fnode_sess = NULL;
+ struct iscsi_flash_session *fnode_sess = NULL;
int ret = 0;

- if (dev->type != &iscsi_flashnode_sess_dev_type)
+ if (!iscsi_is_flashnode_session_dev(dev))
goto exit_match_index;

fnode_sess = iscsi_dev_to_flash_session(dev);
@@ -1400,10 +1400,10 @@ static int flashnode_match_index(struct device *dev, void *data)
* pointer to found flashnode session object on success
* %NULL on failure
*/
-static struct iscsi_bus_flash_session *
+static struct iscsi_flash_session *
iscsi_get_flashnode_by_index(struct Scsi_Host *shost, uint32_t idx)
{
- struct iscsi_bus_flash_session *fnode_sess = NULL;
+ struct iscsi_flash_session *fnode_sess = NULL;
struct device *dev;

dev = device_find_child(&shost->shost_gendev, &idx,
@@ -1447,7 +1447,7 @@ EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess);
* %NULL on failure
*/
struct device *
-iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess)
+iscsi_find_flashnode_conn(struct iscsi_flash_session *fnode_sess)
{
return device_find_child(&fnode_sess->dev, NULL,
iscsi_is_flashnode_conn_dev);
@@ -1469,7 +1469,7 @@ static int iscsi_iter_destroy_flashnode_conn_fn(struct device *dev, void *data)
* Deletes the flashnode session entry and all children flashnode connection
* entries from sysfs
*/
-void iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess)
+void iscsi_destroy_flashnode_sess(struct iscsi_flash_session *fnode_sess)
{
int err;

@@ -1485,7 +1485,7 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_flashnode_sess);

static int iscsi_iter_destroy_flashnode_fn(struct device *dev, void *data)
{
- if (dev->type != &iscsi_flashnode_sess_dev_type)
+ if (!iscsi_is_flashnode_session_dev(dev))
return 0;

iscsi_destroy_flashnode_sess(iscsi_dev_to_flash_session(dev));
@@ -3610,8 +3610,8 @@ static int iscsi_set_flashnode_param(struct net *net,
{
char *data = (char *)ev + sizeof(*ev);
struct Scsi_Host *shost;
- struct iscsi_bus_flash_session *fnode_sess;
- struct iscsi_bus_flash_conn *fnode_conn;
+ struct iscsi_flash_session *fnode_sess;
+ struct iscsi_flash_conn *fnode_conn;
struct device *dev;
uint32_t idx;
int err = 0;
@@ -3699,7 +3699,7 @@ static int iscsi_del_flashnode(struct net *net,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
- struct iscsi_bus_flash_session *fnode_sess;
+ struct iscsi_flash_session *fnode_sess;
uint32_t idx;
int err = 0;

@@ -3740,8 +3740,8 @@ static int iscsi_login_flashnode(struct net *net,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
- struct iscsi_bus_flash_session *fnode_sess;
- struct iscsi_bus_flash_conn *fnode_conn;
+ struct iscsi_flash_session *fnode_sess;
+ struct iscsi_flash_conn *fnode_conn;
struct device *dev;
uint32_t idx;
int err = 0;
@@ -3793,8 +3793,8 @@ static int iscsi_logout_flashnode(struct net *net,
struct iscsi_uevent *ev)
{
struct Scsi_Host *shost;
- struct iscsi_bus_flash_session *fnode_sess;
- struct iscsi_bus_flash_conn *fnode_conn;
+ struct iscsi_flash_session *fnode_sess;
+ struct iscsi_flash_conn *fnode_conn;
struct device *dev;
uint32_t idx;
int err = 0;
@@ -5194,7 +5194,7 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_conn_class;

- err = class_register(&iscsi_flashnode_bus);
+ err = class_register(&iscsi_flashnode);
if (err)
goto unregister_session_class;

@@ -5217,7 +5217,7 @@ static __init int iscsi_transport_init(void)
unregister_pernet_subsys:
unregister_pernet_subsys(&iscsi_net_ops);
unregister_flashnode_bus:
- class_unregister(&iscsi_flashnode_bus);
+ class_unregister(&iscsi_flashnode);
unregister_session_class:
transport_class_unregister(&iscsi_session_class);
unregister_conn_class:
@@ -5237,7 +5237,7 @@ static void __exit iscsi_transport_exit(void)
{
destroy_workqueue(iscsi_conn_cleanup_workq);
unregister_pernet_subsys(&iscsi_net_ops);
- class_unregister(&iscsi_flashnode_bus);
+ class_unregister(&iscsi_flashnode);
transport_class_unregister(&iscsi_connection_class);
transport_class_unregister(&iscsi_session_class);
transport_class_unregister(&iscsi_host_class);
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 580f06d1479b..d03d9eb5707b 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -26,8 +26,8 @@ struct iscsi_task;
struct sockaddr;
struct iscsi_iface;
struct bsg_job;
-struct iscsi_bus_flash_session;
-struct iscsi_bus_flash_conn;
+struct iscsi_flash_session;
+struct iscsi_flash_conn;

/**
* struct iscsi_transport - iSCSI Transport template
@@ -141,18 +141,18 @@ struct iscsi_transport {
uint32_t *num_entries, char *buf);
int (*delete_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx);
int (*set_chap) (struct Scsi_Host *shost, void *data, int len);
- int (*get_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess,
- int param, char *buf);
- int (*set_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn,
- void *data, int len);
- int (*new_flashnode) (struct Scsi_Host *shost, const char *buf,
- int len);
- int (*del_flashnode) (struct iscsi_bus_flash_session *fnode_sess);
- int (*login_flashnode) (struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn);
- int (*logout_flashnode) (struct iscsi_bus_flash_session *fnode_sess,
- struct iscsi_bus_flash_conn *fnode_conn);
+ int (*get_flashnode_param)(struct iscsi_flash_session *fnode_sess,
+ int param, char *buf);
+ int (*set_flashnode_param)(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn,
+ void *data, int len);
+ int (*new_flashnode)(struct Scsi_Host *shost, const char *buf,
+ int len);
+ int (*del_flashnode)(struct iscsi_flash_session *fnode_sess);
+ int (*login_flashnode)(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn);
+ int (*logout_flashnode)(struct iscsi_flash_session *fnode_sess,
+ struct iscsi_flash_conn *fnode_conn);
int (*logout_flashnode_sid) (struct iscsi_cls_session *cls_sess);
int (*get_host_stats) (struct Scsi_Host *shost, char *buf, int len);
u8 (*check_protection)(struct iscsi_task *task, sector_t *sector);
@@ -332,7 +332,7 @@ struct iscsi_iface {
dev_to_shost(_iface->dev.parent)


-struct iscsi_bus_flash_conn {
+struct iscsi_flash_conn {
struct list_head conn_list; /* item in connlist */
void *dd_data; /* LLD private data */
struct iscsi_transport *transport;
@@ -370,14 +370,14 @@ struct iscsi_bus_flash_conn {
};

#define iscsi_dev_to_flash_conn(_dev) \
- container_of(_dev, struct iscsi_bus_flash_conn, dev)
+ container_of(_dev, struct iscsi_flash_conn, dev)

#define iscsi_flash_conn_to_flash_session(_conn) \
iscsi_dev_to_flash_session(_conn->dev.parent)

#define ISID_SIZE 6

-struct iscsi_bus_flash_session {
+struct iscsi_flash_session {
struct list_head sess_list; /* item in session_list */
struct iscsi_transport *transport;
unsigned int target_id;
@@ -432,7 +432,7 @@ struct iscsi_bus_flash_session {
};

#define iscsi_dev_to_flash_session(_dev) \
- container_of(_dev, struct iscsi_bus_flash_session, dev)
+ container_of(_dev, struct iscsi_flash_session, dev)

#define iscsi_flash_session_to_shost(_session) \
dev_to_shost(_session->dev.parent)
@@ -491,17 +491,17 @@ extern struct device *
iscsi_find_flashnode(struct Scsi_Host *shost, void *data,
int (*fn)(struct device *dev, void *data));

-extern struct iscsi_bus_flash_session *
+extern struct iscsi_flash_session *
iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
struct iscsi_transport *transport, int dd_size);

-extern struct iscsi_bus_flash_conn *
+extern struct iscsi_flash_conn *
iscsi_create_flashnode_conn(struct Scsi_Host *shost,
- struct iscsi_bus_flash_session *fnode_sess,
+ struct iscsi_flash_session *fnode_sess,
struct iscsi_transport *transport, int dd_size);

extern void
-iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess);
+iscsi_destroy_flashnode_sess(struct iscsi_flash_session *fnode_sess);

extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost);
extern int iscsi_flashnode_bus_match(struct device *dev,
@@ -510,7 +510,9 @@ extern struct device *
iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
int (*fn)(struct device *dev, void *data));
extern struct device *
-iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);
+iscsi_find_flashnode_conn(struct iscsi_flash_session *fnode_sess);
+
+extern bool iscsi_is_flashnode_session_dev(struct device *dev);

extern bool iscsi_is_flashnode_session_dev(struct device *dev);

--
2.39.1

Lee Duncan

unread,
Feb 8, 2023, 12:41:04 PM2/8/23
to linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
From: Lee Duncan <ldu...@suse.com>

This finishes the net namespace support for flashnode sysfs devices.

Signed-off-by: Chris Leech <cle...@redhat.com>
Signed-off-by: Lee Duncan <ldu...@suse.com>
---
drivers/scsi/scsi_transport_iscsi.c | 34 +++++++++++++++++++++++++++++
include/scsi/scsi_transport_iscsi.h | 4 ----
2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 13393c025ccb..9a176ea0d866 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1268,8 +1268,42 @@ static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
return dev->type == &iscsi_flashnode_conn_dev_type;
}

+static struct net *iscsi_flashnode_sess_net(struct iscsi_flash_session *f_sess)
+{
+ struct Scsi_Host *shost = iscsi_flash_session_to_shost(f_sess);
+ struct iscsi_cls_host *ihost = shost->shost_data;
+
+ return iscsi_host_net(ihost);
+}
+
+static struct net *iscsi_flashnode_conn_net(struct iscsi_flash_conn *f_conn)
+{
+ struct iscsi_flash_session *f_sess =
+ iscsi_flash_conn_to_flash_session(f_conn);
+
+ return iscsi_flashnode_sess_net(f_sess);
+}
+
+static const void *iscsi_flashnode_namespace(const struct device *dev)
+{
+ struct iscsi_flash_conn *f_conn;
+ struct iscsi_flash_session *f_sess;
+ struct device *dev_tmp = (struct device *)dev;
+
+ if (iscsi_is_flashnode_conn_dev(dev_tmp, NULL)) {
+ f_conn = iscsi_dev_to_flash_conn(dev);
+ return iscsi_flashnode_conn_net(f_conn);
+ } else if (iscsi_is_flashnode_session_dev(dev_tmp)) {
+ f_sess = iscsi_dev_to_flash_session(dev);
+ return iscsi_flashnode_sess_net(f_sess);
+ }
+ return NULL;
+}
+
static struct class iscsi_flashnode = {
.name = "iscsi_flashnode",
+ .ns_type = &net_ns_type_operations,
+ .namespace = iscsi_flashnode_namespace,
};

/**
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index d03d9eb5707b..0c3fd690ecf8 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -504,8 +504,6 @@ extern void
iscsi_destroy_flashnode_sess(struct iscsi_flash_session *fnode_sess);

extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost);
-extern int iscsi_flashnode_bus_match(struct device *dev,
- struct device_driver *drv);
extern struct device *
iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
int (*fn)(struct device *dev, void *data));
@@ -514,8 +512,6 @@ iscsi_find_flashnode_conn(struct iscsi_flash_session *fnode_sess);

extern bool iscsi_is_flashnode_session_dev(struct device *dev);

-extern bool iscsi_is_flashnode_session_dev(struct device *dev);
-

The Lee-Man

unread,
Feb 8, 2023, 2:17:48 PM2/8/23
to open-iscsi
I wanted to mention some issues I've discovered as part of testing this:

  • Currently, only some sysfs entries are going to be different per namespace
  • This means that the Configuration and Initiator Name are going to be common to all running daemons (this is /etc/iscsi)
  • This also means that the Node database (and discovery DB, and interface DB) are common to all running daemons
I'm really not sure all running daemons should have the same initiator name. If we think of them as separate initiators, then this seems wrong.

Sharing the Node database may not be a good idea, either. This assumes that nodes discovered (and saved) from one namespace can actually be reached from other namespaces, but this may not be true. Having the Node DB and initiatorname shared means the different iscsid instances must cooperate with each other, else their requests can collide. Also, I can imagine situations where different daemons may want to set different configuration values. Currently they cannot.

Lee Duncan

unread,
Feb 8, 2023, 2:23:16 PM2/8/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org
[Resent to include all mailing lists]

I wanted to mention some issues I've discovered as part of testing this:

- Currently, only some sysfs entries are going to be different
per namespace
- This means that the Configuration and Initiator Name are going to
be common to all running daemons (this is /etc/iscsi)
- This also means that the Node database (and discovery DB,
and interface DB) are common to all running daemons

I'm really not sure all running daemons should have the same initiator
name. If we think of them as separate initiators, then this seems wrong.

Sharing the Node database may not be a good idea, either. This assumes
that nodes discovered (and saved) from one namespace can actually be
reached from other namespaces, but this may not be true. Having the Node
DB and initiatorname shared means the different iscsid instances must
cooperate with each other, else their requests can collide. Also, I can
imagine situations where different daemons may want to set different
configuration values. Currently they cannot.

Chris Leech

unread,
Feb 8, 2023, 2:52:13 PM2/8/23
to open-...@googlegroups.com
On Wed, Feb 8, 2023 at 11:17 AM The Lee-Man <leeman...@gmail.com> wrote:
I wanted to mention some issues I've discovered as part of testing this:
  • Currently, only some sysfs entries are going to be different per namespace

Anything that's directly related to the iSCSI host, session, connection, etc. should be filtered, I think.  SCSI mid-layer objects and block devices are not.  That seemed the cleanest break for being able to isolate the control plane to a network namespace, which is the isolation that I've seen asked for.
 
  • This means that the Configuration and Initiator Name are going to be common to all running daemons (this is /etc/iscsi)
  • This also means that the Node database (and discovery DB, and interface DB) are common to all running daemons
These changes were about making the kernel to iscsid interfaces namespace aware, so that iscsid could be containerized.  If you were to do that, wouldn't you give iscsid a separate filesystem view with different configuration and record database space?  I think you're right that there are other resources that shouldn't be shared between multiple instances of iscsid, and maybe protecting against some of that misconfiguration needs to happen in Open-iSCSI.

- Chris
 
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open-iscsi+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/open-iscsi/9ff09a3d-1a75-436a-bbc3-0f154285cfa3n%40googlegroups.com.

Don Williams

unread,
Feb 8, 2023, 3:10:37 PM2/8/23
to open-...@googlegroups.com
I agree that sharing the initiator name and the other config files would not be recommended. 

The initiator name is often used as an access controll method on the target.   Which could lead to double mounting volumes. 

Also one benefit would be better isolating an iSCSI SAN with multiple customers accessing the SAN via unique containers.    

It should be possible to specify those files and directories as part of the container config.  

Don

The Lee-Man

unread,
Feb 28, 2023, 12:38:20 PM2/28/23
to open-iscsi
Don: Agreed.

I have been playing with podman, and I actually have a working prototype! Right now, I'm looking how to end sessions started in a container. Just killing the container leaves a dangling session.

Hannes Reinecke

unread,
Mar 14, 2023, 12:20:15 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
Awesome work!

Thanks for this!

Comments to follow on the individual patches.

Cheers,

Hannes

Hannes Reinecke

unread,
Mar 14, 2023, 12:23:30 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
On 2/8/23 18:40, Lee Duncan wrote:
Umm... doesn't this change the sysfs layout?
IE won't the endpoint node be moved under the Scsi_Host directory?

But even if it does: do we care?


Cheers,

Hannes

Hannes Reinecke

unread,
Mar 14, 2023, 12:29:30 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
On 2/8/23 18:40, Lee Duncan wrote:
> From: Lee Duncan <ldu...@suse.com>
>
> This lets iscsi_tcp operate in multiple namespaces. It uses current
> during session creation to find the net namespace, but it might be
> better to manage to pass it along from the iscsi netlink socket.
>
And indeed, I'd rather use the namespace from the iscsi netlink socket.
If you use the namespace from session creation you'd better hope that
this function is not called from a workqueue ...


> Signed-off-by: Chris Leech <cle...@redhat.com>
> Signed-off-by: Lee Duncan <ldu...@suse.com>
> ---
> drivers/scsi/iscsi_tcp.c | 7 +++++++
> drivers/scsi/scsi_transport_iscsi.c | 7 ++++++-
> include/scsi/scsi_transport_iscsi.h | 1 +
> 3 files changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
> index 0454d94e8cf0..22e7a5c93627 100644
> --- a/drivers/scsi/iscsi_tcp.c
> +++ b/drivers/scsi/iscsi_tcp.c
> @@ -1069,6 +1069,11 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
> return 0;
> }
>
> +static struct net *iscsi_sw_tcp_netns(struct Scsi_Host *shost)
> +{
> + return current->nsproxy->net_ns;
> +}
> +

See above if you can't reference the namespace for the netlink socket here.
Cheers,

Hannes

Hannes Reinecke

unread,
Mar 14, 2023, 1:44:52 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
On 2/8/23 18:40, Lee Duncan wrote:
> From: Lee Duncan <ldu...@suse.com>
>
> All internal lookups of iSCSI transport objects need to be filtered by
> net namespace.
>
> Signed-off-by: Chris Leech <cle...@redhat.com>
> Signed-off-by: Lee Duncan <ldu...@suse.com>
> ---
> drivers/infiniband/ulp/iser/iscsi_iser.c | 5 +-
> drivers/scsi/be2iscsi/be_iscsi.c | 4 +-
> drivers/scsi/bnx2i/bnx2i_iscsi.c | 4 +-
> drivers/scsi/cxgbi/libcxgbi.c | 4 +-
> drivers/scsi/qedi/qedi_iscsi.c | 4 +-
> drivers/scsi/qla4xxx/ql4_os.c | 8 +-
> drivers/scsi/scsi_transport_iscsi.c | 202 ++++++++++++++---------
> include/scsi/scsi_transport_iscsi.h | 5 +-
> 8 files changed, 149 insertions(+), 87 deletions(-)
>
Reviewed-by: Hannes Reinecke <ha...@suse.de>

Cheers,

Hannes


Hannes Reinecke

unread,
Mar 14, 2023, 1:45:34 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
On 2/8/23 18:40, Lee Duncan wrote:
> From: Lee Duncan <ldu...@suse.com>
>
> The flashnode session and connection devices should be filtered by net
> namespace along with the iscsi_host, but we can't do that with a bus
> device. As these don't use any of the bus matching functionality, they
> make more sense as a class device anyway.
>
> Signed-off-by: Chris Leech <cle...@redhat.com>
> Signed-off-by: Lee Duncan <ldu...@suse.com>
> ---
> drivers/scsi/qla4xxx/ql4_os.c | 2 +-
> drivers/scsi/scsi_transport_iscsi.c | 36 ++++++++++++-----------------
> include/scsi/scsi_transport_iscsi.h | 2 ++
> 3 files changed, 18 insertions(+), 22 deletions(-)
>

Hannes Reinecke

unread,
Mar 14, 2023, 1:46:25 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
On 2/8/23 18:40, Lee Duncan wrote:
> From: Lee Duncan <ldu...@suse.com>
>
> These are cleanups after the bus to class conversion
> for flashnode devices.
>
> Signed-off-by: Chris Leech <cle...@redhat.com>
> Signed-off-by: Lee Duncan <ldu...@suse.com>
> ---
> drivers/scsi/qla4xxx/ql4_os.c | 52 +++++++-------
> drivers/scsi/scsi_transport_iscsi.c | 102 ++++++++++++++--------------
> include/scsi/scsi_transport_iscsi.h | 48 ++++++-------
> 3 files changed, 102 insertions(+), 100 deletions(-)
>
Can be merged with the previous patch, but otherwise:

Hannes Reinecke

unread,
Mar 14, 2023, 1:47:09 PM3/14/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan, Chris Leech
On 2/8/23 18:40, Lee Duncan wrote:
> From: Lee Duncan <ldu...@suse.com>
>
> This finishes the net namespace support for flashnode sysfs devices.
>
> Signed-off-by: Chris Leech <cle...@redhat.com>
> Signed-off-by: Lee Duncan <ldu...@suse.com>
> ---
> drivers/scsi/scsi_transport_iscsi.c | 34 +++++++++++++++++++++++++++++
> include/scsi/scsi_transport_iscsi.h | 4 ----
> 2 files changed, 34 insertions(+), 4 deletions(-)
>

Lee Duncan

unread,
Mar 17, 2023, 5:42:54 PM3/17/23
to Hannes Reinecke, linux...@vger.kernel.org, open-iscsi, net...@vger.kernel.org, Lee Duncan, Chris Leech
No, it’s still /sys/class/iscsi_endpoint, since the dev.class hasn’t changed.


Lee

Chris Leech

unread,
Apr 10, 2023, 8:22:00 PM4/10/23
to Hannes Reinecke, Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
On Tue, Mar 14, 2023 at 05:29:25PM +0100, Hannes Reinecke wrote:
> On 2/8/23 18:40, Lee Duncan wrote:
> > From: Lee Duncan <ldu...@suse.com>
> >
> > This lets iscsi_tcp operate in multiple namespaces. It uses current
> > during session creation to find the net namespace, but it might be
> > better to manage to pass it along from the iscsi netlink socket.
> >
> And indeed, I'd rather use the namespace from the iscsi netlink socket.
> If you use the namespace from session creation you'd better hope that
> this function is not called from a workqueue ...

The cleanest way I see to do this is to split the transport
session_create function between bound and unbound, instead of checking
for a NULL ep. That should cleanly serperate out the host-per-session
behavior of iscsi_tcp, so we can pass in the namespace without changing
the other drivers.

This is what that looks like on top of the existing patches, but we can
merge it in and rearrange if desired.

- Chris

---

Distinguish between bound and unbound session creation with different
transport functions, instead of just checking for a NULL endpoint.

This let's the transport code pass the network namespace into the
unbound session creation of iscsi_tcp, without changing the offloading
drivers which all expect an bound endpoint.

iSER has compatibility checks to work without a bound endpoint, so
expose both transport functions there.

Signed-off-by: Chris Leech <cle...@redhat.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 41 +++++++++++++++++-------
drivers/scsi/iscsi_tcp.c | 16 ++++-----
drivers/scsi/iscsi_tcp.h | 1 +
drivers/scsi/scsi_transport_iscsi.c | 17 +++++++---
include/scsi/scsi_transport_iscsi.h | 3 ++
5 files changed, 52 insertions(+), 26 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 6865f62eb831..ca8de612d585 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -593,20 +593,10 @@ static inline unsigned int iser_dif_prot_caps(int prot_caps)
return ret;
}

-/**
- * iscsi_iser_session_create() - create an iscsi-iser session
- * @ep: iscsi end-point handle
- * @cmds_max: maximum commands in this session
- * @qdepth: session command queue depth
- * @initial_cmdsn: initiator command sequnce number
- *
- * Allocates and adds a scsi host, expose DIF supprot if
- * exists, and sets up an iscsi session.
- */
static struct iscsi_cls_session *
-iscsi_iser_session_create(struct iscsi_endpoint *ep,
+__iscsi_iser_session_create(struct iscsi_endpoint *ep,
uint16_t cmds_max, uint16_t qdepth,
- uint32_t initial_cmdsn)
+ uint32_t initial_cmdsn, struct net *net)
{
struct iscsi_cls_session *cls_session;
struct Scsi_Host *shost;
@@ -694,6 +684,32 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
return NULL;
}

+/**
+ * iscsi_iser_session_create() - create an iscsi-iser session
+ * @ep: iscsi end-point handle
+ * @cmds_max: maximum commands in this session
+ * @qdepth: session command queue depth
+ * @initial_cmdsn: initiator command sequnce number
+ *
+ * Allocates and adds a scsi host, expose DIF supprot if
+ * exists, and sets up an iscsi session.
+ */
+static struct iscsi_cls_session *
+iscsi_iser_session_create(struct iscsi_endpoint *ep,
+ uint16_t cmds_max, uint16_t qdepth,
+ uint32_t initial_cmdsn) {
+ return __iscsi_iser_session_create(ep, cmds_max, qdepth,
+ initial_cmdsn, NULL);
+}
+
+static struct iscsi_cls_session *
+iscsi_iser_unbound_session_create(struct net *net,
+ uint16_t cmds_max, uint16_t qdepth,
+ uint32_t initial_cmdsn) {
+ return __iscsi_iser_session_create(NULL, cmds_max, qdepth,
+ initial_cmdsn, net);
+}
+
static int iscsi_iser_set_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf, int buflen)
{
@@ -983,6 +999,7 @@ static struct iscsi_transport iscsi_iser_transport = {
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_TEXT_NEGO,
/* session management */
.create_session = iscsi_iser_session_create,
+ .create_unbound_session = iscsi_iser_unbound_session_create,
.destroy_session = iscsi_iser_session_destroy,
/* connection management */
.create_conn = iscsi_iser_conn_create,
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 171685011ad9..b78239f25073 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -922,7 +922,7 @@ iscsi_sw_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
}

static struct iscsi_cls_session *
-iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
+iscsi_sw_tcp_session_create(struct net *net, uint16_t cmds_max,
uint16_t qdepth, uint32_t initial_cmdsn)
{
struct iscsi_cls_session *cls_session;
@@ -931,11 +931,6 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
struct Scsi_Host *shost;
int rc;

- if (ep) {
- printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep);
- return NULL;
- }
-
shost = iscsi_host_alloc(&iscsi_sw_tcp_sht,
sizeof(struct iscsi_sw_tcp_host), 1);
if (!shost)
@@ -952,6 +947,9 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
goto free_host;
shost->can_queue = rc;

+ tcp_sw_host = iscsi_host_priv(shost);
+ tcp_sw_host->net_ns = net;
+
if (iscsi_host_add(shost, NULL))
goto free_host;

@@ -968,7 +966,6 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
goto remove_session;

/* We are now fully setup so expose the session to sysfs. */
- tcp_sw_host = iscsi_host_priv(shost);
tcp_sw_host->session = session;
return cls_session;

@@ -1074,7 +1071,8 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)

static struct net *iscsi_sw_tcp_netns(struct Scsi_Host *shost)
{
- return current->nsproxy->net_ns;
+ struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
+ return tcp_sw_host->net_ns;
}

static struct scsi_host_template iscsi_sw_tcp_sht = {
@@ -1104,7 +1102,7 @@ static struct iscsi_transport iscsi_sw_tcp_transport = {
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
| CAP_DATADGST,
/* session management */
- .create_session = iscsi_sw_tcp_session_create,
+ .create_unbound_session = iscsi_sw_tcp_session_create,
.destroy_session = iscsi_sw_tcp_session_destroy,
/* connection management */
.create_conn = iscsi_sw_tcp_conn_create,
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 68e14a344904..f0020cb22f59 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -53,6 +53,7 @@ struct iscsi_sw_tcp_conn {

struct iscsi_sw_tcp_host {
struct iscsi_session *session;
+ struct net *net_ns;
};

struct iscsi_sw_tcp_hdrbuf {
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 8fafa8f0e0df..4d346e79468e 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3144,14 +3144,21 @@ static int
iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
struct iscsi_uevent *ev, pid_t pid,
uint32_t initial_cmdsn, uint16_t cmds_max,
- uint16_t queue_depth)
+ uint16_t queue_depth, struct net *net)
{
struct iscsi_transport *transport = priv->iscsi_transport;
struct iscsi_cls_session *session;
struct Scsi_Host *shost;

- session = transport->create_session(ep, cmds_max, queue_depth,
- initial_cmdsn);
+ if (ep) {
+ session = transport->create_session(ep, cmds_max, queue_depth,
+ initial_cmdsn);
+ } else {
+ session = transport->create_unbound_session(net, cmds_max,
+ queue_depth,
+ initial_cmdsn);
+ }
+
if (!session)
return -ENOMEM;

@@ -4145,7 +4152,7 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
portid,
ev->u.c_session.initial_cmdsn,
ev->u.c_session.cmds_max,
- ev->u.c_session.queue_depth);
+ ev->u.c_session.queue_depth, net);
break;
/* MARK */
case ISCSI_UEVENT_CREATE_BOUND_SESSION:
@@ -4160,7 +4167,7 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
portid,
ev->u.c_bound_session.initial_cmdsn,
ev->u.c_bound_session.cmds_max,
- ev->u.c_bound_session.queue_depth);
+ ev->u.c_bound_session.queue_depth, net);
iscsi_put_endpoint(ep);
break;
case ISCSI_UEVENT_DESTROY_SESSION:
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 0c3fd690ecf8..4d8a3d770bed 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -79,6 +79,9 @@ struct iscsi_transport {
struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,
uint16_t cmds_max, uint16_t qdepth,
uint32_t sn);
+ struct iscsi_cls_session *(*create_unbound_session) (struct net *net,
+ uint16_t cmds_max, uint16_t qdepth,
+ uint32_t sn);
void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid);
--
2.39.2

Hannes Reinecke

unread,
Apr 11, 2023, 2:58:58 AM4/11/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
I'm not _that_ happy with these two functions; but can't really see a
way around it.
Can't we rename the 'unbound' version to
'create_session_ns' or something?

Cheers,

Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
ha...@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Ivo Totev, Andrew
Myers, Andrew McDonald, Martje Boudien Moerman

Chris Leech

unread,
Apr 11, 2023, 2:03:46 PM4/11/23
to Hannes Reinecke, Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
Yes, in my mind I was matching the netlink commands, but those are
create_session and create_bound_session. I got it exactly backwards
with which one had the additional text.

I'm OK with changing to a shorter name, like the one you suggested.

Thanks,
- Chris

Chris Leech

unread,
Apr 11, 2023, 10:31:39 PM4/11/23
to Hannes Reinecke, Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
On Tue, Mar 14, 2023 at 05:23:26PM +0100, Hannes Reinecke wrote:
> On 2/8/23 18:40, Lee Duncan wrote:
> > From: Lee Duncan <ldu...@suse.com>
> > @@ -230,6 +230,7 @@ iscsi_create_endpoint(int dd_size)
> > ep->id = id;
> > ep->dev.class = &iscsi_endpoint_class;
> > + ep->dev.parent = &shost->shost_gendev;
> > dev_set_name(&ep->dev, "ep-%d", id);
> > err = device_register(&ep->dev);
> > if (err)
>
> Umm... doesn't this change the sysfs layout?
> IE won't the endpoint node be moved under the Scsi_Host directory?
>
> But even if it does: do we care?

It does, but it shouldn't matter. The Open-iSCSI tools look under the
subsystem, not the device path. Being a child of the host makes more
sense then being a floating virtual device.

I just re-tested with bnx2i to make sure moving an endpoint devpath in
sysfs didn't break anything.

- Chris

Chris Leech

unread,
Apr 20, 2023, 12:42:41 PM4/20/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, net...@vger.kernel.org, Lee Duncan
On Wed, Feb 08, 2023 at 09:40:50AM -0800, Lee Duncan wrote:
> Right now the iscsi_endpoint is only linked to a connection once that
> connection has been established. For net namespace filtering of the
> sysfs objects, associate an endpoint with the host that it was
> allocated for when it is created.
>
> Signed-off-by: Chris Leech <cle...@redhat.com>
> Signed-off-by: Lee Duncan <ldu...@suse.com>
> ---
>
> diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
> index 6b7603765383..212fa7aa9810 100644
> --- a/drivers/infiniband/ulp/iser/iscsi_iser.c
> +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
> @@ -802,7 +802,7 @@ static struct iscsi_endpoint *iscsi_iser_ep_connect(struct Scsi_Host *shost,
> struct iser_conn *iser_conn;
> struct iscsi_endpoint *ep;
>
> - ep = iscsi_create_endpoint(0);
> + ep = iscsi_create_endpoint(shost, 0);
> if (!ep)
> return ERR_PTR(-ENOMEM);

I started trying[1] to look at iSER, and I think this is a problem.
iSER is the only iSCSI driver that uses endpoint objects, but does not
require then to be bound to a host. That means that
iscsi_iser_ep_connect can be called with a null shost.

So this fails, and not in a new namespace.
It just breaks iSER entirely.

I think we need to preserve support for the iscsi_endpoint device
having a virtual device path for iSER.

Also, enabling net namespace support for iSER might require the ability
to create an endpoint directly in a namespace instead of on a host.
Kind of like the create_session discussion for iscsi_tcp.

- Chris

[1] I say trying, becuase before going and borrowing an RDMA setup I
thought I'd give the kernel target and either siw or rxe a try. The
isert module seems to have issues with siw, and I think maybe any iWARP,
where setting enable_iser on a port will try and re-use the TCP port
number and fail due to it being in use. With rxe my host failed, but
that's becuase of this create_endpoint issue.

Chris Leech

unread,
Apr 21, 2023, 1:05:59 AM4/21/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, Lee Duncan, Chris Leech
iSER creates endpoints before hosts and sessions, so we need to keep
compatibility with virtual device paths and not always expect a parent
host.

Signed-off-by: Chris Leech <cle...@redhat.com>
---
drivers/scsi/scsi_transport_iscsi.c | 9 ++++++---
include/scsi/scsi_transport_iscsi.h | 3 ++-
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 41f0de2165e0..b8e451a8c76c 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -189,8 +189,10 @@ static struct net *iscsi_host_net(struct iscsi_cls_host *ihost)
static struct net *iscsi_endpoint_net(struct iscsi_endpoint *ep)
{
struct Scsi_Host *shost = iscsi_endpoint_to_shost(ep);
- struct iscsi_cls_host *ihost = shost->shost_data;
-
+ struct iscsi_cls_host *ihost;
+ if (!shost)
+ return &init_net;
+ ihost = shost->shost_data;
return iscsi_host_net(ihost);
}

@@ -252,7 +254,8 @@ iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size)

ep->id = id;
ep->dev.class = &iscsi_endpoint_class;
- ep->dev.parent = &shost->shost_gendev;
+ if (shost)
+ ep->dev.parent = &shost->shost_gendev;
dev_set_name(&ep->dev, "ep-%d", id);
err = device_register(&ep->dev);
if (err)
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index d233618a17de..bb6734e900e0 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -293,8 +293,9 @@ struct iscsi_cls_session {
#define iscsi_session_to_shost(_session) \
dev_to_shost(_session->dev.parent)

+/* endpoints might not have a parent host (iSER) */
#define iscsi_endpoint_to_shost(_ep) \
- dev_to_shost(_ep->dev.parent)
+ dev_to_shost(&_ep->dev)

extern struct net *iscsi_sess_net(struct iscsi_cls_session *session);

--
2.39.2

Chris Leech

unread,
Apr 21, 2023, 1:05:59 AM4/21/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, Lee Duncan, Chris Leech
Split endpoint creation into host-bound and with a specified namespace,
for iSER's unique use of enpoint objects + virtual host-per-session.

This is much like was done with sessions already for iscsi_tcp.

Signed-off-by: Chris Leech <cle...@redhat.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 6 ++--
drivers/scsi/scsi_transport_iscsi.c | 38 +++++++++++++++++++-----
include/scsi/scsi_transport_iscsi.h | 6 ++++
3 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 49fbfeb49b34..ecb8aba1cee9 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -813,7 +813,7 @@ static int iscsi_iser_get_ep_param(struct iscsi_endpoint *ep,
* Return: iscsi_endpoint created by iscsi layer or ERR_PTR(error)
* if fails.
*/
-static struct iscsi_endpoint *iscsi_iser_ep_connect(struct Scsi_Host *shost,
+static struct iscsi_endpoint *iscsi_iser_ep_connect(struct net *net,
struct sockaddr *dst_addr,
int non_blocking)
{
@@ -821,7 +821,7 @@ static struct iscsi_endpoint *iscsi_iser_ep_connect(struct Scsi_Host *shost,
struct iser_conn *iser_conn;
struct iscsi_endpoint *ep;

- ep = iscsi_create_endpoint(shost, 0);
+ ep = iscsi_create_endpoint_net(net, 0);
if (!ep)
return ERR_PTR(-ENOMEM);

@@ -1027,7 +1027,7 @@ static struct iscsi_transport iscsi_iser_transport = {
/* recovery */
.session_recovery_timedout = iscsi_session_recovery_timedout,

- .ep_connect = iscsi_iser_ep_connect,
+ .ep_connect_net = iscsi_iser_ep_connect,
.ep_poll = iscsi_iser_ep_poll,
.ep_disconnect = iscsi_iser_ep_disconnect
};
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index b8e451a8c76c..d41b4c1ad611 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -190,6 +190,9 @@ static struct net *iscsi_endpoint_net(struct iscsi_endpoint *ep)
{
struct Scsi_Host *shost = iscsi_endpoint_to_shost(ep);
struct iscsi_cls_host *ihost;
+
+ if (ep->netns)
+ return ep->netns;
if (!shost)
return &init_net;
ihost = shost->shost_data;
@@ -228,7 +231,7 @@ static struct attribute_group iscsi_endpoint_group = {
};

struct iscsi_endpoint *
-iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size)
+__iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size, struct net *net)
{
struct iscsi_endpoint *ep;
int err, id;
@@ -256,6 +259,8 @@ iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size)
ep->dev.class = &iscsi_endpoint_class;
if (shost)
ep->dev.parent = &shost->shost_gendev;
+ if (net)
+ ep->netns = net;
dev_set_name(&ep->dev, "ep-%d", id);
err = device_register(&ep->dev);
if (err)
@@ -283,8 +288,21 @@ iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size)
kfree(ep);
return NULL;
}
+
+struct iscsi_endpoint *
+iscsi_create_endpoint(struct Scsi_Host *shost, int dd_size) {
+ return __iscsi_create_endpoint(shost, dd_size, NULL);
+}
+
EXPORT_SYMBOL_GPL(iscsi_create_endpoint);

+struct iscsi_endpoint *
+iscsi_create_endpoint_net(struct net *net, int dd_size) {
+ return __iscsi_create_endpoint(NULL, dd_size, net);
+}
+
+EXPORT_SYMBOL_GPL(iscsi_create_endpoint_net);
+
void iscsi_destroy_endpoint(struct iscsi_endpoint *ep)
{
sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group);
@@ -3279,10 +3297,10 @@ static int iscsi_if_ep_connect(struct net *net,
struct Scsi_Host *shost = NULL;
int non_blocking, err = 0;

- if (!transport->ep_connect)
- return -EINVAL;
-
if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) {
+ if (!transport->ep_connect)
+ return -EINVAL;
+
shost = iscsi_host_lookup(net,
ev->u.ep_connect_through_host.host_no);
if (!shost) {
@@ -3292,11 +3310,17 @@ static int iscsi_if_ep_connect(struct net *net,
return -ENODEV;
}
non_blocking = ev->u.ep_connect_through_host.non_blocking;
- } else
+ dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
+ ep = transport->ep_connect(shost, dst_addr, non_blocking);
+ } else {
+ if (!transport->ep_connect_net)
+ return -EINVAL;
+
non_blocking = ev->u.ep_connect.non_blocking;
+ dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
+ ep = transport->ep_connect_net(net, dst_addr, non_blocking);
+ }

- dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
- ep = transport->ep_connect(shost, dst_addr, non_blocking);
if (IS_ERR(ep)) {
err = PTR_ERR(ep);
goto release_host;
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index bb6734e900e0..a540e085de8d 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -127,6 +127,9 @@ struct iscsi_transport {
struct iscsi_endpoint *(*ep_connect) (struct Scsi_Host *shost,
struct sockaddr *dst_addr,
int non_blocking);
+ struct iscsi_endpoint *(*ep_connect_net) (struct net *net,
+ struct sockaddr *dst_addr,
+ int non_blocking);
int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms);
void (*ep_disconnect) (struct iscsi_endpoint *ep);
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
@@ -321,6 +324,7 @@ struct iscsi_endpoint {
struct device dev;
int id;
struct iscsi_cls_conn *conn;
+ struct net *netns; /* used if there's no parent shost */
};

struct iscsi_iface {
@@ -477,6 +481,8 @@ extern void iscsi_unblock_session(struct iscsi_cls_session *session);
extern void iscsi_block_session(struct iscsi_cls_session *session);
extern struct iscsi_endpoint *iscsi_create_endpoint(struct Scsi_Host *shost,
int dd_size);
+extern struct iscsi_endpoint *iscsi_create_endpoint_net(struct net *net,
+ int dd_size);
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
extern struct iscsi_endpoint *iscsi_lookup_endpoint(struct net *net,
u64 handle);
--
2.39.2

Chris Leech

unread,
Apr 21, 2023, 1:06:00 AM4/21/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, Lee Duncan, Chris Leech
Move the logic to store the network namespace during virtual host
creation (due to the way transport-class object setup callbacks
function) from iscsi_tcp into libiscsi, and share it with iser.

Signed-off-by: Chris Leech <cle...@redhat.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 7 ++++++-
drivers/scsi/iscsi_tcp.c | 10 ++--------
drivers/scsi/iscsi_tcp.h | 1 -
drivers/scsi/libiscsi.c | 12 ++++++++++++
include/scsi/libiscsi.h | 4 ++++
5 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index ecb8aba1cee9..381f48a832ce 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -646,6 +646,8 @@ __iscsi_iser_session_create(struct iscsi_endpoint *ep,
if (!(ib_dev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG))
shost->virt_boundary_mask = SZ_4K - 1;

+ iscsi_host_set_netns(shost, ep->netns);
+
if (iscsi_host_add(shost, ib_dev->dev.parent)) {
mutex_unlock(&iser_conn->state_mutex);
goto free_host;
@@ -653,6 +655,7 @@ __iscsi_iser_session_create(struct iscsi_endpoint *ep,
mutex_unlock(&iser_conn->state_mutex);
} else {
shost->can_queue = min_t(u16, cmds_max, ISER_DEF_XMIT_CMDS_MAX);
+ iscsi_host_set_netns(shost, net);
if (iscsi_host_add(shost, NULL))
goto free_host;
}
@@ -1029,7 +1032,9 @@ static struct iscsi_transport iscsi_iser_transport = {

.ep_connect_net = iscsi_iser_ep_connect,
.ep_poll = iscsi_iser_ep_poll,
- .ep_disconnect = iscsi_iser_ep_disconnect
+ .ep_disconnect = iscsi_iser_ep_disconnect,
+ /* net namespace */
+ .get_netns = iscsi_host_get_netns,
};

static int __init iser_init(void)
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 17f07ca2bbb8..3150d9c7a1ee 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -947,7 +947,7 @@ iscsi_sw_tcp_session_create(struct net *net, uint16_t cmds_max,
shost->can_queue = rc;

tcp_sw_host = iscsi_host_priv(shost);
- tcp_sw_host->net_ns = net;
+ iscsi_host_set_netns(shost, net);

if (iscsi_host_add(shost, NULL))
goto free_host;
@@ -1068,12 +1068,6 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
return 0;
}

-static struct net *iscsi_sw_tcp_netns(struct Scsi_Host *shost)
-{
- struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
- return tcp_sw_host->net_ns;
-}
-
static struct scsi_host_template iscsi_sw_tcp_sht = {
.module = THIS_MODULE,
.name = "iSCSI Initiator over TCP/IP",
@@ -1130,7 +1124,7 @@ static struct iscsi_transport iscsi_sw_tcp_transport = {
/* recovery */
.session_recovery_timedout = iscsi_session_recovery_timedout,
/* net namespace */
- .get_netns = iscsi_sw_tcp_netns,
+ .get_netns = iscsi_host_get_netns,
};

static int __init iscsi_sw_tcp_init(void)
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index f0020cb22f59..68e14a344904 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -53,7 +53,6 @@ struct iscsi_sw_tcp_conn {

struct iscsi_sw_tcp_host {
struct iscsi_session *session;
- struct net *net_ns;
};

struct iscsi_sw_tcp_hdrbuf {
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 127f3d7f19dc..ca8856c24688 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -3929,6 +3929,18 @@ int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param,
}
EXPORT_SYMBOL_GPL(iscsi_host_set_param);

+void iscsi_host_set_netns(struct Scsi_Host *shost, struct net *netns) {
+ struct iscsi_host *ihost = shost_priv(shost);
+ ihost->net_ns = netns;
+}
+EXPORT_SYMBOL_GPL(iscsi_host_set_netns);
+
+struct net *iscsi_host_get_netns(struct Scsi_Host *shost) {
+ struct iscsi_host *ihost = shost_priv(shost);
+ return ihost->net_ns;
+}
+EXPORT_SYMBOL_GPL(iscsi_host_get_netns);
+
MODULE_AUTHOR("Mike Christie");
MODULE_DESCRIPTION("iSCSI library functions");
MODULE_LICENSE("GPL");
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index e39fb0736ade..acd868b5f6ef 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -383,6 +383,7 @@ struct iscsi_host {
int state;

struct workqueue_struct *workq;
+ struct net *net_ns;
};

/*
@@ -492,6 +493,9 @@ extern void iscsi_pool_free(struct iscsi_pool *);
extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int);
extern int iscsi_switch_str_param(char **, char *);

+extern void iscsi_host_set_netns(struct Scsi_Host *, struct net *);
+extern struct net *iscsi_host_get_netns(struct Scsi_Host *);
+
/*
* inline functions to deal with padding.
*/
--
2.39.2

Chris Leech

unread,
Apr 21, 2023, 1:06:01 AM4/21/23
to Lee Duncan, linux...@vger.kernel.org, open-...@googlegroups.com, Lee Duncan, Chris Leech
I managed to fix the iSER endpoint issue by making endpoints created
without a host valid again. Once I had iSER working, I went ahead and
made it network namespace aware as well.

Only tested with software roce (rxe) against the kernel target.

I think the net_exit code might need to do a bit more with iSER.
I'm going to look into that, then I'll merge some of these patches that
fix earlier patches together, and get a new clean version of the set
posted.

Chris Leech (3):
iscsi iser: fix iser, allow virtual endpoints again
iscsi iser: direct network namespace support for endpoints
iscsi iser: enable network namespace awareness in iser

drivers/infiniband/ulp/iser/iscsi_iser.c | 13 ++++---
drivers/scsi/iscsi_tcp.c | 10 ++----
drivers/scsi/iscsi_tcp.h | 1 -
drivers/scsi/libiscsi.c | 12 +++++++
drivers/scsi/scsi_transport_iscsi.c | 45 +++++++++++++++++++-----
include/scsi/libiscsi.h | 4 +++
include/scsi/scsi_transport_iscsi.h | 9 ++++-
7 files changed, 71 insertions(+), 23 deletions(-)

--
2.39.2

Reply all
Reply to author
Forward
0 new messages